initial shutdown function where a client can request an orderly shutdown of a ctdb...
authorRonnie sahlberg <ronniesahlberg@gmail.com>
Wed, 18 Apr 2007 02:39:03 +0000 (12:39 +1000)
committerRonnie sahlberg <ronniesahlberg@gmail.com>
Wed, 18 Apr 2007 02:39:03 +0000 (12:39 +1000)
1  2 
common/ctdb.c
common/ctdb_client.c
common/ctdb_daemon.c
include/ctdb.h
include/ctdb_private.h
tests/ctdb_test.c

diff --cc common/ctdb.c
index 60e1e6b90b4d20cd75733b8b2e6724d8dcd8e3af,a086fc4cfdf91100caf82e1ff59346bba867552b..de7a36f0c479300d9e684bba2a236d9f9f1f49e1
@@@ -302,21 -306,21 +306,6 @@@ void ctdb_daemon_connect_wait(struct ct
        DEBUG(3,("ctdb_connect_wait: got all %d nodes\n", expected));
  }
  
--/*
--  wait until we're the only node left
--*/
--void ctdb_wait_loop(struct ctdb_context *ctdb)
--{
--      int expected = 0;
--      if (ctdb->flags & CTDB_FLAG_SELF_CONNECT) {
--              expected++;
--      }
--      while (ctdb->num_connected > expected) {
--              event_loop_once(ctdb->ev);
--      }
--}
--
--
  /*
    queue a packet or die
  */
index aca243eda12ec22be02f2cc718fb184476a9f790,4e5e7701cccd29627082005448d4e56a33ad4bb6..29afbae82f2335f6feec38b7ae01b6fdb316d49d
@@@ -92,6 -92,6 +92,20 @@@ void ctdb_reply_fetch_lock(struct ctdb_
        state->state = CTDB_FETCH_LOCK_DONE;
  }
  
++/*
++  called in the client when we receive a CTDB_REPLY_SHUTDOWN from the daemon
++
++  This packet comes in response to a CTDB_REQ_SHUTDOWN request packet. It
++  contains any reply data from the call
++*/
++void ctdb_reply_shutdown(struct ctdb_context *ctdb, struct ctdb_req_header *hdr)
++{
++      printf("daemon:%d has completed shutdown. client will now terminate\n",ctdb_get_vnn(ctdb));
++      talloc_free(ctdb);
++
++      exit(10);
++}
++
  /*
    this is called in the client, when data comes in from the daemon
   */
@@@ -146,6 -146,6 +160,10 @@@ static void ctdb_client_read_cb(uint8_
                ctdb_reply_fetch_lock(ctdb, hdr);
                break;
  
++      case CTDB_REPLY_SHUTDOWN:
++              ctdb_reply_shutdown(ctdb, hdr);
++              break;
++
        default:
                DEBUG(0,("bogus operation code:%d\n",hdr->operation));
        }
