]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
ceph-fuse: rewrite the fork hackery using Prefork 12358/head
authorKefu Chai <kchai@redhat.com>
Wed, 7 Dec 2016 06:29:58 +0000 (14:29 +0800)
committerKefu Chai <kchai@redhat.com>
Thu, 8 Dec 2016 02:26:06 +0000 (10:26 +0800)
in this change we use global_init_postfork_start() to restart the
log after it is stopped by Preforker.

* ceph_fuse.c:
   - rewrite the fork hackery using Preforker helper class
   - write "starting ceph client" message to cerr, as the cout was
     closed
     by global_init_postfork_start()
* fuse_ll.cc: write -1 to signal the parent process that init is
  done.
* Preforker.h: add a helper method to return the fd to which, the
  child process can write an int to notify its status.

Signed-off-by: Kefu Chai <kchai@redhat.com>
src/ceph_fuse.cc
src/client/fuse_ll.cc
src/common/Preforker.h

index d6983d932e9613c8a7dd40153b382bc8a71aba1f..06a1e4150040f8fbacb6e204b4821c4cafb842f9 100644 (file)
@@ -35,6 +35,7 @@ using namespace std;
 #endif
 #include "global/global_init.h"
 #include "global/signal_handler.h"
+#include "common/Preforker.h"
 #include "common/safe_io.h"
        
 #include <sys/types.h>
@@ -111,33 +112,31 @@ int main(int argc, const char **argv, const char *envp[]) {
     cerr << std::endl;
   }
 
-  // we need to handle the forking ourselves.
-  int fd[2] = {0, 0};  // parent's, child's
-  pid_t childpid = 0;
-  int tester_r = 0;
-  void *tester_rp = NULL;
-  bool restart_log = false;
+  global_init_prefork(g_ceph_context);
+  Preforker forker;
   if (g_conf->daemonize) {
-    int r = socketpair(AF_UNIX, SOCK_STREAM, 0, fd);
-    if (r < 0) {
-      cerr << "ceph-fuse[" << getpid() << "]: unable to create socketpair: " << cpp_strerror(errno) << std::endl;
-      exit(1);
+    string err;
+    if (forker.prefork(err)) {
+      cerr << "ceph-fuse[" << err << std::endl;
+      return 1;
     }
+    global_init_postfork_start(cct.get());
+  }
 
-    g_ceph_context->_log->stop();
-    restart_log = true;
 
-    childpid = fork();
+  if (forker.is_parent()) {
+    string err;
+    int r = forker.parent_wait(err);
+    if (r) {
+      cerr << "ceph-fuse" << err << std::endl;
+    }
+    return r;
   }
 
-  if (childpid == 0) {
-    if (restart_log)
-      g_ceph_context->_log->start();
+  if (forker.is_child()) {
     common_init_finish(g_ceph_context);
 
     //cout << "child, mounting" << std::endl;
-    ::close(fd[0]);
-
     class RemountTest : public Thread {
     public:
       CephFuse *cfuse;
@@ -191,6 +190,8 @@ int main(int argc, const char **argv, const char *envp[]) {
     Client *client;
     CephFuse *cfuse;
     UserPerm perms;
+    int tester_r = 0;
+    void *tester_rp = NULL;
 
     MonClient *mc = new MonClient(g_ceph_context);
     int r = mc->build_initial_monmap();
@@ -210,7 +211,7 @@ int main(int argc, const char **argv, const char *envp[]) {
       client->set_filer_flags(filer_flags);
     }
 
-    cfuse = new CephFuse(client, fd[1]);
+    cfuse = new CephFuse(client, forker.get_signal_fd());
 
     r = cfuse->init(newargc, newargv);
     if (r != 0) {
@@ -218,7 +219,7 @@ int main(int argc, const char **argv, const char *envp[]) {
       goto out_messenger_start_failed;
     }
 
-    cout << "ceph-fuse[" << getpid() << "]: starting ceph client" << std::endl;
+    cerr << "ceph-fuse[" << getpid() << "]: starting ceph client" << std::endl;
     r = messenger->start();
     if (r < 0) {
       cerr << "ceph-fuse[" << getpid() << "]: ceph messenger failed with " << cpp_strerror(-r) << std::endl;
@@ -281,40 +282,10 @@ int main(int argc, const char **argv, const char *envp[]) {
     delete client;
     delete messenger;
   out_mc_start_failed:
-    
-    if (g_conf->daemonize) {
-      //cout << "child signalling parent with " << r << std::endl;
-      static int foo = 0;
-      foo += ::write(fd[1], &r, sizeof(r));
-    }
-    
     free(newargv);
-    
     delete mc;
-    
     //cout << "child done" << std::endl;
-    return r;
-  } else {
-    if (restart_log)
-      g_ceph_context->_log->start();
-    // i am the parent
-    //cout << "parent, waiting for signal" << std::endl;
-    ::close(fd[1]);
-
-    int r = -1;
-    int err = safe_read_exact(fd[0], &r, sizeof(r));
-    if (err == 0 && r == 0) {
-      // close stdout, etc.
-      //cout << "success" << std::endl;
-      ::close(0);
-      ::close(1);
-      ::close(2);
-    } else if (err) {
-      cerr << "ceph-fuse[" << getpid() << "]: mount failed: " << cpp_strerror(-err) << std::endl;
-    } else {
-      cerr << "ceph-fuse[" << getpid() << "]: mount failed: " << cpp_strerror(-r) << std::endl;
-    }
-    return r;
+    return forker.signal_exit(r);
   }
 }
 
index f59b53c6cb87da606481c898d5d8321517ab8a54..a0b9e06388deec605e400186456fbda55fcb8034 100644 (file)
@@ -931,7 +931,9 @@ static void do_init(void *data, fuse_conn_info *conn)
 
   if (cfuse->fd_on_success) {
     //cout << "fuse init signaling on fd " << fd_on_success << std::endl;
-    uint32_t r = 0;
+    // see Preforker::daemonize(), ceph-fuse's parent process expects a `-1`
+    // from a daemonized child process.
+    uint32_t r = -1;
     int err = safe_write(cfuse->fd_on_success, &r, sizeof(r));
     if (err) {
       derr << "fuse_ll: do_init: safe_write failed with error "
index cc8ed46bc7a13538db14fbe39051742ce28167c0..d3bbe48363a7503f0e8215e45a59fa8900e24b8c 100644 (file)
@@ -64,6 +64,10 @@ public:
     return 0;
   }
 
+  int get_signal_fd() const {
+    return forked ? fd[1] : 0;
+  }
+
   bool is_child() {
     return childpid == 0;
   }