summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2018-06-04 22:52:02 +0200
committerLennart Poettering <lennart@poettering.net>2018-06-07 13:36:19 +0200
commite5ca27b772267bd18109eb460fb6653a920e551e (patch)
treee0a23f07c1ae580171d27e82a5e7763d52ea4bdf
parentcore: split out device validation from device_found_node() (diff)
downloadsystemd-e5ca27b772267bd18109eb460fb6653a920e551e.tar.xz
systemd-e5ca27b772267bd18109eb460fb6653a920e551e.zip
udev: add helper udev_device_new_from_stat_rdev()
This is a simple wrapper around udev_device_new_from_devnum(), and uses the data from a struct stat's .st_rdev field to derive the udev_device object.
Diffstat (limited to '')
-rw-r--r--src/core/device.c19
-rw-r--r--src/core/swap.c15
-rw-r--r--src/journal/journalctl.c13
-rw-r--r--src/shared/udev-util.c23
-rw-r--r--src/shared/udev-util.h2
5 files changed, 50 insertions, 22 deletions
diff --git a/src/core/device.c b/src/core/device.c
index e296ffa418..e92b982439 100644
--- a/src/core/device.c
+++ b/src/core/device.c
@@ -943,6 +943,7 @@ static bool device_supported(void) {
static int validate_node(Manager *m, const char *node, struct udev_device **ret) {
struct stat st;
+ int r;
assert(m);
assert(node);
@@ -966,19 +967,15 @@ static int validate_node(Manager *m, const char *node, struct udev_device **ret)
} else {
_cleanup_(udev_device_unrefp) struct udev_device *dev = NULL;
- if (!S_ISBLK(st.st_mode) && !S_ISCHR(st.st_mode)) {
- *ret = NULL;
- return 0; /* bad! */
- }
-
- dev = udev_device_new_from_devnum(m->udev, S_ISBLK(st.st_mode) ? 'b' : 'c', st.st_rdev);
- if (!dev) {
- 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));
-
+ r = udev_device_new_from_stat_rdev(m->udev, &st, &dev);
+ if (r == -ENOENT) {
*ret = NULL;
return 1; /* good! (though missing) */
- }
+ } else if (r == -ENOTTY) {
+ *ret = NULL;
+ return 0; /* bad! (not a device node but some other kind of file system node) */
+ } else if (r < 0)
+ return log_error_errno(r, "Failed to get udev device from devnum %u:%u: %m", major(st.st_rdev), minor(st.st_rdev));
*ret = TAKE_PTR(dev);
return 1; /* good! */
diff --git a/src/core/swap.c b/src/core/swap.c
index 693561dd90..ab9057f29d 100644
--- a/src/core/swap.c
+++ b/src/core/swap.c
@@ -255,15 +255,19 @@ static int swap_load_devnode(Swap *s) {
_cleanup_(udev_device_unrefp) struct udev_device *d = NULL;
struct stat st;
const char *p;
+ int r;
assert(s);
if (stat(s->what, &st) < 0 || !S_ISBLK(st.st_mode))
return 0;
- d = udev_device_new_from_devnum(UNIT(s)->manager->udev, 'b', st.st_rdev);
- if (!d)
+ r = udev_device_new_from_stat_rdev(UNIT(s)->manager->udev, &st, &d);
+ if (r < 0) {
+ log_unit_full(UNIT(s), r == -ENOENT ? LOG_DEBUG : LOG_WARNING, r,
+ "Failed to allocate udev device for swap %s: %m", s->what);
return 0;
+ }
p = udev_device_get_devnode(d);
if (!p)
@@ -443,9 +447,12 @@ static int swap_process_new(Manager *m, const char *device, int prio, bool set_f
if (stat(device, &st) < 0 || !S_ISBLK(st.st_mode))
return 0;
- d = udev_device_new_from_devnum(m->udev, 'b', st.st_rdev);
- if (!d)
+ r = udev_device_new_from_stat_rdev(m->udev, &st, &d);
+ if (r < 0) {
+ log_full_errno(r == -ENOENT ? LOG_DEBUG : LOG_WARNING, r,
+ "Failed to allocate udev device for swap %s: %m", device);
return 0;
+ }
/* Add the main device node */
dn = udev_device_get_devnode(d);
diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
index 61d29986ce..9ad1b31fa3 100644
--- a/src/journal/journalctl.c
+++ b/src/journal/journalctl.c
@@ -182,11 +182,11 @@ typedef struct BootId {
} BootId;
static int add_matches_for_device(sd_journal *j, const char *devpath) {
- int r;
_cleanup_(udev_unrefp) struct udev *udev = NULL;
_cleanup_(udev_device_unrefp) struct udev_device *device = NULL;
struct udev_device *d = NULL;
struct stat st;
+ int r;
assert(j);
assert(devpath);
@@ -200,13 +200,12 @@ static int add_matches_for_device(sd_journal *j, const char *devpath) {
if (!udev)
return log_oom();
- r = stat(devpath, &st);
- if (r < 0)
- log_error_errno(errno, "Couldn't stat file: %m");
+ if (stat(devpath, &st) < 0)
+ return log_error_errno(errno, "Couldn't stat file: %m");
- d = device = udev_device_new_from_devnum(udev, S_ISBLK(st.st_mode) ? 'b' : 'c', st.st_rdev);
- if (!device)
- return log_error_errno(errno, "Failed to get udev device from devnum %u:%u: %m", major(st.st_rdev), minor(st.st_rdev));
+ r = udev_device_new_from_stat_rdev(udev, &st, &device);
+ if (r < 0)
+ return log_error_errno(r, "Failed to get udev device from devnum %u:%u: %m", major(st.st_rdev), minor(st.st_rdev));
while (d) {
_cleanup_free_ char *match = NULL;
diff --git a/src/shared/udev-util.c b/src/shared/udev-util.c
index 29484226c6..a5ed8e8f6b 100644
--- a/src/shared/udev-util.c
+++ b/src/shared/udev-util.c
@@ -42,3 +42,26 @@ int udev_parse_config(void) {
return 0;
}
+
+int udev_device_new_from_stat_rdev(struct udev *udev, const struct stat *st, struct udev_device **ret) {
+ struct udev_device *nd;
+ char type;
+
+ assert(udev);
+ assert(st);
+ assert(ret);
+
+ if (S_ISBLK(st->st_mode))
+ type = 'b';
+ else if (S_ISCHR(st->st_mode))
+ type = 'c';
+ else
+ return -ENOTTY;
+
+ nd = udev_device_new_from_devnum(udev, type, st->st_rdev);
+ if (!nd)
+ return -errno;
+
+ *ret = nd;
+ return 0;
+}
diff --git a/src/shared/udev-util.h b/src/shared/udev-util.h
index 0f270f7fbd..ce40f695e8 100644
--- a/src/shared/udev-util.h
+++ b/src/shared/udev-util.h
@@ -21,3 +21,5 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev_ctrl_msg*, udev_ctrl_msg_unref);
DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev_monitor*, udev_monitor_unref);
int udev_parse_config(void);
+
+int udev_device_new_from_stat_rdev(struct udev *udev, const struct stat *st, struct udev_device **ret);