@@@ -643,3 -648,3 +666,35 @@@ int ctdb_record_store(struct ctdb_recor
  {
        return ctdb_ltdb_store(h->ctdb_db, h->key, &h->header, data);
  }
++
++/*
++  wait until we're the only node left.
++  this function never returns
++*/
++void ctdb_shutdown(struct ctdb_context *ctdb)
++{
++      struct ctdb_req_shutdown r;
++      int len;
++
++      /* if the domain socket is not yet open, open it */
++      if (ctdb->daemon.sd==-1) {
++              ux_socket_connect(ctdb);
++      }
++
++      len = sizeof(struct ctdb_req_shutdown);
++      ZERO_STRUCT(r);
++      r.hdr.length       = len;
++      r.hdr.ctdb_magic   = CTDB_MAGIC;
++      r.hdr.ctdb_version = CTDB_VERSION;
++      r.hdr.operation    = CTDB_REQ_SHUTDOWN;
++      r.hdr.reqid        = 0;
++
++      ctdb_client_queue_pkt(ctdb, &(req.hdr));
++
++      /* this event loop will terminate once we receive the reply */
++      while (1) {
++              event_loop_once(ctdb->ev);
++      }
++}
++
++
index 03cc1777e612d2ce36bf18f99f685cb91b43d20c,1e85440efd2b0635ff5e5720b86fc7d1c66d6d71..9825786d16a1e53003d300c518e671efe123005a
@@@ -191,6 -191,6 +191,35 @@@ static void daemon_fetch_lock_complete(
        talloc_free(state);
  }
  
++/*
++  called when the daemon gets a shutdown request from a client
++ */
++static void daemon_request_shutdown(struct ctdb_client *client, 
++                                    struct ctdb_req_shutdown *f)
++{
++      struct ctdb_req_finished r;
++      int len;
++      uint32_t node;
++
++      len = sizeof(struct ctdb_req_finished);
++      ZERO_STRUCT(r);
++      r.hdr.length       = len;
++      r.hdr.ctdb_magic   = CTDB_MAGIC;
++      r.hdr.ctdb_version = CTDB_VERSION;
++      r.hdr.operation    = CTDB_REQ_FINISHED;
++      r.hdr.srcnode      = ctdb->vnn;
++      r.hdr.reqid        = 0;
++
++      /* loop over all nodes of the cluster */
++      for (node=0; node<ctdb_num_nodes;node++) {
++              r.hdr.destnode = node;
++              ctdb_queue_packet(ctdb, &r->hdr);
++      }
++
++      /* send a shutdown reply back to the client */
++
++}
++
  /*
    called when the daemon gets a fetch lock request from a client
   */
@@@ -410,6 -410,6 +439,9 @@@ static void daemon_incoming_packet(stru
        case CTDB_REQ_FETCH_LOCK:
                daemon_request_fetch_lock(client, (struct ctdb_req_fetch_lock *)hdr);
                break;
++      case CTDB_REQ_SHUTDOWN:
++              daemon_request_shutdown(client, (struct ctdb_req_shutdown *)hdr);
++              break;
        default:
                DEBUG(0,(__location__ " daemon: unrecognized operation %d\n",
                         hdr->operation));
diff --cc include/ctdb.h
index 9203cdc07461e1d49e0507f2fb857a1d5e6d781f,9203cdc07461e1d49e0507f2fb857a1d5e6d781f..a61b751812331d40e6a3a9c5f4a0a9d9c77d4d6b
@@@ -140,9 -140,9 +140,10 @@@ int ctdb_call(struct ctdb_db_context *c
  void ctdb_connect_wait(struct ctdb_context *ctdb);
  
  /*
--  wait until we're the only node left
++  initiate an ordered ctdb cluster shutdown
++  this function will never return
  */
--void ctdb_wait_loop(struct ctdb_context *ctdb);
++void ctdb_shutdown(struct ctdb_context *ctdb);
  
  /* return vnn of this node */
  uint32_t ctdb_get_vnn(struct ctdb_context *ctdb);
index 6736ee4ab7ca44535e3bf0bd933ceda61fa87ce4,bf6b96e63578b535829be96d54da095a40b1ce47..3180366ff088861538d0a5b3b353707c03cfa86d
@@@ -220,6 -222,6 +222,8 @@@ enum ctdb_operation 
        CTDB_REPLY_CONNECT_WAIT = 1002,
        CTDB_REQ_FETCH_LOCK     = 1003,
        CTDB_REPLY_FETCH_LOCK   = 1004,
++      CTDB_REQ_SHUTDOWN       = 1005,
++      CTDB_REPLY_SHUTDOWN     = 1006,
  };
  
  #define CTDB_MAGIC 0x43544442 /* CTDB */
@@@ -294,6 -296,10 +298,18 @@@ struct ctdb_req_message 
        uint8_t data[1];
  };
  
+ struct ctdb_req_finished {
+       struct ctdb_req_header hdr;
+ };
++struct ctdb_req_shutdown {
++      struct ctdb_req_header hdr;
++};
++
++struct ctdb_reply_shutdown {
++      struct ctdb_req_header hdr;
++};
++
  struct ctdb_req_connect_wait {
        struct ctdb_req_header hdr;
  };
index dea9066eb2083bc0f4e94cf1c18520e187c6e1df,e051305725ff5875cebf062ddb45dae3877af069..dec1ea51005e7c89c9d81e42473ac2d68c131acb
@@@ -169,14 -171,9 +171,7 @@@ int main(int argc, const char *argv[]
        talloc_free(call.reply_data.dptr);
  
        /* go into a wait loop to allow other nodes to complete */
--      ctdb_wait_loop(ctdb);
-       /*talloc_report_full(ctdb, stdout);*/
- /* sleep for a while so that our daemon will remaining alive for the other nodes in the cluster */
- sleep(10);
++      ctdb_shutdown(ctdb);
  
--      /* shut it down */
--      talloc_free(ctdb);
        return 0;
  }