1
0
mirror of https://github.com/systemd/systemd.git synced 2024-12-23 21:35:11 +03:00

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>
This commit is contained in:
Kay Sievers 2005-08-01 05:07:19 +02:00
parent 70721db6d7
commit d455b0085d
5 changed files with 54 additions and 11 deletions

8
udev.c
View File

@ -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);

View File

@ -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)
{

View File

@ -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);

View File

@ -19,17 +19,17 @@
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <stddef.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 <time.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <unistd.h>
#include <linux/stddef.h>
#include "udev.h"

View File

@ -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);