commit fa49f3c13c139be1b2db1bdc88a224527b7c6e51
Author: Serge Hallyn <serge.hallyn@ubuntu.com>
Date:   Tue Apr 29 10:17:42 2014 -0500

    cgmanager-proxy: wait up to 2 seconds for reply from server
    
    We previously waited indefinately, which causes a hang if the server
    crashes.
    
    Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>

Index: cgmanager-0.24/cgmanager-proxy.c
===================================================================
--- cgmanager-0.24.orig/cgmanager-proxy.c	2014-05-08 13:39:00.163408001 -0500
+++ cgmanager-0.24/cgmanager-proxy.c	2014-05-08 13:39:00.143408001 -0500
@@ -45,6 +45,22 @@
 	return false;
 }
 
+/* wait up to 2 seconds for a reply from cgmanager */
+static int proxyrecv(int sockfd, void *buf, size_t len)
+{
+	struct timeval tv;
+	fd_set rfds;
+
+	FD_ZERO(&rfds);
+	FD_SET(sockfd, &rfds);
+	tv.tv_sec = 2;
+	tv.tv_usec = 0;
+
+	if (select(sockfd+1, &rfds, NULL, NULL, &tv) < 0)
+		return -1;
+	return recv(sockfd, buf, len, MSG_DONTWAIT);
+}
+
 static void cgm_dbus_disconnected(DBusConnection *connection);
 
 int setup_proxy(void)
@@ -208,7 +224,7 @@
 	dbus_connection_flush(server_conn);
 	dbus_message_unref(message);
 
-	if (recv(sv[0], buf, 1, 0) != 1) {
+	if (proxyrecv(sv[0], buf, 1) != 1) {
 		nih_error("%s: Error getting reply from server over socketpair",
 			  __func__);
 		return false;
@@ -222,7 +238,7 @@
 	if (!vcred) // this request only requires one scm_credential
 		return true;
 
-	if (recv(sv[0], buf, 1, 0) != 1) {
+	if (proxyrecv(sv[0], buf, 1) != 1) {
 		nih_error("%s: Error getting reply from server over socketpair",
 			__func__);
 		return false;
@@ -273,8 +289,7 @@
 		goto out;
 	}
 
-	// TODO - switch to nih_io_message_recv?
-	if (recv(sv[0], s, MAXPATHLEN-1, 0) <= 0)
+	if (proxyrecv(sv[0], s, MAXPATHLEN-1) <= 0)
 		nih_error("%s: Error reading result from cgmanager",
 			__func__);
 	else {
@@ -334,7 +349,7 @@
 		goto out;
 	}
 
-	if (recv(sv[0], buf, 1, 0) == 1 && *buf == '1')
+	if (proxyrecv(sv[0], buf, 1) == 1 && *buf == '1')
 		ret = 0;
 out:
 	close(sv[0]);
@@ -416,7 +431,7 @@
 		goto out;
 	}
 
-	if (recv(sv[0], buf, 1, 0) == 1 && (*buf == '1' || *buf == '2'))
+	if (proxyrecv(sv[0], buf, 1) == 1 && (*buf == '1' || *buf == '2'))
 		ret = 0;
 	*existed = *buf == '2' ? 1 : -1;
 out:
@@ -470,7 +485,7 @@
 		goto out;
 	}
 
-	if (recv(sv[0], buf, 1, 0) == 1 && *buf == '1')
+	if (proxyrecv(sv[0], buf, 1) == 1 && *buf == '1')
 		ret = 0;
 out:
 	close(sv[0]);
@@ -533,7 +548,7 @@
 		goto out;
 	}
 
-	if (recv(sv[0], buf, 1, 0) == 1 && *buf == '1')
+	if (proxyrecv(sv[0], buf, 1) == 1 && *buf == '1')
 		ret = 0;
 out:
 	close(sv[0]);
@@ -591,7 +606,7 @@
 		goto out;
 	}
 
-	if (recv(sv[0], output, MAXPATHLEN, 0) <= 0) {
+	if (proxyrecv(sv[0], output, MAXPATHLEN) <= 0) {
 		nih_error("%s: Failed reading string from cgmanager: %s",
 			__func__, strerror(errno));
 	} else {
@@ -660,7 +675,7 @@
 		goto out;
 	}
 
-	if (recv(sv[0], buf, 1, 0) == 1 && *buf == '1')
+	if (proxyrecv(sv[0], buf, 1) == 1 && *buf == '1')
 		ret = 0;
 out:
 	close(sv[0]);
@@ -718,7 +733,7 @@
 		goto out;
 	}
 
-	if (recv(sv[0], buf, 1, 0) == 1 && (*buf == '1' || *buf == '2'))
+	if (proxyrecv(sv[0], buf, 1) == 1 && (*buf == '1' || *buf == '2'))
 		ret = 0;
 	*existed = *buf == '2' ? 1 : -1;
 out:
@@ -773,7 +788,7 @@
 		nih_error("%s: error completing dbus request", __func__);
 		goto out;
 	}
-	if (recv(sv[0], &nrpids, sizeof(uint32_t), 0) != sizeof(uint32_t))
+	if (proxyrecv(sv[0], &nrpids, sizeof(uint32_t)) != sizeof(uint32_t))
 		goto out;
 	if (nrpids == -1) {
 		nih_error("%s: bad cgroup: %s:%s", __func__, controller, cgroup);
@@ -852,7 +867,7 @@
 		goto out;
 	}
 
-	if (recv(sv[0], &nrkids, sizeof(int32_t), 0) != sizeof(int32_t))
+	if (proxyrecv(sv[0], &nrkids, sizeof(int32_t)) != sizeof(int32_t))
 		goto out;
 	if (nrkids == 0) {
 		ret = 0;
@@ -863,7 +878,7 @@
 		ret = -1;
 		goto out;
 	}
-	if (recv(sv[0], &len, sizeof(uint32_t), 0) != sizeof(uint32_t))
+	if (proxyrecv(sv[0], &len, sizeof(uint32_t)) != sizeof(uint32_t))
 		goto out;
 
 	paths = nih_alloc(NULL, len);
@@ -932,7 +947,7 @@
 		goto out;
 	}
 
-	if (recv(sv[0], buf, 1, 0) == 1 && (*buf == '1'))
+	if (proxyrecv(sv[0], buf, 1) == 1 && (*buf == '1'))
 		ret = 0;
 out:
 	close(sv[0]);
