locking: Create commandline arguments for locking helper
authorAmitay Isaacs <amitay@gmail.com>
Tue, 30 Apr 2013 04:32:46 +0000 (14:32 +1000)
committerAmitay Isaacs <amitay@gmail.com>
Thu, 23 May 2013 23:06:39 +0000 (09:06 +1000)
Signed-off-by: Amitay Isaacs <amitay@gmail.com>
server/ctdb_lock.c

index db38e0d7c13089bf97ed3b6c74fa62ddac536177..8e2f40dd4e0c053511800f37b8fc0418e49c3880 100644 (file)
@@ -685,6 +685,121 @@ static char *lock_child_log_prefix(struct lock_context *lock_ctx)
 }
 
 
+static int db_count_handler(struct ctdb_db_context *ctdb_db, uint32_t priority,
+                           void *private_data)
+{
+       int *count = (int *)private_data;
+
+       (*count)++;
+
+       return 0;
+}
+
+struct db_namelist {
+       char **names;
+       int n;
+};
+
+static int db_name_handler(struct ctdb_db_context *ctdb_db, uint32_t priority,
+                          void *private_data)
+{
+       struct db_namelist *list = (struct db_namelist *)private_data;
+
+       list->names[list->n] = talloc_strdup(list->names, ctdb_db->db_path);
+       list->n++;
+
+       return 0;
+}
+
+static char **lock_helper_args(TALLOC_CTX *mem_ctx, struct lock_context *lock_ctx, int fd)
+{
+       struct ctdb_context *ctdb = lock_ctx->ctdb;
+       char **args = NULL;
+       int nargs, i;
+       int priority;
+       struct db_namelist list;
+
+       switch (lock_ctx->type) {
+       case LOCK_RECORD:
+               nargs = 6;
+               break;
+
+       case LOCK_DB:
+               nargs = 5;
+               break;
+
+       case LOCK_ALLDB_PRIO:
+               nargs = 4;
+               ctdb_db_iterator(ctdb, lock_ctx->priority, db_count_handler, &nargs);
+               break;
+
+       case LOCK_ALLDB:
+               nargs = 4;
+               for (priority=1; priority<NUM_DB_PRIORITIES; priority++) {
+                       ctdb_db_iterator(ctdb, priority, db_count_handler, &nargs);
+               }
+               break;
+       }
+
+       /* Add extra argument for null termination */
+       nargs++;
+
+       args = talloc_array(mem_ctx, char *, nargs);
+       if (args == NULL) {
+               return NULL;
+       }
+
+       args[0] = talloc_strdup(args, "ctdb_lock_helper");
+       args[1] = talloc_asprintf(args, "%d", getpid());
+       args[2] = talloc_asprintf(args, "%d", fd);
+
+       switch (lock_ctx->type) {
+       case LOCK_RECORD:
+               args[3] = talloc_strdup(args, "RECORD");
+               args[4] = talloc_strdup(args, lock_ctx->ctdb_db->db_path);
+               if (lock_ctx->key.dsize == 0) {
+                       args[5] = talloc_strdup(args, "NULL");
+               } else {
+                       args[5] = hex_encode_talloc(args, lock_ctx->key.dptr, lock_ctx->key.dsize);
+               }
+               break;
+
+       case LOCK_DB:
+               args[3] = talloc_strdup(args, "DB");
+               args[4] = talloc_strdup(args, lock_ctx->ctdb_db->db_path);
+               break;
+
+       case LOCK_ALLDB_PRIO:
+               args[3] = talloc_strdup(args, "DB");
+               list.names = args;
+               list.n = 4;
+               ctdb_db_iterator(ctdb, lock_ctx->priority, db_name_handler, &list);
+               break;
+
+       case LOCK_ALLDB:
+               args[3] = talloc_strdup(args, "DB");
+               list.names = args;
+               list.n = 4;
+               for (priority=1; priority<NUM_DB_PRIORITIES; priority++) {
+                       ctdb_db_iterator(ctdb, priority, db_name_handler, &list);
+               }
+               break;
+       }
+
+       /* Make sure last argument is NULL */
+       args[nargs-1] = NULL;
+
+       for (i=0; i<nargs-1; i++) {
+               if (args[i] == NULL) {
+                       talloc_free(args);
+                       return NULL;
+               }
+       }
+
+       return args;
+}
+
+
 /*
  * Schedule a new lock child process
  * Set up callback handler and timeout handler