core/device: move several functions

No functional change. A preparation for later commits.
This commit is contained in:
Yu Watanabe 2022-04-29 03:12:17 +09:00
parent 367a2597c3
commit dce2d35ce5

View file

@ -31,7 +31,6 @@ static const UnitActiveState state_translation_table[_DEVICE_STATE_MAX] = {
};
static int device_dispatch_io(sd_device_monitor *monitor, sd_device *dev, void *userdata);
static void device_update_found_one(Device *d, DeviceFound found, DeviceFound mask);
static void device_unset_sysfs(Device *d) {
Hashmap *devices;
@ -157,6 +156,85 @@ static void device_set_state(Device *d, DeviceState state) {
unit_notify(UNIT(d), state_translation_table[old_state], state_translation_table[state], 0);
}
static void device_found_changed(Device *d, DeviceFound previous, DeviceFound now) {
assert(d);
/* Didn't exist before, but does now? if so, generate a new invocation ID for it */
if (previous == DEVICE_NOT_FOUND && now != DEVICE_NOT_FOUND)
(void) unit_acquire_invocation_id(UNIT(d));
if (FLAGS_SET(now, DEVICE_FOUND_UDEV))
/* When the device is known to udev we consider it plugged. */
device_set_state(d, DEVICE_PLUGGED);
else if (now != DEVICE_NOT_FOUND && !FLAGS_SET(previous, DEVICE_FOUND_UDEV))
/* If the device has not been seen by udev yet, but is now referenced by the kernel, then we assume the
* kernel knows it now, and udev might soon too. */
device_set_state(d, DEVICE_TENTATIVE);
else
/* If nobody sees the device, or if the device was previously seen by udev and now is only referenced
* from the kernel, then we consider the device is gone, the kernel just hasn't noticed it yet. */
device_set_state(d, DEVICE_DEAD);
}
static void device_update_found_one(Device *d, DeviceFound found, DeviceFound mask) {
assert(d);
if (MANAGER_IS_RUNNING(UNIT(d)->manager)) {
DeviceFound n, previous;
/* When we are already running, then apply the new mask right-away, and trigger state changes
* right-away */
n = (d->found & ~mask) | (found & mask);
if (n == d->found)
return;
previous = d->found;
d->found = n;
device_found_changed(d, previous, n);
} else
/* We aren't running yet, let's apply the new mask to the shadow variable instead, which we'll apply as
* soon as we catch-up with the state. */
d->enumerated_found = (d->enumerated_found & ~mask) | (found & mask);
}
static void device_update_found_by_sysfs(Manager *m, const char *sysfs, DeviceFound found, DeviceFound mask) {
Device *l;
assert(m);
assert(sysfs);
if (mask == 0)
return;
l = hashmap_get(m->devices_by_sysfs, sysfs);
LIST_FOREACH(same_sysfs, d, l)
device_update_found_one(d, found, mask);
}
static void device_update_found_by_name(Manager *m, const char *path, DeviceFound found, DeviceFound mask) {
_cleanup_free_ char *e = NULL;
Unit *u;
int r;
assert(m);
assert(path);
if (mask == 0)
return;
r = unit_name_from_path(path, ".device", &e);
if (r < 0)
return (void) log_debug_errno(r, "Failed to generate unit name from device path, ignoring: %m");
u = manager_get_unit(m, e);
if (!u)
return;
device_update_found_one(DEVICE(u), found, mask);
}
static int device_coldplug(Unit *u) {
Device *d = DEVICE(u);
@ -610,6 +688,37 @@ static int device_setup_unit(Manager *m, sd_device *dev, const char *path, bool
return 0;
}
static bool device_is_ready(sd_device *dev) {
int r;
assert(dev);
r = device_is_renaming(dev);
if (r < 0)
log_device_warning_errno(dev, r, "Failed to check if device is renaming, assuming device is not renaming: %m");
if (r > 0) {
log_device_debug(dev, "Device busy: device is renaming");
return false;
}
/* Is it really tagged as 'systemd' right now? */
r = sd_device_has_current_tag(dev, "systemd");
if (r < 0)
log_device_warning_errno(dev, r, "Failed to check if device has \"systemd\" tag, assuming device is not tagged with \"systemd\": %m");
if (r == 0)
log_device_debug(dev, "Device busy: device is not tagged with \"systemd\"");
if (r <= 0)
return false;
r = device_get_property_bool(dev, "SYSTEMD_READY");
if (r < 0 && r != -ENOENT)
log_device_warning_errno(dev, r, "Failed to get device SYSTEMD_READY property, assuming device does not have \"SYSTEMD_READY\" property: %m");
if (r == 0)
log_device_debug(dev, "Device busy: SYSTEMD_READY property from device is false");
return r != 0;
}
static void device_process_new(Manager *m, sd_device *dev, const char *sysfs) {
const char *dn, *alias;
dev_t devnum;
@ -683,116 +792,6 @@ static void device_process_new(Manager *m, sd_device *dev, const char *sysfs) {
}
}
static void device_found_changed(Device *d, DeviceFound previous, DeviceFound now) {
assert(d);
/* Didn't exist before, but does now? if so, generate a new invocation ID for it */
if (previous == DEVICE_NOT_FOUND && now != DEVICE_NOT_FOUND)
(void) unit_acquire_invocation_id(UNIT(d));
if (FLAGS_SET(now, DEVICE_FOUND_UDEV))
/* When the device is known to udev we consider it plugged. */
device_set_state(d, DEVICE_PLUGGED);
else if (now != DEVICE_NOT_FOUND && !FLAGS_SET(previous, DEVICE_FOUND_UDEV))
/* If the device has not been seen by udev yet, but is now referenced by the kernel, then we assume the
* kernel knows it now, and udev might soon too. */
device_set_state(d, DEVICE_TENTATIVE);
else
/* If nobody sees the device, or if the device was previously seen by udev and now is only referenced
* from the kernel, then we consider the device is gone, the kernel just hasn't noticed it yet. */
device_set_state(d, DEVICE_DEAD);
}
static void device_update_found_one(Device *d, DeviceFound found, DeviceFound mask) {
assert(d);
if (MANAGER_IS_RUNNING(UNIT(d)->manager)) {
DeviceFound n, previous;
/* When we are already running, then apply the new mask right-away, and trigger state changes
* right-away */
n = (d->found & ~mask) | (found & mask);
if (n == d->found)
return;
previous = d->found;
d->found = n;
device_found_changed(d, previous, n);
} else
/* We aren't running yet, let's apply the new mask to the shadow variable instead, which we'll apply as
* soon as we catch-up with the state. */
d->enumerated_found = (d->enumerated_found & ~mask) | (found & mask);
}
static void device_update_found_by_sysfs(Manager *m, const char *sysfs, DeviceFound found, DeviceFound mask) {
Device *l;
assert(m);
assert(sysfs);
if (mask == 0)
return;
l = hashmap_get(m->devices_by_sysfs, sysfs);
LIST_FOREACH(same_sysfs, d, l)
device_update_found_one(d, found, mask);
}
static void device_update_found_by_name(Manager *m, const char *path, DeviceFound found, DeviceFound mask) {
_cleanup_free_ char *e = NULL;
Unit *u;
int r;
assert(m);
assert(path);
if (mask == 0)
return;
r = unit_name_from_path(path, ".device", &e);
if (r < 0)
return (void) log_debug_errno(r, "Failed to generate unit name from device path, ignoring: %m");
u = manager_get_unit(m, e);
if (!u)
return;
device_update_found_one(DEVICE(u), found, mask);
}
static bool device_is_ready(sd_device *dev) {
int r;
assert(dev);
r = device_is_renaming(dev);
if (r < 0)
log_device_warning_errno(dev, r, "Failed to check if device is renaming, assuming device is not renaming: %m");
if (r > 0) {
log_device_debug(dev, "Device busy: device is renaming");
return false;
}
/* Is it really tagged as 'systemd' right now? */
r = sd_device_has_current_tag(dev, "systemd");
if (r < 0)
log_device_warning_errno(dev, r, "Failed to check if device has \"systemd\" tag, assuming device is not tagged with \"systemd\": %m");
if (r == 0)
log_device_debug(dev, "Device busy: device is not tagged with \"systemd\"");
if (r <= 0)
return false;
r = device_get_property_bool(dev, "SYSTEMD_READY");
if (r < 0 && r != -ENOENT)
log_device_warning_errno(dev, r, "Failed to get device SYSTEMD_READY property, assuming device does not have \"SYSTEMD_READY\" property: %m");
if (r == 0)
log_device_debug(dev, "Device busy: SYSTEMD_READY property from device is false");
return r != 0;
}
static Unit *device_following(Unit *u) {
Device *d = DEVICE(u);
Device *first = NULL;