From mboxrd@z Thu Jan 1 00:00:00 1970 From: Kay Sievers Date: Wed, 21 Jan 2004 13:38:25 +0000 Subject: Re: about split the udev Message-Id: <20040121133825.GA31006@vrfy.org> MIME-Version: 1 Content-Type: multipart/mixed; boundary="rwEMma7ioTxnRzrJ" List-Id: References: <3ACA40606221794F80A5670F0AF15F8402D4EE96@PDSMSX403.ccr.corp.intel.com> In-Reply-To: <3ACA40606221794F80A5670F0AF15F8402D4EE96@PDSMSX403.ccr.corp.intel.com> To: linux-hotplug@vger.kernel.org --rwEMma7ioTxnRzrJ Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Thu, Jan 15, 2004 at 01:45:10PM -0800, Greg KH wrote: > On Thu, Jan 15, 2004 at 10:36:25PM +0800, Ling, Xiaofeng wrote: > > Hi, Greg > > I wrote a simple implementation for the two pieces > > of send and receive hotplug event, > > use a message queue and a list for the out of order > > hotplug event. It also has a timeout timer of 3 seconds. > > They are now separate program. the file nseq is the test script. > > Could you have a look to see wether it is feasible? > > If so, I'll continue to merge with udev. > > Yes, very nice start. Please continue on. > > One minor comment, please stick with the kernel coding style when you > are writing new code for udev. I took the code from Xiaofeng, cleaned the whitespace, renamed some bits, tweaked the debugging, added the udev exec and created a patch for the current tree. It seems functional now, by simply executing our current udev (dirty hack). It reorders the incoming events and if one is missing it delays the execution of the following ones up to a maximum of 10 seconds. Test script is included, but you can't mix hotplug sequence numbers and test script numbers, it will result in waiting for the missing numbers :) please have a look at it... thanks, Kay --rwEMma7ioTxnRzrJ Content-Type: text/plain; charset=us-ascii Content-Disposition: inline; filename="01-udevd2.patch" diff -Nru a/Makefile b/Makefile --- a/Makefile Wed Jan 21 14:12:22 2004 +++ b/Makefile Wed Jan 21 14:12:22 2004 @@ -31,6 +31,8 @@ ROOT = udev +DAEMON = udevd +SENDER = udevsend VERSION = 013_bk INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) @@ -155,7 +157,7 @@ CFLAGS += -I$(PWD)/libsysfs -all: $(ROOT) +all: $(ROOT) $(DAEMON) $(SENDER) @extras="$(EXTRAS)" ; for target in $$extras ; do \ echo $$target ; \ $(MAKE) prefix=$(prefix) LD="$(LD)" SYSFS="$(SYSFS)" \ @@ -229,10 +231,18 @@ $(LD) $(LDFLAGS) -o $(ROOT) $(CRT0) $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) $(STRIPCMD) $(ROOT) +$(DAEMON): $(ROOT) udevd.h udevd.o + $(LD) $(LDFLAGS) -o $(DAEMON) $(CRT0) udevd.o logging.o $(LIB_OBJS) $(ARCH_LIB_OBJS) + $(STRIPCMD) $(ROOT) + +$(SENDER): $(ROOT) udevd.h udevsend.o + $(LD) $(LDFLAGS) -o $(SENDER) $(CRT0) udevsend.o logging.o $(LIB_OBJS) $(ARCH_LIB_OBJS) + $(STRIPCMD) $(ROOT) + clean: -find . \( -not -type d \) -and \( -name '*~' -o -name '*.[oas]' \) -type f -print \ | xargs rm -f - -rm -f core $(ROOT) $(GEN_HEADERS) $(GEN_CONFIGS) + -rm -f core $(ROOT) $(GEN_HEADERS) $(GEN_CONFIGS) $(DAEMON) $(SENDER) $(MAKE) -C klibc clean @extras="$(EXTRAS)" ; for target in $$extras ; do \ echo $$target ; \ diff -Nru a/test/udevd_test.sh b/test/udevd_test.sh --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/test/udevd_test.sh Wed Jan 21 14:12:22 2004 @@ -0,0 +1,31 @@ +#!/bin/bash + + +export ACTION=add +export DEVPATH=/block/sda +export SEQNUM=1 +./udevsend block +export SEQNUM=2 +./udevsend block +export SEQNUM=3 +./udevsend block +export SEQNUM=5 +./udevsend block +export SEQNUM=4 +./udevsend block +export SEQNUM=6 +./udevsend block +export SEQNUM=7 +./udevsend block +export SEQNUM=10 +./udevsend block +export SEQNUM=9 +./udevsend block +export SEQNUM=8 +./udevsend block +export SEQNUM=11 +./udevsend block +export SEQNUM=12 +./udevsend block +export SEQNUM=13 +./udevsend block diff -Nru a/udevd.c b/udevd.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/udevd.c Wed Jan 21 14:12:22 2004 @@ -0,0 +1,198 @@ +/* + * udevd.c + * + * Userspace devfs + * + * Copyright (C) 2004 Ling, Xiaofeng + * Copyright (C) 2004 Kay Sievers + * + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" +#include "udevd.h" +#include "logging.h" + +#define BUFFER_SIZE 1024 +#define TIMEOUT_SECONDS 10 + +static int expect_seqnum = 0; +static int timeout_value = TIMEOUT_SECONDS; +static int timeout = 0; +static struct hotplug_msg *head = NULL; + + +static void sig_alarmhandler(int signum) +{ + dbg("caught signal %d", signum); + switch (signum) { + case SIGALRM: + timeout = 1; + dbg("timeout, event lost"); + default: + dbg("unhandled signal"); + } +} + +static void dump_queue(void) +{ + struct hotplug_msg *p; + p = head; + dbg("next expected sequence %d", expect_seqnum); + while(p) { + dbg("waiting for sequence %d", p->seqnum); + p=p->next; + } +} + +static void dump_msg(struct hotplug_msg *pmsg) +{ + dbg("sequence %d, '%s', '%s', '%s'", + pmsg->seqnum, pmsg->action, pmsg->devpath, pmsg->subsystem); +} + +static void dispatch_msg(struct hotplug_msg *pmsg) +{ + char name[100]; + + dump_msg(pmsg); + + /* FIXME: this is proof of concept only :) */ + setenv("ACTION", pmsg->action, 1); + setenv("DEVPATH", pmsg->devpath, 1); + + strcpy(name, "/sbin/udev "); + strncat(name, pmsg->subsystem, sizeof(name)); + system(name); +} + +static void reset_timer(void) +{ + alarm(0); +} + +static void set_timer(void) +{ + signal(SIGALRM, sig_alarmhandler); + alarm(timeout_value); +} + +static void check_queue(void) +{ + struct hotplug_msg *p; + p = head; + + dump_queue(); + while(head && head->seqnum == expect_seqnum) { + dispatch_msg(head); + expect_seqnum++; + p = head; + head=head->next; + free(p); + } + if (head != NULL) + set_timer(); + else + reset_timer(); +} + +static void add_queue(struct hotplug_msg *pmsg) +{ + struct hotplug_msg *pnewmsg; + struct hotplug_msg *p; + struct hotplug_msg *p1; + + p = head; + p1 = NULL; + pnewmsg = malloc(sizeof(struct hotplug_msg)); + *pnewmsg = *pmsg; + pnewmsg->next = NULL; + while(p && pmsg->seqnum > p->seqnum) { + p1 = p; + p = p->next; + } + pnewmsg->next = p; + if (p1 == NULL) { + head = pnewmsg; + } else { + p1->next = pnewmsg; + } + dump_queue(); +} + +static int process_queue(void) +{ + int msgid; + key_t key; + struct hotplug_msg *pmsg; + char buf[BUFFER_SIZE]; + int ret; + + key = 12345; /*may use inode number of /etc/udev? */ + pmsg = (struct hotplug_msg *) buf; + msgid = msgget(key, IPC_CREAT); + if (msgid == -1) { + dbg("open message queue error"); + goto exit; + } + while (1) { + ret = msgrcv(msgid, (struct msgbuf *) buf, BUFFER_SIZE-4, HOTPLUGMSGTYPE, 0); + if (ret != -1) { + dbg("current sequence %d, expected sequence %d", pmsg->seqnum, expect_seqnum); + if (expect_seqnum == 0) /* init sequence with very first call */ + expect_seqnum = pmsg->seqnum; + if (pmsg->seqnum > expect_seqnum) { + add_queue(pmsg); + set_timer(); + } else { + if (pmsg->seqnum == expect_seqnum) { + dispatch_msg(pmsg); + expect_seqnum++; + check_queue(); + } else { + dbg("timeout event come again"); + } + } + } else + if (errno == EINTR) { + dbg("recv signal '%s'", strerror(errno)); + expect_seqnum++; + check_queue(); + timeout = 0; + } else { + dbg("recv error '%s'", strerror(errno)); + } + } + return 0; +exit: + return -1; +} + +int main(int argc, char *argv[]) +{ + process_queue(); + return 0; +} diff -Nru a/udevd.h b/udevd.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/udevd.h Wed Jan 21 14:12:22 2004 @@ -0,0 +1,33 @@ +/* + * udevd.h + * + * Userspace devfs + * + * Copyright (C) 2004 Ling, Xiaofeng + * + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#define HOTPLUGMSGTYPE 44 + +struct hotplug_msg { + long mtype; + struct hotplug_msg *next; + int seqnum; + char action[8]; + char devpath[128]; + char subsystem[16]; +}; diff -Nru a/udevsend.c b/udevsend.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/udevsend.c Wed Jan 21 14:12:22 2004 @@ -0,0 +1,142 @@ +/* + * udevsend.c + * + * Userspace devfs + * + * Copyright (C) 2004 Ling, Xiaofeng + * + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" +#include "udevd.h" +#include "logging.h" + +static inline char *get_action(void) +{ + char *action; + + action = getenv("ACTION"); + return action; +} + +static inline char *get_devpath(void) +{ + char *devpath; + + devpath = getenv("DEVPATH"); + return devpath; +} + +static inline char *get_seqnum(void) +{ + char *seqnum; + + seqnum = getenv("SEQNUM"); + return seqnum; +} + +static int build_hotplugmsg(struct hotplug_msg **ppmsg, char *action, + char *devpath, char *subsystem, int seqnum) +{ + struct hotplug_msg *pmsg; + pmsg = malloc(sizeof(struct hotplug_msg)); + pmsg->mtype = HOTPLUGMSGTYPE; + pmsg->seqnum = seqnum; + strncpy(pmsg->action, action, 8); + strncpy(pmsg->devpath, devpath, 128); + strncpy(pmsg->subsystem, subsystem, 16); + *ppmsg = pmsg; + return sizeof(struct hotplug_msg); +} + +static void free_hotplugmsg(struct hotplug_msg *pmsg) +{ + free(pmsg); +} + +int main(int argc, char* argv[]) +{ + int msgid; + struct msgbuf *pmsg; + key_t key; + char *action; + char *devpath; + char *subsystem; + char *seqnum; + int seq; + int retval = -EINVAL; + int size; + + key = 12345; /*may use inode number of /etc/udev?*/ + + subsystem = argv[1]; + if (subsystem == NULL) { + dbg("no subsystem"); + goto exit; + } + + devpath = get_devpath(); + if (devpath == NULL) { + dbg("no devpath"); + goto exit; + } + + action = get_action(); + if (action == NULL) { + dbg("no action"); + goto exit; + } + + seqnum = get_seqnum(); + if (seqnum == NULL) { + dbg("no seqnum"); + goto exit; + } + + seq = atoi(seqnum); + + size = build_hotplugmsg( (struct hotplug_msg**) &pmsg, action, devpath, subsystem, seq); + msgid = msgget(key, IPC_CREAT); + if (msgid == -1) + { + dbg("open message queue error"); + goto exit; + } + + retval = msgsnd(msgid, pmsg, size, 0); + free_hotplugmsg( (struct hotplug_msg*) pmsg); + if (retval == -1) + { + dbg("send message error"); + goto exit; + } + return 0; + +exit: + if (retval > 0) + retval = 0; + + return retval; +} --rwEMma7ioTxnRzrJ-- ------------------------------------------------------- The SF.Net email is sponsored by EclipseCon 2004 Premiere Conference on Open Tools Development and Integration See the breadth of Eclipse activity. February 3-5 in Anaheim, CA. http://www.eclipsecon.org/osdn _______________________________________________ Linux-hotplug-devel mailing list http://linux-hotplug.sourceforge.net Linux-hotplug-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-hotplug-devel