summaryrefslogtreecommitdiff
path: root/ctdb/libctdb/test/attachdb.c
blob: bb4ce2d0bf226b258d261368eac26405c9da3e0a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#include "utils.h"
#include "log.h"
#include "tui.h"
#include "ctdb-test.h"
#include <ctdb.h>
#include <tdb.h>
#include <talloc.h>
#include <dlinklist.h>
#include <errno.h>

static unsigned int db_num;
static struct db *dbs;

struct db {
	struct db *next, *prev;
	struct ctdb_db *db;
	const char *name;
	unsigned int num;
	bool persistent;
	uint32_t tdb_flags;
};

static void attachdb_help(int agc, char **argv)
{
#include "generated-attachdb-help:attachdb"
/*** XML Help:
    <section id="c:attachdb">
     <title><command>attachdb</command></title>
     <para>Attach to a ctdb database</para>
     <cmdsynopsis>
      <command>attachdb</command>
      <arg choice="req"><replaceable>name</replaceable></arg>
      <arg choice="req"><replaceable>persistent</replaceable></arg>
      <arg choice="opt"><replaceable>tdb-flags</replaceable></arg>
     </cmdsynopsis>
     <para>Attach to the database of the given <replaceable>name</replaceable>.
	<replaceable>persistent</replaceable> is 'true' or 'false', an

	<replaceable>tdb-flags</replaceable> an optional one or more
	comma-separated values:</para>
     <variablelist>
      <varlistentry>
       <term>SEQNUM</term>
       <listitem>
        <para>Use sequence numbers on the tdb</para>
       </listitem>
      </varlistentry>
     </variablelist>

     <para>It uses a consecutive number for each attached db to
     identify it for other ctdb-test commands, starting with 1.</para>

     <para>Without any options, the <command>attachdb</command>
      command lists all databases attached.</para>
     </section>
*/
}

static void detachdb_help(int agc, char **argv)
{
#include "generated-attachdb-help:detachdb"
/*** XML Help:
    <section id="c:detachdb">
     <title><command>detachdb</command></title>
     <para>Detach from a ctdb database</para>
     <cmdsynopsis>
      <command>detachdb</command>
      <arg choice="req"><replaceable>number</replaceable></arg>
     </cmdsynopsis>
     <para>Detach from the database returned by <command>attachdb</command>.
     </para>
     </section>
*/
}
static int db_destructor(struct db *db)
{
	ctdb_detachdb(get_ctdb(), db->db);
	DLIST_REMOVE(dbs, db);
	return 0;
}

static bool detachdb(int argc, char **argv)
{
	struct db *db;

	if (argc != 2) {
		log_line(LOG_ALWAYS, "Need database number");
		return false;
	}

	for (db = dbs; db; db = db->next) {
		if (db->num == atoi(argv[1]))
			break;
	}
	if (!db) {
		log_line(LOG_ALWAYS, "Unknown db number %s", argv[1]);
		return false;
	}
	talloc_free(db);
	return true;
}

static bool attachdb(int argc, char **argv)
{
	struct db *db;

	if (!get_ctdb()) {
		log_line(LOG_ALWAYS, "No ctdb connection");
		return false;
	}

	if (argc == 1) {
		log_line(LOG_UI, "Databases currently attached:");
		for (db = dbs; db; db = db->next) {
			log_line(LOG_ALWAYS, "  %i: %s: %s %u",
				 db->num, db->name,
				 db->persistent
				 ? "persistent" : "not persistent",
				 db->tdb_flags);
		}
		return true;
	}
	if (argc != 3 && argc != 4) {
		log_line(LOG_ALWAYS, "Need 2 or 3 args");
		return false;
	}
	db = talloc(working, struct db);
	db->name = talloc_strdup(db, argv[1]);
	if (strcasecmp(argv[2], "true") == 0)
		db->persistent = true;
	else if (strcasecmp(argv[2], "false") == 0)
		db->persistent = false;
	else {
		log_line(LOG_ALWAYS, "persistent should be true or false");
		talloc_free(db);
		return false;
	}
	db->tdb_flags = 0;
	if (argc == 4) {
		if (strcasecmp(argv[3], "seqnum") == 0)
			db->tdb_flags |= TDB_SEQNUM;
		else {
			log_line(LOG_ALWAYS, "invalid tdb-flags");
			talloc_free(db);
			return false;
		}
	}
	db->db = ctdb_attachdb(get_ctdb(), db->name, db->persistent,
			       db->tdb_flags);
	if (!db->db) {
		log_line(LOG_UI, "ctdb_attachdb: %s", strerror(errno));
		return false;
	}
	db->num = ++db_num;
	DLIST_ADD(dbs, db);
	talloc_set_destructor(db, db_destructor);
	log_line(LOG_UI, "attached: %u", db->num);
	return true;
}

static void attachdb_init(void)
{
	tui_register_command("attachdb", attachdb, attachdb_help);
	tui_register_command("detachdb", detachdb, detachdb_help);
}
init_call(attachdb_init);