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 */