Re: [Utopia] kernel -> dbus event delivery?



On Fri, Jul 09, 2004 at 07:18:19PM +0200, Kay Sievers wrote:
> On Fri, Jul 09, 2004 at 01:39:54AM +0200, Kay Sievers wrote:
> > On Thu, Jul 08, 2004 at 10:34:18AM -0400, Robert Love wrote:
> > > 
> > > I will be talking at OLS on the event system and D-BUS, so hopefully I
> > > can attract some attention.
> > > 
> > > Anyhow, my latest patch is here:
> > > 
> > > http://www.kernel.org/pub/linux/kernel/people/rml/events/
>
>   I want to be able to send hotplug messages on a new group, so what is the
>   best raw format to compose it. We need to pass several key value pairs, like
>   we do in the environment of the hotplug call today. Should the strings be:
>     'KEY=value\0KEY2=value2\0', or should we use
>     'KEY:value\nKEY2:value2\n\n', like the mail header format?
>   (As a proof of the concept, I will probably convert udevd to listen on the
>    socket, instead of getting the message by the forked udevsend helper)

Ok, here we go. Attached is a experimental patch to udevd, which
switches from the forked udevsend helper to listen directly to the
netlink socket. It's only to proof the concept, the parsing code
is totally stupid :)

I have now 2 applications running kdbusd getting all broadcasts and
udevd getting only KMSG_HOTPLUG. Did I already mention it? Netlink
broadcast is soo cool. :)

It looks pretty nice, is blasting fast and 21th century!

Thanks,
Kay
===== Makefile 1.163 vs edited =====
--- 1.163/Makefile	2004-07-09 19:59:03 +02:00
+++ edited/Makefile	2004-07-11 13:16:40 +02:00
@@ -165,7 +165,7 @@
 	WARNINGS += -Wshadow -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations
 	CRT0 =
 	LIBC = 
-	CFLAGS += $(WARNINGS) -I$(GCCINCDIR)
+	CFLAGS += $(WARNINGS) -I ../linux.pm/include -I$(GCCINCDIR)
 	LIB_OBJS = -lc
 	LDFLAGS =
 endif
===== udevd.c 1.33 vs edited =====
--- 1.33/udevd.c	2004-06-07 02:50:03 +02:00
+++ edited/udevd.c	2004-07-11 14:04:19 +02:00
@@ -31,7 +31,9 @@
 #include <sys/time.h>
 #include <sys/types.h>
 #include <sys/socket.h>
-#include <sys/un.h>
+#include <sys/user.h>
+#include <linux/netlink.h>
+#include <linux/kmessage.h>
 #include <fcntl.h>
 #include "klibc_fixups.h"
 #include <sys/sysinfo.h>
@@ -43,6 +45,11 @@
 #include "udevd.h"
 #include "logging.h"
 
+#define SENDER_HEADER		"From: "
+#define SIGNAL_HEADER		"Signal: "
+#define DEVPATH_HEADER		"Devpath: "
+#define SEQNUM_HEADER		"Seqnum: "
+
 static int pipefds[2];
 static int expected_seqnum = 0;
 volatile static int children_waiting;
