aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKay Sievers <kay.sievers@suse.de>2005-08-01 05:07:19 +0200
committerKay Sievers <kay.sievers@suse.de>2005-08-01 05:07:19 +0200
commitd455b0085d65cd25915a34d84f894a4950d313a2 (patch)
tree9d948af85de34d1a5e210362e6b50f40ce4ee996
parent70721db6d7ba0d4f3ac5c17f2cedac056065ad8a (diff)
downloadudev-d455b0085d65cd25915a34d84f894a4950d313a2.tar.gz
allow RUN to send the environment to a local socket
RUN="socket:<name>" will send the environment in the kernel uevent format to the named destination. Using the socket instead of the program to pass the hotplug events to the HAL daemon, cuts down the running time of udevstart from 0.8 to 0.4 seconds on my box. env -i ACTION=add DEVPATH=/block/hda/hda1 strace -s10000 ./udev block sendto(3, "add@/block/hda/hda1\0 ACTION=add\0DEVPATH=/block/hda/hda1\0UDEV_LOG=3\0 ID_TYPE=disk\0ID_MODEL=HTS726060M9AT00\0ID_SERIAL=MRH401M4G6UM9B\0 ID_REVISION=MH4OA6BA\0ID_BUS=ata\0ID_PATH=pci-0000:00:1f.1-ide-0:0\0 ID_FS_USAGE=other\0ID_FS_TYPE=swap\0ID_FS_VERSION=2\0 ID_FS_UUID=9352cfef-7687-47bc-a2a3-34cf136f72e1\0 ID_FS_LABEL=ThisIsSwap\0ID_FS_LABEL_SAFE=ThisIsSwap\0 DEVNAME=/dev/hda1\0" Signed-off-by: Kay Sievers <kay.sievers@suse.de>
-rw-r--r--udev.c8
-rw-r--r--udev_utils.c34
-rw-r--r--udev_utils.h1
-rw-r--r--udevsend.c14
-rw-r--r--udevstart.c8
5 files changed, 54 insertions, 11 deletions
diff --git a/udev.c b/udev.c
index 4096b8b3..2a6e1efc 100644
--- a/udev.c
+++ b/udev.c
@@ -123,8 +123,12 @@ int main(int argc, char *argv[], char *envp[])
struct name_entry *name_loop;
dbg("executing run list");
- list_for_each_entry(name_loop, &udev.run_list, node)
- execute_program(name_loop->name, udev.subsystem, NULL, 0, NULL);
+ list_for_each_entry(name_loop, &udev.run_list, node) {
+ if (strncmp(name_loop->name, "socket:", strlen("socket:")) == 0)
+ pass_env_to_socket(&name_loop->name[strlen("socket:")], devpath, action);
+ else
+ execute_program(name_loop->name, udev.subsystem, NULL, 0, NULL);
+ }
}
udev_cleanup_device(&udev);
diff --git a/udev_utils.c b/udev_utils.c
index 2524baf5..fd4cd13e 100644
--- a/udev_utils.c
+++ b/udev_utils.c
@@ -28,6 +28,8 @@
#include <ctype.h>
#include <dirent.h>
#include <syslog.h>
+#include <sys/socket.h>
+#include <sys/un.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/mman.h>
@@ -372,6 +374,38 @@ int add_matching_files(struct list_head *name_list, const char *dirname, const c
return 0;
}
+int pass_env_to_socket(const char *sockname, const char *devpath, const char *action)
+{
+ int sock;
+ struct sockaddr_un saddr;
+ socklen_t addrlen;
+ char buf[2048];
+ size_t bufpos = 0;
+ int i;
+ int retval;
+
+ dbg("pass environment to socket '%s'", sockname);
+ sock = socket(AF_LOCAL, SOCK_DGRAM, 0);
+ memset(&saddr, 0x00, sizeof(struct sockaddr_un));
+ saddr.sun_family = AF_LOCAL;
+ /* only abstract namespace is supported */
+ strcpy(&saddr.sun_path[1], sockname);
+ addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(saddr.sun_path+1) + 1;
+
+ bufpos = snprintf(buf, sizeof(buf)-1, "%s@%s", action, devpath);
+ bufpos++;
+ for (i = 0; environ[i] != NULL && bufpos < sizeof(buf); i++) {
+ bufpos += strlcpy(&buf[bufpos], environ[i], sizeof(buf) - bufpos-1);
+ bufpos++;
+ }
+
+ retval = sendto(sock, &buf, bufpos, 0, (struct sockaddr *)&saddr, addrlen);
+ if (retval != -1)
+ retval = 0;
+
+ return retval;
+}
+
int execute_program(const char *command, const char *subsystem,
char *result, size_t ressize, size_t *reslen)
{
diff --git a/udev_utils.h b/udev_utils.h
index 5f4152df..5b223855 100644
--- a/udev_utils.h
+++ b/udev_utils.h
@@ -44,6 +44,7 @@ extern void replace_untrusted_chars(char *string);
extern int name_list_add(struct list_head *name_list, const char *name, int sort);
extern int name_list_key_add(struct list_head *name_list, const char *key, const char *value);
extern int add_matching_files(struct list_head *name_list, const char *dirname, const char *suffix);
+extern int pass_env_to_socket(const char *name, const char *devpath, const char *action);
extern int execute_program(const char *command, const char *subsystem,
char *result, size_t ressize, size_t *reslen);
diff --git a/udevsend.c b/udevsend.c
index 94ab6ff6..0ba1b58a 100644
--- a/udevsend.c
+++ b/udevsend.c
@@ -19,17 +19,17 @@
*
*/
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/wait.h>
-#include <sys/un.h>
-#include <time.h>
-#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
-#include <string.h>
#include <unistd.h>
+#include <string.h>
+#include <time.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+#include <sys/un.h>
#include <linux/stddef.h>
#include "udev.h"
diff --git a/udevstart.c b/udevstart.c
index 0bcbc397..5f3ba711 100644
--- a/udevstart.c
+++ b/udevstart.c
@@ -160,8 +160,12 @@ run:
struct name_entry *name_loop;
dbg("executing run list");
- list_for_each_entry(name_loop, &udev.run_list, node)
- execute_program(name_loop->name, udev.subsystem, NULL, 0, NULL);
+ list_for_each_entry(name_loop, &udev.run_list, node) {
+ if (strncmp(name_loop->name, "socket:", strlen("socket:")) == 0)
+ pass_env_to_socket(&name_loop->name[strlen("socket:")], devpath, "add");
+ else
+ execute_program(name_loop->name, udev.subsystem, NULL, 0, NULL);
+ }
}
exit:
sysfs_close_class_device(class_dev);