mirror of
https://github.com/systemd/systemd.git
synced 2024-11-06 08:26:52 +03:00
device: create units with intended "found" value
Change device_found_node() to also create a .device unit if a device is not known by udev; this is the case for "tentative" devices picked up by mountinfo (DEVICE_FOUND_MOUNT). With that we can record the "found" attribute on the unit. Change device_setup_unit() to also accept a NULL udev_device, and don't add the extra udev information in that case. Previously device_found_node() would not create a .device unit, and unit_add_node_link() would then create a "dead" stub one via manager_load_unit(), so we lost the "found" attribute and unmounted everything from that device. https://launchpad.net/bugs/1444402 http://lists.freedesktop.org/archives/systemd-devel/2015-May/031658.html
This commit is contained in:
parent
139e533628
commit
2005219f83
@ -292,18 +292,19 @@ static int device_add_udev_wants(Unit *u, struct udev_device *dev) {
|
|||||||
|
|
||||||
static int device_setup_unit(Manager *m, struct udev_device *dev, const char *path, bool main) {
|
static int device_setup_unit(Manager *m, struct udev_device *dev, const char *path, bool main) {
|
||||||
_cleanup_free_ char *e = NULL;
|
_cleanup_free_ char *e = NULL;
|
||||||
const char *sysfs;
|
const char *sysfs = NULL;
|
||||||
Unit *u = NULL;
|
Unit *u = NULL;
|
||||||
bool delete;
|
bool delete;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(m);
|
assert(m);
|
||||||
assert(dev);
|
|
||||||
assert(path);
|
assert(path);
|
||||||
|
|
||||||
|
if (dev) {
|
||||||
sysfs = udev_device_get_syspath(dev);
|
sysfs = udev_device_get_syspath(dev);
|
||||||
if (!sysfs)
|
if (!sysfs)
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
r = unit_name_from_path(path, ".device", &e);
|
r = unit_name_from_path(path, ".device", &e);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
@ -312,6 +313,7 @@ static int device_setup_unit(Manager *m, struct udev_device *dev, const char *pa
|
|||||||
u = manager_get_unit(m, e);
|
u = manager_get_unit(m, e);
|
||||||
|
|
||||||
if (u &&
|
if (u &&
|
||||||
|
sysfs &&
|
||||||
DEVICE(u)->sysfs &&
|
DEVICE(u)->sysfs &&
|
||||||
!path_equal(DEVICE(u)->sysfs, sysfs)) {
|
!path_equal(DEVICE(u)->sysfs, sysfs)) {
|
||||||
log_unit_debug(u, "Device %s appeared twice with different sysfs paths %s and %s", e, DEVICE(u)->sysfs, sysfs);
|
log_unit_debug(u, "Device %s appeared twice with different sysfs paths %s and %s", e, DEVICE(u)->sysfs, sysfs);
|
||||||
@ -336,7 +338,7 @@ static int device_setup_unit(Manager *m, struct udev_device *dev, const char *pa
|
|||||||
/* If this was created via some dependency and has not
|
/* If this was created via some dependency and has not
|
||||||
* actually been seen yet ->sysfs will not be
|
* actually been seen yet ->sysfs will not be
|
||||||
* initialized. Hence initialize it if necessary. */
|
* initialized. Hence initialize it if necessary. */
|
||||||
|
if (sysfs) {
|
||||||
r = device_set_sysfs(DEVICE(u), sysfs);
|
r = device_set_sysfs(DEVICE(u), sysfs);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
@ -347,6 +349,8 @@ static int device_setup_unit(Manager *m, struct udev_device *dev, const char *pa
|
|||||||
* for the main object */
|
* for the main object */
|
||||||
if (main)
|
if (main)
|
||||||
(void) device_add_udev_wants(u, dev);
|
(void) device_add_udev_wants(u, dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Note that this won't dispatch the load queue, the caller
|
/* Note that this won't dispatch the load queue, the caller
|
||||||
* has to do that if needed and appropriate */
|
* has to do that if needed and appropriate */
|
||||||
@ -788,23 +792,16 @@ int device_found_node(Manager *m, const char *node, bool add, DeviceFound found,
|
|||||||
* will still have a device node even when the medium
|
* will still have a device node even when the medium
|
||||||
* is not there... */
|
* is not there... */
|
||||||
|
|
||||||
if (stat(node, &st) < 0) {
|
if (stat(node, &st) >= 0) {
|
||||||
if (errno == ENOENT)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return log_error_errno(errno, "Failed to stat device node file %s: %m", node);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!S_ISBLK(st.st_mode) && !S_ISCHR(st.st_mode))
|
if (!S_ISBLK(st.st_mode) && !S_ISCHR(st.st_mode))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
dev = udev_device_new_from_devnum(m->udev, S_ISBLK(st.st_mode) ? 'b' : 'c', st.st_rdev);
|
dev = udev_device_new_from_devnum(m->udev, S_ISBLK(st.st_mode) ? 'b' : 'c', st.st_rdev);
|
||||||
if (!dev) {
|
if (!dev && errno != ENOENT)
|
||||||
if (errno == ENOENT)
|
return log_error_errno(errno, "Failed to get udev device from devnum %u:%u: %m", major(st.st_rdev), minor(st.st_rdev));
|
||||||
return 0;
|
|
||||||
|
|
||||||
return log_oom();
|
} else if (errno != ENOENT)
|
||||||
}
|
return log_error_errno(errno, "Failed to stat device node file %s: %m", node);
|
||||||
|
|
||||||
/* If the device is known in the kernel and newly
|
/* If the device is known in the kernel and newly
|
||||||
* appeared, then we'll create a device unit for it,
|
* appeared, then we'll create a device unit for it,
|
||||||
|
Loading…
Reference in New Issue
Block a user