Merge pull request #11916 from yuwata/pid1-id-renaming-handling

core: handle ID_RENAMING= udev property
This commit is contained in:
Lennart Poettering 2019-03-07 14:42:08 +01:00 committed by GitHub
commit 441dc329d7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 126 additions and 26 deletions

3
TODO
View file

@ -23,9 +23,6 @@ Janitorial Clean-ups:
Features:
* check ID_RENAMING= property from PID1's .device logic, and don't consider
devices that are being renamed.
* make MAINPID= message reception checks even stricter: if service uses User=,
then check sending UID and ignore message if it doesn't match the user or
root.

View file

@ -220,8 +220,10 @@
<term><option>-c</option></term>
<term><option>--action=<replaceable>ACTION</replaceable></option></term>
<listitem>
<para>Type of event to be triggered. The default value is
<command>change</command>.</para>
<para>Type of event to be triggered. Possible actions are <literal>add</literal>,
<literal>remove</literal>, <literal>change</literal>, <literal>move</literal>,
<literal>online</literal>, <literal>offline</literal>, <literal>bind</literal>,
and <literal>unbind</literal>. The default value is <literal>change</literal>.</para>
</listitem>
</varlistentry>
<varlistentry>

View file

@ -17,6 +17,7 @@
#include "stat-util.h"
#include "string-util.h"
#include "swap.h"
#include "udev-util.h"
#include "unit-name.h"
#include "unit.h"
@ -729,6 +730,9 @@ static bool device_is_ready(sd_device *dev) {
assert(dev);
if (device_is_renaming(dev) > 0)
return false;
if (sd_device_get_property_value(dev, "SYSTEMD_READY", &ready) < 0)
return true;

View file

@ -81,19 +81,6 @@ struct sd_device {
bool db_persist:1; /* don't clean up the db when switching from initrd to real root */
};
typedef enum DeviceAction {
DEVICE_ACTION_ADD,
DEVICE_ACTION_REMOVE,
DEVICE_ACTION_CHANGE,
DEVICE_ACTION_MOVE,
DEVICE_ACTION_ONLINE,
DEVICE_ACTION_OFFLINE,
DEVICE_ACTION_BIND,
DEVICE_ACTION_UNBIND,
_DEVICE_ACTION_MAX,
_DEVICE_ACTION_INVALID = -1,
} DeviceAction;
int device_new_aux(sd_device **ret);
int device_add_property_aux(sd_device *device, const char *key, const char *value, bool db);
int device_add_property_internal(sd_device *device, const char *key, const char *value);
@ -108,6 +95,3 @@ int device_set_devnum(sd_device *device, const char *major, const char *minor);
int device_set_subsystem(sd_device *device, const char *_subsystem);
int device_set_driver(sd_device *device, const char *_driver);
int device_set_usec_initialized(sd_device *device, usec_t when);
DeviceAction device_action_from_string(const char *s) _pure_;
const char *device_action_to_string(DeviceAction a) _const_;

View file

@ -8,6 +8,8 @@
#include "sd-device.h"
#include "macro.h"
int device_new_from_nulstr(sd_device **ret, uint8_t *nulstr, size_t len);
int device_new_from_strv(sd_device **ret, char **strv);
int device_new_from_stat_rdev(sd_device **ret, const struct stat *st);
@ -55,3 +57,19 @@ int device_read_db_internal(sd_device *device, bool force);
static inline int device_read_db(sd_device *device) {
return device_read_db_internal(device, false);
}
typedef enum DeviceAction {
DEVICE_ACTION_ADD,
DEVICE_ACTION_REMOVE,
DEVICE_ACTION_CHANGE,
DEVICE_ACTION_MOVE,
DEVICE_ACTION_ONLINE,
DEVICE_ACTION_OFFLINE,
DEVICE_ACTION_BIND,
DEVICE_ACTION_UNBIND,
_DEVICE_ACTION_MAX,
_DEVICE_ACTION_INVALID = -1,
} DeviceAction;
DeviceAction device_action_from_string(const char *s) _pure_;
const char *device_action_to_string(DeviceAction a) _const_;

View file

@ -5,7 +5,7 @@
#include "cgroup.h"
#include "compress.h"
#include "condition.h"
#include "device-internal.h"
#include "device-private.h"
#include "device.h"
#include "execute.h"
#include "import-util.h"

View file

@ -7,6 +7,7 @@
#include "sd-event.h"
#include "device-enumerator-private.h"
#include "device-private.h"
#include "fd-util.h"
#include "fileio.h"
#include "path-util.h"
@ -199,11 +200,10 @@ int trigger_main(int argc, char *argv[], void *userdata) {
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown type --type=%s", optarg);
break;
case 'c':
if (STR_IN_SET(optarg, "add", "remove", "change"))
action = optarg;
else
log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown action '%s'", optarg);
if (device_action_from_string(optarg) < 0)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown action '%s'", optarg);
action = optarg;
break;
case 's':
r = sd_device_enumerator_add_match_subsystem(e, optarg, true);

View file

@ -0,0 +1 @@
../TEST-01-BASIC/Makefile

View file

@ -0,0 +1,49 @@
#!/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="UDEV ID_RENAMING property"
TEST_NO_NSPAWN=1
. $TEST_BASE_DIR/test-functions
QEMU_TIMEOUT=300
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 -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
# setup the testsuite service
cat >$initdir/etc/systemd/system/testsuite.service <<EOF
[Unit]
Description=Testsuite service
[Service]
ExecStart=/bin/bash -x /testsuite.sh
Type=oneshot
StandardOutput=tty
StandardError=tty
EOF
cp testsuite.sh $initdir/
setup_testsuite
) || return 1
ddebug "umount $TESTDIR/root"
umount $TESTDIR/root
}
do_test "$@"

View file

@ -0,0 +1,45 @@
#!/bin/bash
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
# ex: ts=8 sw=4 sts=4 et filetype=sh
set -ex
set -o pipefail
mkdir -p /run/udev/rules.d/
cat > /run/udev/rules.d/50-testsuite.rules <<EOF
ACTION=="remove", GOTO="lo_end"
SUBSYSTEM=="net", KERNEL=="lo", TAG+="systemd", ENV{SYSTEMD_ALIAS}+="/sys/subsystem/net/devices/lo"
ACTION!="change", GOTO="lo_end"
SUBSYSTEM=="net", KERNEL=="lo", ENV{ID_RENAMING}="1"
LABEL="lo_end"
EOF
udevadm control --log-priority=debug --reload
udevadm trigger --action=add --settle /sys/devices/virtual/net/lo
udevadm info /sys/devices/virtual/net/lo
STATE=$(systemctl show --property=ActiveState --value sys-devices-virtual-net-lo.device)
[[ $STATE == "active" ]] || exit 1
udevadm trigger --action=change --settle /sys/devices/virtual/net/lo
udevadm info /sys/devices/virtual/net/lo
STATE=$(systemctl show --property=ActiveState --value sys-devices-virtual-net-lo.device)
[[ $STATE == "inactive" ]] || exit 1
udevadm trigger --action=move --settle /sys/devices/virtual/net/lo
udevadm info /sys/devices/virtual/net/lo
STATE=$(systemctl show --property=ActiveState --value sys-devices-virtual-net-lo.device)
[[ $STATE == "active" ]] || exit 1
rm -f /run/udev/rules.d/50-testsuite.rules
udevadm control --reload
echo OK > /testok
exit 0