mirror of
https://github.com/systemd/systemd.git
synced 2024-12-26 03:22:00 +03:00
udevinitsend: handle replay messages correctly
Signed-off-by: Kay Sievers <kay.sievers@suse.de>
This commit is contained in:
parent
d27d8d6a8d
commit
510de9c9e4
13
udevd.c
13
udevd.c
@ -542,13 +542,15 @@ static struct uevent_msg *get_udevd_msg(void)
|
||||
}
|
||||
|
||||
switch (usend_msg.type) {
|
||||
case UDEVD_UEVENT:
|
||||
dbg("udevd message (UEVENT) received");
|
||||
case UDEVD_UDEVSEND:
|
||||
case UDEVD_INITSEND:
|
||||
dbg("udevd event message received");
|
||||
envbuf_size = size - offsetof(struct udevd_msg, envbuf);
|
||||
dbg("envbuf_size=%i", envbuf_size);
|
||||
msg = get_msg_from_envbuf(usend_msg.envbuf, envbuf_size);
|
||||
if (msg == NULL)
|
||||
return NULL;
|
||||
msg->type = usend_msg.type;
|
||||
return msg;
|
||||
case UDEVD_STOP_EXEC_QUEUE:
|
||||
dbg("udevd message (STOP_EXEC_QUEUE) received");
|
||||
@ -566,7 +568,7 @@ switch (usend_msg.type) {
|
||||
}
|
||||
|
||||
/* receive the kernel user event message and do some sanity checks */
|
||||
static struct uevent_msg *get_uevent_msg(void)
|
||||
static struct uevent_msg *get_nl_msg(void)
|
||||
{
|
||||
struct uevent_msg *msg;
|
||||
int bufpos;
|
||||
@ -591,6 +593,7 @@ static struct uevent_msg *get_uevent_msg(void)
|
||||
msg = get_msg_from_envbuf(&buffer[bufpos], size-bufpos);
|
||||
if (msg == NULL)
|
||||
return NULL;
|
||||
msg->type = UDEVD_NL;
|
||||
|
||||
/* validate message */
|
||||
pos = strchr(buffer, '@');
|
||||
@ -935,7 +938,7 @@ int main(int argc, char *argv[], char *envp[])
|
||||
msg = get_udevd_msg();
|
||||
if (msg) {
|
||||
/* discard kernel messages if netlink is active */
|
||||
if (uevent_nl_active && msg->seqnum != 0) {
|
||||
if (uevent_nl_active && msg->type == UDEVD_UDEVSEND && msg->seqnum != 0) {
|
||||
dbg("skip uevent_helper message, netlink is active");
|
||||
free(msg);
|
||||
continue;
|
||||
@ -945,7 +948,7 @@ int main(int argc, char *argv[], char *envp[])
|
||||
}
|
||||
|
||||
if (FD_ISSET(uevent_nl_sock, &workreadfds)) {
|
||||
msg = get_uevent_msg();
|
||||
msg = get_nl_msg();
|
||||
if (msg) {
|
||||
msg_queue_insert(msg);
|
||||
/* disable kernel uevent_helper with first netlink message */
|
||||
|
5
udevd.h
5
udevd.h
@ -50,7 +50,9 @@
|
||||
|
||||
enum udevd_msg_type {
|
||||
UDEVD_UNKNOWN,
|
||||
UDEVD_UEVENT,
|
||||
UDEVD_UDEVSEND,
|
||||
UDEVD_INITSEND,
|
||||
UDEVD_NL,
|
||||
UDEVD_STOP_EXEC_QUEUE,
|
||||
UDEVD_START_EXEC_QUEUE,
|
||||
};
|
||||
@ -63,6 +65,7 @@ struct udevd_msg {
|
||||
};
|
||||
|
||||
struct uevent_msg {
|
||||
enum udevd_msg_type type;
|
||||
struct list_head node;
|
||||
pid_t pid;
|
||||
long queue_time;
|
||||
|
@ -58,17 +58,18 @@ void log_message (int level, const char *format, ...)
|
||||
* Scan a file, write all variables into the msgbuf and
|
||||
* fires the message to udevd.
|
||||
*/
|
||||
static int udevsend(char *filename, int sock, int ignore_loops)
|
||||
static int udevsend(char *filename, int sock, int disable_loop_detection)
|
||||
{
|
||||
struct stat statbuf;
|
||||
int fd, bufpos;
|
||||
char *fdmap, *ls, *le, *ch;
|
||||
struct udevd_msg usend_msg;
|
||||
int retval = 0;
|
||||
static struct udevd_msg usend_msg;
|
||||
int usend_msg_len;
|
||||
int bufpos = 0;
|
||||
struct stat statbuf;
|
||||
int fd;
|
||||
char *fdmap, *ls, *le, *ch;
|
||||
struct sockaddr_un saddr;
|
||||
socklen_t addrlen;
|
||||
|
||||
int retval = 0;
|
||||
|
||||
if (stat(filename,&statbuf) < 0) {
|
||||
dbg("cannot stat %s: %s\n", filename, strerror(errno));
|
||||
return 1;
|
||||
@ -91,24 +92,23 @@ static int udevsend(char *filename, int sock, int ignore_loops)
|
||||
strcpy(&saddr.sun_path[1], UDEVD_SOCK_PATH);
|
||||
addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(saddr.sun_path+1) + 1;
|
||||
|
||||
memset(usend_msg.envbuf, 0, UEVENT_BUFFER_SIZE+256);
|
||||
bufpos = 0;
|
||||
memset(&usend_msg, 0x00, sizeof(struct udevd_msg));
|
||||
strcpy(usend_msg.magic, UDEV_MAGIC);
|
||||
usend_msg.type = UDEVD_INITSEND;
|
||||
|
||||
ls = fdmap;
|
||||
ch = le = ls;
|
||||
while (*ch && ch < fdmap + statbuf.st_size) {
|
||||
le = strchr(ch,'\n');
|
||||
le = strchr(ch, '\n');
|
||||
if (!le)
|
||||
break;
|
||||
ch = strchr(ch,'=');
|
||||
ch = strchr(ch, '=');
|
||||
if (!ch)
|
||||
break;
|
||||
|
||||
/* prevent loops in the scripts we execute */
|
||||
if (strncmp(ls, "UDEVD_EVENT=", 12) == 0) {
|
||||
if (!ignore_loops) {
|
||||
if (!disable_loop_detection) {
|
||||
dbg("event already handled by udev\n");
|
||||
retval = -1;
|
||||
break;
|
||||
@ -161,7 +161,8 @@ int main(int argc, char *argv[], char *envp[])
|
||||
char *event_file = NULL;
|
||||
DIR *dirstream;
|
||||
struct dirent *direntry;
|
||||
int retval = 1, ignore_loops = 0;
|
||||
int retval = 1;
|
||||
int disable_loop_detection = 0;
|
||||
int sock;
|
||||
|
||||
logging_init("udevinitsend");
|
||||
@ -186,14 +187,10 @@ int main(int argc, char *argv[], char *envp[])
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
dbg("ignoring loops\n");
|
||||
ignore_loops = 1;
|
||||
dbg("disable loop detection, ignore UDEVD_EVENT\n");
|
||||
disable_loop_detection = 1;
|
||||
break;
|
||||
|
||||
case 'V':
|
||||
printf("udevinitsend, version 0.1\n");
|
||||
return 0;
|
||||
|
||||
case 'h':
|
||||
retval = 0;
|
||||
}
|
||||
@ -217,11 +214,11 @@ int main(int argc, char *argv[], char *envp[])
|
||||
if (!strcmp(direntry->d_name,".") ||
|
||||
!strcmp(direntry->d_name,".."))
|
||||
continue;
|
||||
retval = udevsend(direntry->d_name, sock, ignore_loops);
|
||||
retval = udevsend(direntry->d_name, sock, disable_loop_detection);
|
||||
}
|
||||
closedir(dirstream);
|
||||
} else if (event_file) {
|
||||
retval = udevsend(event_file, sock, ignore_loops);
|
||||
retval = udevsend(event_file, sock, disable_loop_detection);
|
||||
}
|
||||
|
||||
if (sock != -1)
|
||||
|
@ -146,7 +146,7 @@ int main(int argc, char *argv[], char *envp[])
|
||||
|
||||
memset(&usend_msg, 0x00, sizeof(struct udevd_msg));
|
||||
strcpy(usend_msg.magic, UDEV_MAGIC);
|
||||
usend_msg.type = UDEVD_UEVENT;
|
||||
usend_msg.type = UDEVD_UDEVSEND;
|
||||
|
||||
/* copy all keys to send buffer */
|
||||
for (i = 0; envp[i]; i++) {
|
||||
|
Loading…
Reference in New Issue
Block a user