File lldpad-0.9.32-fix-race-condition of Package lldpad

commit a8439e6af4483fa97e1a0b69a8486c2f220f935c

From: Eric Multanen <eric.w.multanen@intel.com>

lldpad: init the client interface socket early

    When lldpad is run as a daemon, a dcbtool or lldptool
    command executed immediately afterwards is in a race
    with the daemon lldpad for accessing the client interface
    socket.  The tool will typically fail because the
    client interface is not set up yet.  This patch splits
    the client interface intiailization into two steps,
    1) create the socket, and 2) register the socket.  The
    creation step is done early, before the daemon is
    started, to prevent the race.  The registration of
    the socket (with eloop) is still performed at the
    same place it was before.
---

 ctrl_iface.c         |    8 +++++--
 include/ctrl_iface.h |    1 +
 lldpad.c             |   60 +++++++++++++++++++++++++-------------------------
 3 files changed, 37 insertions(+), 32 deletions(-)

--
Signed-off-by: Eric Multanen <eric.w.multanen@intel.com>

diff --git a/ctrl_iface.c b/ctrl_iface.c
index 19cc282..308c01b 100644
--- a/ctrl_iface.c
+++ b/ctrl_iface.c
@@ -406,6 +406,12 @@ static char *ctrl_iface_path(struct clif_data *clifd)
 }
 
 
+void ctrl_iface_register(struct clif_data *clifd)
+{
+	eloop_register_read_sock(clifd->ctrl_sock, ctrl_iface_receive, clifd,
+				 NULL);
+}
+
 int ctrl_iface_init(struct clif_data *clifd)
 {
 	struct sockaddr_un addr;
@@ -481,8 +487,6 @@ int ctrl_iface_init(struct clif_data *clifd)
 	free(fname);
 
 	clifd->ctrl_sock = s;
-	eloop_register_read_sock(s, ctrl_iface_receive, clifd,
-				 NULL);
 
 	return 0;
 
diff --git a/include/ctrl_iface.h b/include/ctrl_iface.h
index 3947f09..a735933 100644
--- a/include/ctrl_iface.h
+++ b/include/ctrl_iface.h
@@ -48,6 +48,7 @@ struct clif_data {
 };
 
 int ctrl_iface_init(struct clif_data *clifd);
+void ctrl_iface_register(struct clif_data *clifd);
 void ctrl_iface_deinit(struct clif_data *clifd);
 void ctrl_iface_send(struct clif_data *clifd, int level, u32 moduleid,
 				char *buf, size_t len);
diff --git a/lldpad.c b/lldpad.c
index 3098ce1..f09d56f 100644
--- a/lldpad.c
+++ b/lldpad.c
@@ -261,6 +261,35 @@ int main(int argc, char *argv[])
 		exit(1);
 	}
 
+	/* initialize lldpad user data */
+	clifd = malloc(sizeof(struct clif_data));
+	if (clifd == NULL) {
+		fprintf(stderr, "failed to malloc user data\n");
+		log_message(MSG_ERR_SERVICE_START_FAILURE,
+			"%s", "failed to malloc user data");
+		exit(1);
+	}
+
+	clifd->ctrl_interface = (char *) CLIF_IFACE_DIR;
+	strcpy(clifd->iface, CLIF_IFACE_IFNAME);
+	clifd->ctrl_interface_gid_set = 0;
+	clifd->ctrl_interface_gid = 0;
+
+	if (eloop_init(clifd)) {
+		fprintf(stderr, "failed to initialize event loop\n");
+		log_message(MSG_ERR_SERVICE_START_FAILURE,
+			"%s", "failed to initialize event loop");
+		exit(1);
+	}
+
+	/* initialize the client interface socket before daemonize */
+	if (ctrl_iface_init(clifd) < 0) {
+		fprintf(stderr, "failed to register client interface\n");
+		log_message(MSG_ERR_SERVICE_START_FAILURE,
+			"%s", "failed to register client interface");
+		exit(1);
+	}
+
 	if (daemonize && os_daemonize(PID_FILE)) {
 		log_message(MSG_ERR_SERVICE_START_FAILURE,
 			"%s", "error daemonizing lldpad");
@@ -323,28 +352,6 @@ int main(int argc, char *argv[])
 
 	init_modules("");
 
-	/* initialize lldpad user data */
-	clifd = malloc(sizeof(struct clif_data));
-	if (clifd == NULL) {
-		if (!daemonize)
-			fprintf(stderr, "failed to malloc user data\n");
-		log_message(MSG_ERR_SERVICE_START_FAILURE,
-			"%s", "failed to malloc user data");
-		exit(1);
-	}
-
-	clifd->ctrl_interface = (char *) CLIF_IFACE_DIR;
-	strcpy(clifd->iface, CLIF_IFACE_IFNAME);
-	clifd->ctrl_interface_gid_set = 0;
-	clifd->ctrl_interface_gid = 0;
-
-	if (eloop_init(clifd)) {
-		if (!daemonize)
-			fprintf(stderr, "failed to initialize event loop\n");
-		log_message(MSG_ERR_SERVICE_START_FAILURE,
-			"%s", "failed to initialize event loop");
-		exit(1);
-	}
 
 	eloop_register_signal_terminate(eloop_terminate, NULL);
 
@@ -357,14 +364,7 @@ int main(int argc, char *argv[])
 		exit(1);
 	}
 
-	if (ctrl_iface_init(clifd) < 0) {
-		if (!daemonize)
-			fprintf(stderr,
-				"failed to register client interface\n");
-		log_message(MSG_ERR_SERVICE_START_FAILURE,
-			"%s", "failed to register client interface");
-		exit(1);
-	}
+	ctrl_iface_register(clifd);
 
 	/* Find available interfaces, read in the lldpad.conf file and
 	 * add adapters */