svn commit: samba r10583 - in branches/tmp/vl-cluster/source: lib torture

vlendec at samba.org vlendec at samba.org
Wed Sep 28 15:15:22 GMT 2005


Author: vlendec
Date: 2005-09-28 15:15:22 +0000 (Wed, 28 Sep 2005)
New Revision: 10583

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=10583

Log:
Commit a checkpoint to proceed from: This implements the fallback to the
dispatch socket if the direct non-blocking send fails with EAGAIN. However,
the central daemon now seems to hit a bug in the linux kernel where select
says a unix *dgram* socket is writable but the subsequent send/write block.

BTW, if you want a perfect backup of your data, post to linux-kernel. Google
for the string 'select "unix dgram socket"' and see on how many mailing list
archives the corresponding message by "Koblinger Egmont" shows up...

Volker

Modified:
   branches/tmp/vl-cluster/source/lib/messages.c
   branches/tmp/vl-cluster/source/torture/msgtest.c


Changeset:
Modified: branches/tmp/vl-cluster/source/lib/messages.c
===================================================================
--- branches/tmp/vl-cluster/source/lib/messages.c	2005-09-28 14:42:04 UTC (rev 10582)
+++ branches/tmp/vl-cluster/source/lib/messages.c	2005-09-28 15:15:22 UTC (rev 10583)
@@ -110,6 +110,13 @@
 		return False;
 	}
 
+	if (set_blocking(socket_fd, False) < 0) {
+		DEBUG(0, ("set_blocking failed: %s\n", strerror(errno)));
+		close(socket_fd);
+		socket_fd = -1;
+		return False;
+	}
+
 	return True;
 }
 
@@ -205,11 +212,13 @@
 	size_t packet_len = sizeof(struct message_rec) + len;
 	struct sockaddr_un sunaddr;
 	ssize_t sent;
+	int attempts;
+	BOOL result = False;
 
 	packet = data_blob(NULL, packet_len);
 	if (packet.data == NULL) {
 		DEBUG(0, ("malloc failed\n"));
-		return False;
+		goto done;
 	}
 
 	hdr = (struct message_rec *)packet.data;
@@ -226,32 +235,71 @@
 	ZERO_STRUCT(sunaddr);
 	sunaddr.sun_family = AF_UNIX;
 
-#if 0
 	strncpy(sunaddr.sun_path, message_path(&pid),
 		sizeof(sunaddr.sun_path)-1);
