Daemonize before forking in NFS proxy to fix OSD RDMA support (fix #107)
This commit is contained in:
+36
-14
@@ -276,6 +276,19 @@ void nfs_proxy_t::run(json11::Json cfg)
|
|||||||
}
|
}
|
||||||
// Check default pool
|
// Check default pool
|
||||||
check_default_pool();
|
check_default_pool();
|
||||||
|
// Daemonize before initializing messenger and RDMA because otherwise RDMA doesn't survive fork()
|
||||||
|
bool bg = cfg["foreground"].is_null() && cfg["cmd"].is_null();
|
||||||
|
int notifyfd[2] = { -1, -1 };
|
||||||
|
if (bg)
|
||||||
|
{
|
||||||
|
if (socketpair(AF_UNIX, SOCK_STREAM, 0, notifyfd) < 0)
|
||||||
|
{
|
||||||
|
perror("socketpair");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
daemonize_fork(notifyfd);
|
||||||
|
close(notifyfd[0]);
|
||||||
|
}
|
||||||
// Init VitastorFS after starting client because it depends on loaded inode configuration
|
// Init VitastorFS after starting client because it depends on loaded inode configuration
|
||||||
if (fsname != "")
|
if (fsname != "")
|
||||||
{
|
{
|
||||||
@@ -294,6 +307,13 @@ void nfs_proxy_t::run(json11::Json cfg)
|
|||||||
{
|
{
|
||||||
kvfs->upgrade_db([this](int res) { finished = true; });
|
kvfs->upgrade_db([this](int res) { finished = true; });
|
||||||
}
|
}
|
||||||
|
if (bg)
|
||||||
|
{
|
||||||
|
daemonize_reopen_stdio();
|
||||||
|
int ok = 0;
|
||||||
|
(void)write(notifyfd[1], &ok, sizeof(ok));
|
||||||
|
close(notifyfd[1]);
|
||||||
|
}
|
||||||
while (!finished)
|
while (!finished)
|
||||||
{
|
{
|
||||||
ringloop->loop();
|
ringloop->loop();
|
||||||
@@ -409,10 +429,6 @@ void nfs_proxy_t::run_server(json11::Json cfg)
|
|||||||
{
|
{
|
||||||
mount_fs();
|
mount_fs();
|
||||||
}
|
}
|
||||||
if (cfg["foreground"].is_null())
|
|
||||||
{
|
|
||||||
daemonize();
|
|
||||||
}
|
|
||||||
if (pidfile != "")
|
if (pidfile != "")
|
||||||
{
|
{
|
||||||
write_pid();
|
write_pid();
|
||||||
@@ -699,7 +715,8 @@ void nfs_client_t::handle_read(int result)
|
|||||||
return;
|
return;
|
||||||
if (result <= 0 && result != -EAGAIN && result != -EINTR && result != -ECANCELED)
|
if (result <= 0 && result != -EAGAIN && result != -EINTR && result != -ECANCELED)
|
||||||
{
|
{
|
||||||
printf("Failed read from client %d: %d (%s)\n", nfs_fd, result, strerror(-result));
|
if (result != 0)
|
||||||
|
printf("Failed read from client %d: %d (%s)\n", nfs_fd, result, strerror(-result));
|
||||||
stop();
|
stop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1224,26 +1241,31 @@ void nfs_client_t::free_or_rdma(rpc_op_t *rop, void *buf)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void nfs_proxy_t::daemonize()
|
void nfs_proxy_t::daemonize_fork(int *notifyfd)
|
||||||
{
|
{
|
||||||
// Stop all clients because client I/O sometimes breaks during daemonize
|
|
||||||
// I.e. the new process stops receiving events on the old FD
|
|
||||||
// It doesn't happen if we call sleep(1) here, but we don't want to call sleep(1)...
|
|
||||||
for (auto & cli: rpc_clients)
|
|
||||||
cli->stop();
|
|
||||||
if (fork())
|
if (fork())
|
||||||
exit(0);
|
{
|
||||||
|
// Parent - check status
|
||||||
|
close(notifyfd[1]);
|
||||||
|
int child_errno = 1;
|
||||||
|
(void)read(notifyfd[0], &child_errno, sizeof(child_errno));
|
||||||
|
exit(child_errno);
|
||||||
|
}
|
||||||
setsid();
|
setsid();
|
||||||
if (fork())
|
if (fork())
|
||||||
exit(0);
|
exit(0);
|
||||||
if (chdir("/") != 0)
|
}
|
||||||
fprintf(stderr, "Warning: Failed to chdir into /\n");
|
|
||||||
|
void nfs_proxy_t::daemonize_reopen_stdio()
|
||||||
|
{
|
||||||
close(0);
|
close(0);
|
||||||
close(1);
|
close(1);
|
||||||
close(2);
|
close(2);
|
||||||
open("/dev/null", O_RDONLY);
|
open("/dev/null", O_RDONLY);
|
||||||
open(logfile.c_str(), O_WRONLY|O_APPEND|O_CREAT, 0666);
|
open(logfile.c_str(), O_WRONLY|O_APPEND|O_CREAT, 0666);
|
||||||
open(logfile.c_str(), O_WRONLY|O_APPEND|O_CREAT, 0666);
|
open(logfile.c_str(), O_WRONLY|O_APPEND|O_CREAT, 0666);
|
||||||
|
if (chdir("/") != 0)
|
||||||
|
fprintf(stderr, "Warning: Failed to chdir into /\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void nfs_proxy_t::write_pid()
|
void nfs_proxy_t::write_pid()
|
||||||
|
|||||||
+2
-1
@@ -83,7 +83,8 @@ public:
|
|||||||
void check_default_pool();
|
void check_default_pool();
|
||||||
nfs_client_t* create_client();
|
nfs_client_t* create_client();
|
||||||
void do_accept(int listen_fd);
|
void do_accept(int listen_fd);
|
||||||
void daemonize();
|
void daemonize_fork(int *notifyfd);
|
||||||
|
void daemonize_reopen_stdio();
|
||||||
void write_pid();
|
void write_pid();
|
||||||
void mount_fs();
|
void mount_fs();
|
||||||
void check_already_mounted();
|
void check_already_mounted();
|
||||||
|
|||||||
Reference in New Issue
Block a user