Skip to content
Snippets Groups Projects
Commit dbadeb8d authored by Georgy Kirichenko's avatar Georgy Kirichenko Committed by Roman Tsisyk
Browse files

Reuse abadoned unix socket. Fixed #1395

parent c77b3536
No related branches found
No related tags found
No related merge requests found
......@@ -194,6 +194,32 @@ evio_service_accept_cb(ev_loop * /* loop */, ev_io *watcher,
}
}
static bool
evio_service_reuse_addr(struct evio_service *service)
{
if ((service->addr.sa_family != AF_UNIX) || (errno != EADDRINUSE))
return false;
int save_errno = errno;
int cl_fd = sio_socket(service->addr.sa_family,
SOCK_STREAM, 0);
if (connect(cl_fd, &service->addr, service->addr_len) == 0)
goto err;
if (errno != ECONNREFUSED)
goto err;
if (unlink(((struct sockaddr_un *)(&service->addr))->sun_path))
goto err;
close(cl_fd);
return true;
err:
errno = save_errno;
close(cl_fd);
return false;
}
/** Try to bind and listen on the configured port.
*
* Throws an exception if error.
......@@ -213,12 +239,18 @@ evio_service_bind_addr(struct evio_service *service)
evio_setsockopt_server(fd, service->addr.sa_family, SOCK_STREAM);
if (sio_bind(fd, &service->addr, service->addr_len) ||
sio_listen(fd)) {
if (sio_bind(fd, &service->addr, service->addr_len)) {
assert(errno == EADDRINUSE);
close(fd);
if (!evio_service_reuse_addr(service) ||
sio_bind(fd, &service->addr, service->addr_len)) {
return -1;
}
}
if (sio_listen(fd)) {
return -1;
}
say_info("%s: bound to %s", evio_service_name(service),
sio_strfaddr(&service->addr, service->addr_len));
......
TAP version 13
1..39
1..40
ok - box is not started
ok - invalid replication_source
ok - invalid wal_mode
......@@ -39,3 +39,4 @@ ok - logger_nonblock default value
ok - logger_nonblock new value
ok - dynamic listen
ok - dynamic listen
ok - reuse unix socket
......@@ -4,7 +4,7 @@ local tap = require('tap')
local test = tap.test('cfg')
local socket = require('socket')
local fio = require('fio')
test:plan(39)
test:plan(40)
--------------------------------------------------------------------------------
-- Invalid values
......@@ -161,7 +161,7 @@ test:is(run_script(code), 0, "logger_nonblock new value")
local path = './tarantool.sock'
os.remove(path)
box.cfg{ listen = 'unix/:'..path }
s = socket.tcp_connect('unix/', path)
local s = socket.tcp_connect('unix/', path)
test:isnt(s, nil, "dynamic listen")
if s then s:close() end
box.cfg{ listen = '' }
......@@ -170,5 +170,17 @@ test:isnil(s, 'dynamic listen')
if s then s:close() end
os.remove(path)
path = './tarantool.sock'
local path2 = './tarantool2.sock'
local s = socket.tcp_server('unix/', path, function () end)
os.execute('ln ' .. path .. ' ' .. path2)
s:close()
box.cfg{ listen = 'unix/:'.. path2}
s = socket.tcp_connect('unix/', path2)
test:isnt(s, nil, "reuse unix socket")
if s then s:close() end
box.cfg{ listen = '' }
os.remove(path2)
test:check()
os.exit(0)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment