Skip to content

Commit b1cc105

Browse files
committed
main: improve api socket bind
If the grout process is launched a second time, then socket api bind() failed and the process unlink socket file before exiting, making the first running process unreachable. If the grout process crash, it won't remove api socket file, and the next invocation will fail at socket api bind(). Change api_socket_start() to check, if bind() fails, whether there's a listening process behind the scene: * If there is, exit without removing socket api file * If there is not, then remove file and resume bind. Signed-off-by: Olivier Gournet <[email protected]>
1 parent 6a43d4c commit b1cc105

File tree

2 files changed

+21
-2
lines changed

2 files changed

+21
-2
lines changed

Diff for: main/api.c

+19-1
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ int api_socket_start(struct event_base *base) {
206206
struct sockaddr_un un;
207207
struct sockaddr a;
208208
} addr;
209+
int ret;
209210
int fd;
210211

211212
fd = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0);
@@ -215,7 +216,24 @@ int api_socket_start(struct event_base *base) {
215216
addr.un.sun_family = AF_UNIX;
216217
memccpy(addr.un.sun_path, path, 0, sizeof(addr.un.sun_path) - 1);
217218

218-
if (bind(fd, &addr.a, sizeof(addr.un)) < 0) {
219+
ret = bind(fd, &addr.a, sizeof(addr.un));
220+
if (ret < 0 && errno == EADDRINUSE) {
221+
// unix socket file exists, check if there is a process
222+
// listening on the other side.
223+
ret = connect(fd, &addr.a, sizeof(addr.un));
224+
if (ret == 0) {
225+
LOG(ERR, "grout already running on API socket %s, exiting", path);
226+
close(fd);
227+
return errno_set(EADDRINUSE);
228+
}
229+
if (ret < 0 && errno != ECONNREFUSED)
230+
return errno_log(errno, "connect");
231+
// remove socket file, and try to bind again
232+
if (unlink(addr.un.sun_path) < 0)
233+
return errno_log(errno, "unlink");
234+
ret = bind(fd, &addr.a, sizeof(addr.un));
235+
}
236+
if (ret < 0) {
219237
close(fd);
220238
return errno_log(errno, "bind");
221239
}

Diff for: main/main.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,8 @@ int main(int argc, char **argv) {
211211
modules_fini(ev_base);
212212
event_base_free(ev_base);
213213
}
214-
unlink(args.api_sock_path);
214+
if (err != EADDRINUSE)
215+
unlink(args.api_sock_path);
215216
libevent_global_shutdown();
216217
dpdk_stop:
217218
dpdk_fini();

0 commit comments

Comments
 (0)