linux-hotplug.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Chris Friesen <chris_friesen@sympatico.ca>
To: linux-hotplug@vger.kernel.org
Subject: [PATCH] closing the loop -- retries and acks
Date: Wed, 18 Feb 2004 06:26:43 +0000	[thread overview]
Message-ID: <403305A3.2070604@sympatico.ca> (raw)

[-- Attachment #1: Type: text/plain, Size: 895 bytes --]

This patch reduces the already low chances of lost messages.

Once udevsend successfully sends a message, it waits with a timeout for
a response.  If the response is good, then all is well, otherwise it
sends the message again.

In udevd, when we receive a request we store the address of the
requestor, and then once the request has been handled we then send an
ack back so that they know they have been taken care of.

This patch takes care of the basics, but there are still a few things left:
1) tuning timeouts and retry numbers
2) capabilities check on the ack
3) pull out the udevd-specific stuff from struct hotplug_msg so that we
don't waste time/memory.  udevd will have a different struct, one
element of which is hotplug_msg.  udevsend still only knows about
hotplug_msg
4) pull the messaging stuff into a set of headers or something to get
rid of code duplication

Comments?

Chris

[-- Attachment #2: udevack.patch --]
[-- Type: text/plain, Size: 4424 bytes --]

diff -Nur --exclude=RCS --exclude=CVS --exclude=SCCS --exclude=BitKeeper --exclude=ChangeSet udev/udevd.c myudev/udevd.c
--- udev/udevd.c	Wed Feb 18 00:50:51 2004
+++ myudev/udevd.c	Wed Feb 18 01:16:00 2004
@@ -232,6 +232,7 @@
 	struct iovec iov;
 	struct ucred *cred;
 	char cred_msg[CMSG_SPACE(sizeof(struct ucred))];
+	struct sockaddr_un addr;
 
 	msg = msg_create();
 	if (msg == NULL) {
@@ -247,13 +248,21 @@
 	smsg.msg_iovlen = 1;
 	smsg.msg_control = cred_msg;
 	smsg.msg_controllen = sizeof(cred_msg);
+	smsg.msg_name = &addr;
+	smsg.msg_namelen = sizeof(addr);
 
 	retval = recvmsg(sock, &smsg, 0);
 	if (retval <  0) {
 		if (errno != EINTR)
 			dbg("unable to receive message");
-		return;
+		goto skip;
 	}
+	
+	if (retval != sizeof(struct hotplug_msg)) {
+		dbg("wrong message size");
+		goto skip;
+	}
+	
 	cmsg = CMSG_FIRSTHDR(&smsg);
 	cred = (struct ucred *) CMSG_DATA(cmsg);
 
@@ -271,7 +280,10 @@
 		dbg("message magic '%s' doesn't match, ignore it", msg->magic);
 		goto skip;
 	}
-
+	
+	memcpy(&msg->addr, smsg.msg_name, smsg.msg_namelen);
+	msg->addrlen = smsg.msg_namelen;
+	
 	/* if no seqnum is given, we move straight to exec queue */
 	if (msg->seqnum == -1) {
 		list_add(&msg->list, &exec_list);
@@ -304,7 +316,7 @@
 	}
 }
 
-static void udev_done(int pid)
+static void udev_done(int pid, int sock)
 {
 	/* find msg associated with pid and delete it */
 	struct hotplug_msg *msg;
@@ -312,6 +324,10 @@
 	list_for_each_entry(msg, &running_list, list) {
 		if (msg->pid == pid) {
 			dbg("<== exec seq %d came back", msg->seqnum);
+			
+			/* send ack back to udevsend */
+			sendto(sock, msg, sizeof(struct hotplug_msg), 0, (struct sockaddr*) &msg->addr, msg->addrlen);
+			
 			run_queue_delete(msg);
 			return;
 		}
@@ -384,7 +400,7 @@
 				int pid = waitpid(-1, 0, WNOHANG);
 				if ((pid == -1) || (pid == 0))
 					break;
-				udev_done(pid);
+				udev_done(pid, ssock);
 			}
 		}
 	}
