return 0;
}
+
+/* when forking the main daemon and the child process needs to connect back
+ * to the daemon as a client process, this function can be used to change
+ * the ctdb context from daemon into client mode
+ */
+int switch_from_server_to_client(struct ctdb_context *ctdb)
+{
+ int ret;
+
+ /* shutdown the transport */
+ if (ctdb->methods) {
+ ctdb->methods->shutdown(ctdb);
+ }
+
+ /* get a new event context */
+ talloc_free(ctdb->ev);
+ ctdb->ev = event_context_init(ctdb);
+
+ close(ctdb->daemon.sd);
+ ctdb->daemon.sd = -1;
+
+ /* the client does not need to be realtime */
+ if (ctdb->do_setsched) {
+ ctdb_restore_scheduler(ctdb);
+ }
+
+ /* initialise ctdb */
+ ret = ctdb_socket_connect(ctdb);
+ if (ret != 0) {
+ DEBUG(DEBUG_ALERT, (__location__ " Failed to init ctdb client\n"));
+ return -1;
+ }
+
+ return 0;
+}
+
*/
int ctdb_start_recoverd(struct ctdb_context *ctdb)
{
- int ret;
int fd[2];
struct signal_event *se;
close(fd[1]);
- /* shutdown the transport */
- if (ctdb->methods) {
- ctdb->methods->shutdown(ctdb);
- }
-
- /* get a new event context */
- talloc_free(ctdb->ev);
- ctdb->ev = event_context_init(ctdb);
-
- event_add_fd(ctdb->ev, ctdb, fd[0], EVENT_FD_READ|EVENT_FD_AUTOCLOSE,
- ctdb_recoverd_parent, &fd[0]);
-
- close(ctdb->daemon.sd);
- ctdb->daemon.sd = -1;
-
srandom(getpid() ^ time(NULL));
- /* the recovery daemon does not need to be realtime */
- if (ctdb->do_setsched) {
- ctdb_restore_scheduler(ctdb);
- }
-
- /* initialise ctdb */
- ret = ctdb_socket_connect(ctdb);
- if (ret != 0) {
- DEBUG(DEBUG_ALERT, (__location__ " Failed to init ctdb\n"));
+ if (switch_from_server_to_client(ctdb) != 0) {
+ DEBUG(DEBUG_CRIT, (__location__ "ERROR: failed to switch recovery daemon into client mode. shutting down.\n"));
exit(1);
}
+ event_add_fd(ctdb->ev, ctdb, fd[0], EVENT_FD_READ|EVENT_FD_AUTOCLOSE,
+ ctdb_recoverd_parent, &fd[0]);
+
/* set up a handler to pick up sigchld */
se = event_add_signal(ctdb->ev, ctdb,
SIGCHLD, 0,