]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
merge from ronnie
authorAndrew Tridgell <tridge@samba.org>
Thu, 18 Oct 2007 05:44:02 +0000 (15:44 +1000)
committerAndrew Tridgell <tridge@samba.org>
Thu, 18 Oct 2007 05:44:02 +0000 (15:44 +1000)
(This used to be ctdb commit 75d4b386293e186a6bb8532515585ab72670d663)

1  2 
ctdb/server/ctdb_recover.c

index 85ca2f0dcce227ed020b9413c1ec496d8489e73d,03e1db3f955cf892be1733b198f55978af3cee53..644f0b3c9c5c5d85d9c861e4aea6e205104c65e1
@@@ -422,6 -427,78 +427,78 @@@ static void ctdb_recovered_callback(str
        talloc_free(state);
  }
  
 -      char c;
+ /*
+   called if our set_recmode child times out. this would happen if
+   ctdb_recovery_lock() would block.
+  */
+ static void ctdb_set_recmode_timeout(struct event_context *ev, struct timed_event *te, 
+                                        struct timeval t, void *private_data)
+ {
+       struct ctdb_set_recmode_state *state = talloc_get_type(private_data, 
+                                          struct ctdb_set_recmode_state);
+       ctdb_request_control_reply(state->ctdb, state->c, NULL, -1, "timeout in ctdb_set_recmode");
+       talloc_free(state);
+ }
+ /* when we free the recmode state we must kill any child process.
+ */
+ static int set_recmode_destructor(struct ctdb_set_recmode_state *state)
+ {
+       kill(state->child, SIGKILL);
+       waitpid(state->child, NULL, 0);
+       return 0;
+ }
+ /* this is called when the client process has completed ctdb_recovery_lock()
+    and has written data back to us through the pipe.
+ */
+ static void set_recmode_handler(struct event_context *ev, struct fd_event *fde, 
+                            uint16_t flags, void *private_data)
+ {
+       struct ctdb_set_recmode_state *state= talloc_get_type(private_data, 
+                                            struct ctdb_set_recmode_state);
 -      read(state->fd[0], &c, 1);
 -      if (c != 0) {
++      char c = 0;
+       int ret;
+       /* we got a response from our child process so we can abort the
+          timeout.
+       */
+       talloc_free(state->te);
+       state->te = NULL;
+       /* read the childs status when trying to lock the reclock file.
+          child wrote 0 if everything is fine and 1 if it did manage
+          to lock the file, which would be a problem since that means
+          we got a request to exit from recovery but we could still lock
+          the file   which at this time SHOULD be locked by the recovery
+          daemon on the recmaster
+       */              
++      ret = read(state->fd[0], &c, 1);
++      if (ret != 1 || c != 0) {
+               ctdb_request_control_reply(state->ctdb, state->c, NULL, -1, "managed to lock reclock file from inside daemon");
+               talloc_free(state);
+               return;
+       }
+       ctdb_stop_monitoring(state->ctdb);
+       /* call the events script to tell all subsystems that we have recovered */
+       ret = ctdb_event_script_callback(state->ctdb, 
+                                        timeval_current_ofs(state->ctdb->tunable.script_timeout, 0),
+                                        state, 
+                                        ctdb_recovered_callback, 
+                                        state, "recovered");
+       if (ret != 0) {
+               ctdb_request_control_reply(state->ctdb, state->c, NULL, -1, "failed to run eventscript from set_recmode");
+               talloc_free(state);
+               return;
+       }
+ }
  /*
    set the recovery mode
   */