Merge branch 'master' of git://git.samba.org/sahlberg/ctdb
[ctdb.git] / libctdb / test / attachdb.c
1 #include "utils.h"
2 #include "log.h"
3 #include "tui.h"
4 #include "ctdb-test.h"
5 #include <ctdb.h>
6 #include <tdb.h>
7 #include <talloc.h>
8 #include <dlinklist.h>
9 #include <errno.h>
10
11 static unsigned int db_num;
12 static struct db *dbs;
13
14 struct db {
15         struct db *next, *prev;
16         struct ctdb_db *db;
17         const char *name;
18         unsigned int num;
19         bool persistent;
20         uint32_t tdb_flags;
21 };
22
23 struct ctdb_db *find_db_by_id(unsigned int id)
24 {
25         struct db *db;
26
27         for (db = dbs; db; db = db->next) {
28                 if (db->num == id)
29                         return db->db;
30         }
31         return NULL;
32 }
33
34 static void attachdb_help(int agc, char **argv)
35 {
36 #include "generated-attachdb-help:attachdb"
37 /*** XML Help:
38     <section id="c:attachdb">
39      <title><command>attachdb</command></title>
40      <para>Attach to a ctdb database</para>
41      <cmdsynopsis>
42       <command>attachdb</command>
43       <arg choice="req"><replaceable>name</replaceable></arg>
44       <arg choice="req"><replaceable>persistent</replaceable></arg>
45       <arg choice="opt"><replaceable>tdb-flags</replaceable></arg>
46      </cmdsynopsis>
47      <para>Attach to the database of the given <replaceable>name</replaceable>.
48         <replaceable>persistent</replaceable> is 'true' or 'false', an
49
50         <replaceable>tdb-flags</replaceable> an optional one or more
51         comma-separated values:</para>
52      <variablelist>
53       <varlistentry>
54        <term>SEQNUM</term>
55        <listitem>
56         <para>Use sequence numbers on the tdb</para>
57        </listitem>
58       </varlistentry>
59      </variablelist>
60
61      <para>It uses a consecutive number for each attached db to
62      identify it for other ctdb-test commands, starting with 1.</para>
63
64      <para>Without any options, the <command>attachdb</command>
65       command lists all databases attached.</para>
66      </section>
67 */
68 }
69
70 static void detachdb_help(int agc, char **argv)
71 {
72 #include "generated-attachdb-help:detachdb"
73 /*** XML Help:
74     <section id="c:detachdb">
75      <title><command>detachdb</command></title>
76      <para>Detach from a ctdb database</para>
77      <cmdsynopsis>
78       <command>detachdb</command>
79       <arg choice="req"><replaceable>number</replaceable></arg>
80      </cmdsynopsis>
81      <para>Detach from the database returned by <command>attachdb</command>.
82      </para>
83      </section>
84 */
85 }
86 static int db_destructor(struct db *db)
87 {
88         ctdb_detachdb(get_ctdb(), db->db);
89         DLIST_REMOVE(dbs, db);
90         return 0;
91 }
92
93 static bool detachdb(int argc, char **argv)
94 {
95         struct db *db;
96
97         if (argc != 2) {
98                 log_line(LOG_ALWAYS, "Need database number");
99                 return false;
100         }
101
102         for (db = dbs; db; db = db->next) {
103                 if (db->num == atoi(argv[1]))
104                         break;
105         }
106         if (!db) {
107                 log_line(LOG_ALWAYS, "Unknown db number %s", argv[1]);
108                 return false;
109         }
110         talloc_free(db);
111         return true;
112 }
113
114 static bool attachdb(int argc, char **argv)
115 {
116         struct db *db;
117
118         if (!get_ctdb()) {
119                 log_line(LOG_ALWAYS, "No ctdb connection");
120                 return false;
121         }
122
123         if (argc == 1) {
124                 log_line(LOG_UI, "Databases currently attached:");
125                 for (db = dbs; db; db = db->next) {
126                         log_line(LOG_ALWAYS, "  %i: %s: %s %u",
127                                  db->num, db->name,
128                                  db->persistent
129                                  ? "persistent" : "not persistent",
130                                  db->tdb_flags);
131                 }
132                 return true;
133         }
134         if (argc != 3 && argc != 4) {
135                 log_line(LOG_ALWAYS, "Need 2 or 3 args");
136                 return false;
137         }
138         db = talloc(working, struct db);
139         db->name = talloc_strdup(db, argv[1]);
140         if (strcasecmp(argv[2], "true") == 0)
141                 db->persistent = true;
142         else if (strcasecmp(argv[2], "false") == 0)
143                 db->persistent = false;
144         else {
145                 log_line(LOG_ALWAYS, "persistent should be true or false");
146                 talloc_free(db);
147                 return false;
148         }
149         db->tdb_flags = 0;
150         if (argc == 4) {
151                 if (strcasecmp(argv[3], "seqnum") == 0)
152                         db->tdb_flags |= TDB_SEQNUM;
153                 else {
154                         log_line(LOG_ALWAYS, "invalid tdb-flags");
155                         talloc_free(db);
156                         return false;
157                 }
158         }
159         db->db = ctdb_attachdb(get_ctdb(), db->name, db->persistent,
160                                db->tdb_flags);
161         if (!db->db) {
162                 log_line(LOG_UI, "ctdb_attachdb: %s", strerror(errno));
163                 return false;
164         }
165         db->num = ++db_num;
166         DLIST_ADD(dbs, db);
167         talloc_set_destructor(db, db_destructor);
168         log_line(LOG_UI, "attached: %u", db->num);
169         return true;
170 }
171
172 static void attachdb_init(void)
173 {
174         tui_register_command("attachdb", attachdb, attachdb_help);
175         tui_register_command("detachdb", detachdb, detachdb_help);
176 }
177 init_call(attachdb_init);