@@ -247,11 +254,9 @@
 {
 	struct hotplug_msg *msg;
 	int retval;
-	struct msghdr smsg;
-	struct cmsghdr *cmsg;
-	struct iovec iov;
-	struct ucred *cred;
-	char cred_msg[CMSG_SPACE(sizeof(struct ucred))];
+	char buf[PAGE_SIZE];
+	char *string;	
+	char *pos;	
 
 	msg = msg_create();
 	if (msg == NULL) {
@@ -259,38 +264,60 @@
 		return;
 	}
 
-	iov.iov_base = msg;
-	iov.iov_len = sizeof(struct hotplug_msg);
-
-	memset(&smsg, 0x00, sizeof(struct msghdr));
-	smsg.msg_iov = &iov;
-	smsg.msg_iovlen = 1;
-	smsg.msg_control = cred_msg;
-	smsg.msg_controllen = sizeof(cred_msg);
-
-	retval = recvmsg(sock, &smsg, 0);
+	retval = recv(sock, &buf, sizeof(buf), 0);
 	if (retval <  0) {
 		if (errno != EINTR)
 			dbg("unable to receive message");
 		return;
 	}
-	cmsg = CMSG_FIRSTHDR(&smsg);
-	cred = (struct ucred *) CMSG_DATA(cmsg);
 
-	if (cmsg == NULL || cmsg->cmsg_type != SCM_CREDENTIALS) {
-		dbg("no sender credentials received, message ignored");
+	/* STUPID-TEST-ONLY: HARD CODED MESSAGE PARSING */
+
+	pos = buf;
+	
+	string = strsep(&pos, "\n");
+	if (string == NULL)
+		goto skip;
+
+	/* expecting sending object */
+	if (strncmp(string, SENDER_HEADER, strlen(SENDER_HEADER)) != 0) {
+		dbg("missing " SENDER_HEADER);
 		goto skip;
 	}
+	string = strsep(&pos, "\n");
+	if (string == NULL)
+		goto skip;
 
-	if (cred->uid != 0) {
-		dbg("sender uid=%i, message ignored", cred->uid);
+	/* expecting name of signal, emitted from object */
+	if (strncmp(string, SIGNAL_HEADER, strlen(SIGNAL_HEADER)) != 0) {
+		dbg("missing " SIGNAL_HEADER);
 		goto skip;
 	}
+	strfieldcpy(msg->action, &string[strlen(SIGNAL_HEADER)]);
+	dbg("action '%s'", msg->action);
+	string = strsep(&pos, "\n");
+	if (string == NULL)
+		goto skip;
 
-	if (strncmp(msg->magic, UDEV_MAGIC, sizeof(UDEV_MAGIC)) != 0 ) {
-		dbg("message magic '%s' doesn't match, ignore it", msg->magic);
+	/* expecting devpath */
+	if (strncmp(string, DEVPATH_HEADER, strlen(DEVPATH_HEADER)) != 0) {
+		dbg("missing " DEVPATH_HEADER);
 		goto skip;
 	}
+	strfieldcpy(msg->devpath, &string[strlen(DEVPATH_HEADER)]);
+	dbg("devpath '%s'", msg->devpath);
+	string = strsep(&pos, "\n");
+	if (string == NULL)
+		goto skip;
+
+	/* expecting sequence */
+	if (strncmp(string, SEQNUM_HEADER, strlen(SEQNUM_HEADER)) != 0) {
+		dbg("missing " SEQNUM_HEADER);
+		goto skip;
+	}
+	msg->seqnum = atoi(&string[strlen(SEQNUM_HEADER)]);
+	dbg("seqnum '%i'", msg->seqnum);
+
 
 	/* if no seqnum is given, we move straight to exec queue */
 	if (msg->seqnum == -1) {
@@ -393,10 +420,8 @@
 int main(int argc, char *argv[])
 {
 	int ssock, maxsockplus;
-	struct sockaddr_un saddr;
-	socklen_t addrlen;
+	struct sockaddr_nl snl;
 	int retval;
-	const int on = 1;
 	struct sigaction act;
 	fd_set readfds;
 
@@ -436,27 +461,22 @@
 	sigaction(SIGALRM, &act, NULL);
 	sigaction(SIGCHLD, &act, NULL);
 
-	memset(&saddr, 0x00, sizeof(saddr));
-	saddr.sun_family = AF_LOCAL;
-	/* use abstract namespace for socket path */
-	strcpy(&saddr.sun_path[1], UDEVD_SOCK_PATH);
-	addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(saddr.sun_path+1) + 1;
+	memset(&snl, 0x00, sizeof(snl));
+	snl.nl_family = AF_NETLINK;
+	snl.nl_pid = getpid();
+	snl.nl_groups = 0xffff; //1 << KMSG_HOTPLUG;
 
-	ssock = socket(AF_LOCAL, SOCK_DGRAM, 0);
+	ssock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KMESSAGE);
 	if (ssock == -1) {
 		dbg("error getting socket, exit");
 		exit(1);
 	}
 
-	/* the bind takes care of ensuring only one copy running */
-	retval = bind(ssock, (struct sockaddr *) &saddr, addrlen);
+	retval = bind(ssock, (struct sockaddr *) &snl, sizeof(snl));
 	if (retval < 0) {
 		dbg("bind failed, exit");
 		goto exit;
 	}
-
-	/* enable receiving of the sender credentials */
-	setsockopt(ssock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on));
 
 	/* possible override of udev binary, used for testing */
 	udev_bin = getenv("UDEV_BIN");


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]