-	sent = sendto(socket_fd, packet.data, packet.length, 0,
-		      (struct sockaddr *)&sunaddr, sizeof(sunaddr));
-	if (sent != packet.length) {
-		DEBUG(3, ("Could not send %d bytes to Unix domain socket %s: "
-			  "%s\n", packet.length, sunaddr.sun_path,
+
+	for (attempts = 0; attempts < 10; attempts++) {
+		sent = sendto(socket_fd, packet.data, packet.length, 0,
+			      (struct sockaddr *)&sunaddr, sizeof(sunaddr));
+		if ((sent < 0) && (errno == EINTR)) {
+			continue;
+		}
+		break;
+	}
+
+	if (sent == packet.length) {
+		result = True;
+		goto done;
+	}
+
+	if (sent > 0) {
+		DEBUG(0, ("tried to send %d bytes, send returned %d ?? \n",
+			  packet.length, sent));
+		goto done;
+	}
+
+	if ((errno != EAGAIN) && (errno != EWOULDBLOCK)) {
+		DEBUG(3, ("Could not send %d bytes to Unix domain "
+			  "socket %s: %s\n", packet.length,
+			  sunaddr.sun_path, strerror(errno)));
+		goto done;
+	}
+
+	DEBUG(10, ("sending directly would block -- sending to dispatcher in "
+		   "blocking mode\n"));
+
+	if (set_blocking(socket_fd, True) < 0) {
+		DEBUG(3, ("Could not set socket to blocking mode: %s\n",
 			  strerror(errno)));
-		SAFE_FREE(packet.data);
-		return False;
+		goto done;
 	}
-#endif
-
+	
 	strncpy(sunaddr.sun_path, dispatch_socket_name(),
 		sizeof(sunaddr.sun_path)-1);
-	sent = sendto(socket_fd, packet.data, packet.length, 0,
-		      (struct sockaddr *)&sunaddr, sizeof(sunaddr));
+
+	for (attempts = 0; attempts < 10; attempts++) {
+		sent = sendto(socket_fd, packet.data, packet.length, 0,
+			      (struct sockaddr *)&sunaddr, sizeof(sunaddr));
+		if ((sent < 0) && (errno == EINTR)) {
+			continue;
+		}
+		break;
+	}
 	if (sent != packet.length) {
 		DEBUG(3, ("Could not send %d bytes to dispatch socket %s: "
 			  "%s\n", packet.length, sunaddr.sun_path,
 			  strerror(errno)));
-		SAFE_FREE(packet.data);
-		return False;
 	}
 
+	if (set_blocking(socket_fd, False) < 0) {
+		DEBUG(3, ("Could not set socket to non-blocking mode: %s\n",
+			  strerror(errno)));
+	}
+
+	result = True;
+
+ done:
+
 	SAFE_FREE(packet.data);
 	return True;
 }
@@ -824,11 +872,13 @@
 
 	talloc_set_destructor(result, messaging_client_destr);
 
+#if 0
 	if (set_blocking(result->fd, False) < 0) {
 		DEBUG(5, ("set_blocking() failed: %s\n", strerror(errno)));
 		talloc_free(result);
 		return NULL;
 	}
+#endif
 
 	sunaddr.sun_family = AF_UNIX;
 	strncpy(sunaddr.sun_path, message_path(pid),
@@ -946,7 +996,7 @@
 		DEBUG(10, ("dispatching to client %s\n",
 			   procid_str_static(&client->pid)));
 
-		sent = send(client->fd, msg->data.data, msg->data.length, 0);
+		sent = write(client->fd, msg->data.data, msg->data.length);
 
 		if (sent < 0) {
 			if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {

Modified: branches/tmp/vl-cluster/source/torture/msgtest.c
===================================================================
--- branches/tmp/vl-cluster/source/torture/msgtest.c	2005-09-28 14:42:04 UTC (rev 10582)
+++ branches/tmp/vl-cluster/source/torture/msgtest.c	2005-09-28 15:15:22 UTC (rev 10583)
@@ -43,27 +43,46 @@
 	
 	lp_load(dyn_CONFIGFILE,False,False,False);
 
-	message_init();
-
-	if (argc != 3) {
-		fprintf(stderr, "%s: Usage - %s pid count\n", argv[0], argv[0]);
+	if ((argc < 3) || (argc > 4)) {
+		fprintf(stderr, "%s: Usage - %s pid count [conffile]\n",
+			argv[0], argv[0]);
 		exit(1);
 	}
 
-	pid = atoi(argv[1]);
+	if (strcmp(argv[1], "self") == 0) {
+		pid = getpid();
+	} else {
+		pid = atoi(argv[1]);
+	}
 	n = atoi(argv[2]);
 
+	if (argc == 4) {
+		lp_load(argv[3],False,False,False);
+	}
+
+	sec_init();
+	if (!message_init()) {
+		exit(1);
+	}
+
 	message_register(MSG_PONG, pong_message);
 
 	for (i=0;i<n;i++) {
 		message_send_pid(pid_to_procid(pid), MSG_PING, NULL, 0, True);
 	}
 
+	system("/bin/sleep 60");
+
 	while (pong_count < i) {
+		fd_set rfds;
+		struct timeval tv = timeval_set(1,0);
+		FD_ZERO(&rfds);
+		FD_SET(message_socket(), &rfds);
+		select(message_socket()+1, &rfds, NULL, NULL, &tv);
 		message_dispatch();
-		smb_msleep(1);
 	}
 
+#if 0
 	/* Now test that the duplicate filtering code works. */
 	pong_count = 0;
 
@@ -85,6 +104,7 @@
 		fprintf(stderr, "Duplicate filter failed (%d).\n", pong_count);
 		exit(1);
 	}
+#endif
 
 	return (0);
 }



More information about the samba-cvs mailing list