diff -Nur --exclude=RCS --exclude=CVS --exclude=SCCS --exclude=BitKeeper --exclude=ChangeSet udev/udevd.h myudev/udevd.h
--- udev/udevd.h	Thu Feb  5 23:44:52 2004
+++ myudev/udevd.h	Wed Feb 18 01:16:50 2004
@@ -28,13 +28,16 @@
 #define EVENT_TIMEOUT_SEC		5
 #define UDEVSEND_CONNECT_RETRY		20 /* x 100 millisec */
 #define UDEVD_SOCK_PATH			"udevd"
+#define ACK_TIMEOUT_SEC (EVENT_TIMEOUT_SEC + 1)
 
 struct hotplug_msg {
-	char magic[20];
 	struct list_head list;
 	pid_t pid;
-	int seqnum;
 	time_t queue_time;
+	struct sockaddr_un addr;
+	socklen_t addrlen;
+	char magic[20];
+	int seqnum;
 	char action[8];
 	char devpath[128];
 	char subsystem[16];
diff -Nur --exclude=RCS --exclude=CVS --exclude=SCCS --exclude=BitKeeper --exclude=ChangeSet udev/udevsend.c myudev/udevsend.c
--- udev/udevsend.c	Wed Feb 18 00:50:51 2004
+++ myudev/udevsend.c	Wed Feb 18 00:58:02 2004
@@ -22,6 +22,7 @@
  *
  */
 
+#include <sys/select.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/wait.h>
@@ -180,6 +181,14 @@
 
 	memset(&saddr, 0x00, sizeof(saddr));
 	saddr.sun_family = AF_LOCAL;
+	sprintf(&saddr.sun_path[1], "%d", getpid());
+	addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(saddr.sun_path+1) + 1;
+	
+	if (bind(sock, (struct sockaddr*)&saddr, addrlen) < 0) {
+		dbg("error binding socket");
+		goto exit;
+	}
+		
 	/* 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;
@@ -188,11 +197,36 @@
 
 	/* If we can't send, try to start daemon and resend message */
 	loop = UDEVSEND_CONNECT_RETRY;
+send_msg:
 	while (loop--) {
 		retval = sendto(sock, &msg, size, 0, (struct sockaddr *)&saddr, addrlen);
 		if (retval != -1) {
-			retval = 0;
-			goto close_and_exit;
+			
+			/* wait for ack */
+			fd_set rdset;
+			int rc;
+			struct timeval tv = {ACK_TIMEOUT_SEC, 0};
+						
+			while(1) {
+				FD_ZERO(&rdset);
+				FD_SET(sock, &rdset);
+				rc = select(sock+1, &rdset, 0, 0, &tv);
+				
+				if (!rc)
+					goto send_msg;
+				
+				if (FD_ISSET(sock, &rdset)) {
+					struct hotplug_msg ack;
+					
+					retval = recv(sock, &ack, sizeof(ack), MSG_DONTWAIT);
+					if ((retval > 0) && 
+							(strncmp(ack.magic, msg.magic, sizeof(UDEV_MAGIC)) == 0 ) &&
+							(ack.seqnum == msg.seqnum)) {
+						retval = 0;
+						goto close_and_exit;
+					}
+				}
+			}
 		}
 		
 		if (errno != ECONNREFUSED) {
Binary files udev/udevtest and myudev/udevtest differ

             reply	other threads:[~2004-02-18  6:26 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-02-18  6:26 Chris Friesen [this message]
2004-02-18  8:27 ` [PATCH] closing the loop -- retries and acks Kay Sievers
2004-02-19  5:44 ` Chris Friesen
2004-02-19  7:52 ` Kay Sievers
2004-02-21  0:43 ` Greg KH
2004-02-21  0:44 ` Greg KH
2004-02-22  3:48 ` Chris Friesen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=403305A3.2070604@sympatico.ca \
    --to=chris_friesen@sympatico.ca \
    --cc=linux-hotplug@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).