summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac6
-rw-r--r--rules/rules.d/95-udev-late.rules4
-rw-r--r--udev/lib/libudev-monitor.c31
-rw-r--r--udev/lib/libudev.h6
-rw-r--r--udev/udevadm-monitor.c10
-rw-r--r--udev/udevd.c6
6 files changed, 37 insertions, 26 deletions
diff --git a/configure.ac b/configure.ac
index 001f338d14..3fd51ce36e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -15,9 +15,9 @@ AC_PREFIX_DEFAULT([/usr])
test "$prefix" = NONE && test "$exec_prefix" = NONE && exec_prefix=
dnl /* libudev version */
-LIBUDEV_LT_CURRENT=1
-LIBUDEV_LT_REVISION=1
-LIBUDEV_LT_AGE=1
+LIBUDEV_LT_CURRENT=2
+LIBUDEV_LT_REVISION=0
+LIBUDEV_LT_AGE=2
AC_SUBST(LIBUDEV_LT_CURRENT)
AC_SUBST(LIBUDEV_LT_REVISION)
AC_SUBST(LIBUDEV_LT_AGE)
diff --git a/rules/rules.d/95-udev-late.rules b/rules/rules.d/95-udev-late.rules
index 7207081d46..eca0faa5c5 100644
--- a/rules/rules.d/95-udev-late.rules
+++ b/rules/rules.d/95-udev-late.rules
@@ -2,7 +2,3 @@
# run a command on remove events
ACTION=="remove", ENV{REMOVE_CMD}!="", RUN+="$env{REMOVE_CMD}"
-
-# event to be catched by udevmonitor
-RUN+="socket:@/org/kernel/udev/monitor"
-
diff --git a/udev/lib/libudev-monitor.c b/udev/lib/libudev-monitor.c
index c0aa99c65a..b2f76c3129 100644
--- a/udev/lib/libudev-monitor.c
+++ b/udev/lib/libudev-monitor.c
@@ -29,6 +29,7 @@ struct udev_monitor {
int refcount;
int sock;
struct sockaddr_nl snl;
+ struct sockaddr_nl snl_peer;
struct sockaddr_un sun;
socklen_t addrlen;
};
@@ -90,7 +91,7 @@ struct udev_monitor *udev_monitor_new_from_socket(struct udev *udev, const char
return udev_monitor;
}
-struct udev_monitor *udev_monitor_new_from_netlink(struct udev *udev)
+struct udev_monitor *udev_monitor_new_from_netlink(struct udev *udev, unsigned int group)
{
struct udev_monitor *udev_monitor;
@@ -110,10 +111,11 @@ struct udev_monitor *udev_monitor_new_from_netlink(struct udev *udev)
}
udev_monitor->snl.nl_family = AF_NETLINK;
- udev_monitor->snl.nl_pid = getpid();
- udev_monitor->snl.nl_groups = 1;
+ udev_monitor->snl.nl_groups = group;
+ udev_monitor->snl_peer.nl_family = AF_NETLINK;
+ udev_monitor->snl_peer.nl_groups = UDEV_MONITOR_UDEV;
- dbg(udev, "monitor %p created with NETLINK_KOBJECT_UEVENT\n", udev_monitor);
+ dbg(udev, "monitor %p created with NETLINK_KOBJECT_UEVENT (%u)\n", udev_monitor, group);
return udev_monitor;
}
@@ -123,14 +125,16 @@ int udev_monitor_enable_receiving(struct udev_monitor *udev_monitor)
const int on = 1;
if (udev_monitor->snl.nl_family != 0) {
- err = bind(udev_monitor->sock, (struct sockaddr *)&udev_monitor->snl, sizeof(struct sockaddr_nl));
+ err = bind(udev_monitor->sock,
+ (struct sockaddr *)&udev_monitor->snl, sizeof(struct sockaddr_nl));
if (err < 0) {
err(udev_monitor->udev, "bind failed: %m\n");
return err;
}
dbg(udev_monitor->udev, "monitor %p listening on netlink\n", udev_monitor);
} else if (udev_monitor->sun.sun_family != 0) {
- err = bind(udev_monitor->sock, (struct sockaddr *)&udev_monitor->sun, udev_monitor->addrlen);
+ err = bind(udev_monitor->sock,
+ (struct sockaddr *)&udev_monitor->sun, udev_monitor->addrlen);
if (err < 0) {
err(udev_monitor->udev, "bind failed: %m\n");
return err;
@@ -381,9 +385,18 @@ int udev_monitor_send_device(struct udev_monitor *udev_monitor, struct udev_devi
len = udev_device_get_properties_monitor_buf(udev_device, &buf);
if (len < 32)
return -1;
- count = sendto(udev_monitor->sock,
- buf, len, 0,
- (struct sockaddr *)&udev_monitor->sun, udev_monitor->addrlen);
+ if (udev_monitor->sun.sun_family != 0) {
+ count = sendto(udev_monitor->sock,
+ buf, len, 0,
+ (struct sockaddr *)&udev_monitor->sun,
+ udev_monitor->addrlen);
+ } else {
+ /* no destination besides the muticast group, we will always get -1 ECONNREFUSED */
+ count = sendto(udev_monitor->sock,
+ buf, len, 0,
+ (struct sockaddr *)&udev_monitor->snl_peer,
+ sizeof(struct sockaddr_nl));
+ }
info(udev_monitor->udev, "passed %zi bytes to monitor %p, \n", count, udev_monitor);
return count;
}
diff --git a/udev/lib/libudev.h b/udev/lib/libudev.h
index a5d2c22e8c..be09ddb75a 100644
--- a/udev/lib/libudev.h
+++ b/udev/lib/libudev.h
@@ -76,8 +76,12 @@ extern const char *udev_device_get_sysattr_value(struct udev_device *udev_device
/* udev and kernel device events */
struct udev_monitor;
+enum udev_monitor_netlink_group {
+ UDEV_MONITOR_KERNEL = 1,
+ UDEV_MONITOR_UDEV = 2,
+};
extern struct udev_monitor *udev_monitor_new_from_socket(struct udev *udev, const char *socket_path);
-extern struct udev_monitor *udev_monitor_new_from_netlink(struct udev *udev);
+extern struct udev_monitor *udev_monitor_new_from_netlink(struct udev *udev, enum udev_monitor_netlink_group group);
extern int udev_monitor_enable_receiving(struct udev_monitor *udev_monitor);
extern struct udev_monitor *udev_monitor_ref(struct udev_monitor *udev_monitor);
extern void udev_monitor_unref(struct udev_monitor *udev_monitor);
diff --git a/udev/udevadm-monitor.c b/udev/udevadm-monitor.c
index 9be02da16c..43c1cc1163 100644
--- a/udev/udevadm-monitor.c
+++ b/udev/udevadm-monitor.c
@@ -115,11 +115,6 @@ int udevadm_monitor(struct udev *udev, int argc, char *argv[])
print_udev =1;
}
- if (getuid() != 0 && print_kernel) {
- fprintf(stderr, "root privileges needed to subscribe to kernel events\n");
- goto out;
- }
-
/* set signal handlers */
memset(&act, 0x00, sizeof(struct sigaction));
act.sa_handler = (void (*)(int)) sig_handler;
@@ -130,7 +125,7 @@ int udevadm_monitor(struct udev *udev, int argc, char *argv[])
printf("monitor will print the received events for:\n");
if (print_udev) {
- udev_monitor = udev_monitor_new_from_socket(udev, "@/org/kernel/udev/monitor");
+ udev_monitor = udev_monitor_new_from_netlink(udev, UDEV_MONITOR_UDEV);
if (udev_monitor == NULL) {
rc = 1;
goto out;
@@ -142,8 +137,9 @@ int udevadm_monitor(struct udev *udev, int argc, char *argv[])
printf("UDEV - the event which udev sends out after rule processing\n");
}
if (print_kernel) {
- kernel_monitor = udev_monitor_new_from_netlink(udev);
+ kernel_monitor = udev_monitor_new_from_netlink(udev, UDEV_MONITOR_KERNEL);
if (kernel_monitor == NULL) {
+ fprintf(stderr, "unable to subscribe to kernel events\n");
rc = 3;
goto out;
}
diff --git a/udev/udevd.c b/udev/udevd.c
index 291655ef00..d9de26ea6c 100644
--- a/udev/udevd.c
+++ b/udev/udevd.c
@@ -195,7 +195,6 @@ static void event_fork(struct udev_event *event)
switch (pid) {
case 0:
/* child */
- udev_monitor_unref(kernel_monitor);
udev_ctrl_unref(udev_ctrl);
logging_close();
logging_init("udevd-event");
@@ -235,6 +234,9 @@ static void event_fork(struct udev_event *event)
udev_device_update_db(event->dev);
}
+ /* send processed event back to the kernel netlink socket */
+ udev_monitor_send_device(kernel_monitor, event->dev);
+
info(event->udev, "seq %llu exit with %i\n", udev_device_get_seqnum(event->dev), err);
logging_close();
if (err != 0)
@@ -811,7 +813,7 @@ int main(int argc, char *argv[])
goto exit;
}
- kernel_monitor = udev_monitor_new_from_netlink(udev);
+ kernel_monitor = udev_monitor_new_from_netlink(udev, UDEV_MONITOR_KERNEL);
if (kernel_monitor == NULL || udev_monitor_enable_receiving(kernel_monitor) < 0) {
fprintf(stderr, "error initializing netlink socket\n");
err(udev, "error initializing netlink socket\n");