cfuse: daemonize by default

We have to fork, then start client, to avoid killing our pthreads.  Use
a socketpair to tell the parent process about mount success/failure.
This commit is contained in:
Sage Weil 2010-07-01 11:15:39 -07:00
parent a7d4987f3a
commit bbbf24068f
3 changed files with 101 additions and 36 deletions

View File

@ -46,6 +46,7 @@ int main(int argc, const char **argv, const char *envp[]) {
env_to_vec(args);
common_set_defaults(false);
g_conf.daemonize = true;
common_init(args, "cfuse", true);
// args for fuse
@ -71,44 +72,86 @@ int main(int argc, const char **argv, const char *envp[]) {
// start up network
SimpleMessenger *messenger = new SimpleMessenger();
cout << "mounting ceph" << std::endl;
messenger->register_entity(entity_name_t::CLIENT());
Client *client = new Client(messenger, &mc);
messenger->start();
// we need to handle the forking ourselves.
bool daemonize = g_conf.daemonize;
g_conf.daemonize = false;
int r;
int fd[2] = {0, 0}; // parent's, child's
pid_t childpid = 0;
if (daemonize) {
int r = socketpair(AF_UNIX, SOCK_STREAM, 0, fd);
if (r < 0) {
cerr << "cfuse[" << getpid() << "]: unable to create socketpair: " << strerror(errno) << std::endl;
exit(1);
}
// start client
client->init();
childpid = fork();
}
if (childpid == 0) {
//cout << "child, mounting" << std::endl;
::close(fd[0]);
cout << "cfuse[" << getpid() << "]: starting ceph client" << std::endl;
messenger->start();
// start client
client->init();
// start up fuse
// use my argc, argv (make sure you pass a mount point!)
r = client->mount();
if (r < 0)
goto out_shutdown;
// start up fuse
// use my argc, argv (make sure you pass a mount point!)
int r = client->mount();
if (r < 0) {
cerr << "cfuse[" << getpid() << "]: ceph mount failed with " << strerror(-r) << std::endl;
goto out_shutdown;
}
dout_create_rank_symlink(client->get_nodeid().v);
cerr << "cfuse[" << getpid() << "]: starting fuse" << std::endl;
if (g_conf.fuse_ll)
r = ceph_fuse_ll_main(client, argc, argv, fd[1]);
else
r = ceph_fuse_main(client, argc, argv);
cerr << "cfuse[" << getpid() << "]: fuse finished with error " << r << std::endl;
client->unmount();
//cout << "unmounted" << std::endl;
out_shutdown:
client->shutdown();
delete client;
// wait for messenger to finish
messenger->wait();
dout_create_rank_symlink(client->get_nodeid().v);
cout << "starting fuse" << std::endl;
if (daemonize) {
//cout << "child signalling parent with " << r << std::endl;
::write(fd[1], &r, sizeof(r));
}
//cerr << "starting fuse on pid " << getpid() << std::endl;
if (g_conf.fuse_ll)
ceph_fuse_ll_main(client, argc, argv);
else
ceph_fuse_main(client, argc, argv);
//cerr << "fuse finished on pid " << getpid() << std::endl;
//cout << "child done" << std::endl;
return r;
} else {
// i am the parent
//cout << "parent, waiting for signal" << std::endl;
::close(fd[1]);
cout << "fuse finished, unmounting ceph" << std::endl;
client->unmount();
cout << "unmounted" << std::endl;
out_shutdown:
client->shutdown();
delete client;
// wait for messenger to finish
messenger->wait();
return r;
int r = -1;
::read(fd[0], &r, sizeof(r));
if (r == 0) {
// close stdout, etc.
//cout << "success" << std::endl;
::close(0);
::close(1);
::close(2);
} else {
cerr << "cfuse[" << getpid() << "]: mount failed: " << strerror(-r) << std::endl;
}
return r;
}
}

View File

@ -422,8 +422,25 @@ static void ceph_ll_statfs(fuse_req_t req, fuse_ino_t ino)
fuse_reply_err(req, -r);
}
int fd_on_success = 0;
static void do_init(void *foo, fuse_conn_info *bar)
{
if (fd_on_success) {
//cout << "fuse init signaling on fd " << fd_on_success << std::endl;
int r = 0;
::write(fd_on_success, &r, sizeof(r));
//cout << "fuse init done signaling on fd " << fd_on_success << std::endl;
// close stdout, etc.
::close(0);
::close(1);
::close(2);
}
}
static struct fuse_lowlevel_ops ceph_ll_oper = {
init: 0,
init: do_init,
destroy: 0,
lookup: ceph_ll_lookup,
forget: ceph_ll_forget,
@ -459,9 +476,11 @@ static struct fuse_lowlevel_ops ceph_ll_oper = {
bmap: 0
};
int ceph_fuse_ll_main(Client *c, int argc, const char *argv[])
int ceph_fuse_ll_main(Client *c, int argc, const char *argv[], int fd)
{
cout << "ceph_fuse_ll_main starting fuse on pid " << getpid() << std::endl;
//cout << "ceph_fuse_ll_main starting fuse on pid " << getpid() << std::endl;
fd_on_success = fd;
client = c;
@ -507,10 +526,13 @@ int ceph_fuse_ll_main(Client *c, int argc, const char *argv[])
fuse_session_destroy(se);
}
fuse_unmount(mountpoint, ch);
err = 0;
} else {
err = -errno;
}
fuse_opt_free_args(&args);
cout << "ceph_fuse_ll_main done, err=" << err << std::endl;
return err ? 1 : 0;
//cout << "ceph_fuse_ll_main done, err=" << err << std::endl;
return err;
}

View File

@ -12,4 +12,4 @@
*
*/
int ceph_fuse_ll_main(Client *c, int argc, const char *argv[]);
int ceph_fuse_ll_main(Client *c, int argc, const char *argv[], int fd_on_success);