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 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197
|
#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>
struct lock {
struct lock *next, *prev;
struct ctdb_db *db;
struct ctdb_lock *lock;
unsigned int id;
};
static unsigned int lock_id;
static struct lock *locks;
static void readrecordlock_help(int argc, char **argv)
{
#include "generated-readrecordlock-help:readrecordlock"
/*** XML Help:
<section id="c:readrecordlock">
<title><command>readrecordlock</command></title>
<para>Read and lock a record in a ctdb database</para>
<cmdsynopsis>
<command>readrecordlock</command>
<arg choice="req"><replaceable>db-id</replaceable></arg>
<arg choice="req"><replaceable>key</replaceable></arg>
</cmdsynopsis>
<para>Read and lock a record. Prints the record, and a 1-based
sequential handle on success, which should be handed to
<command>releaselock</command>
</para>
</section>
*/
}
static void releaselock_help(int argc, char **argv)
{
#include "generated-readrecordlock-help:releaselock"
/*** XML Help:
<section id="c:releaselock">
<title><command>releaselock</command></title>
<para>Unlock a record in a ctdb database</para>
<cmdsynopsis>
<command>releaselock</command>
<arg choice="req"><replaceable>db-id</replaceable></arg>
<arg choice="req"><replaceable>lock-id</replaceable></arg>
</cmdsynopsis>
<para>Unlock a record successfully locked by
<command>readrecordlock</command>. </para>
</section>
*/
}
static void writerecord_help(int argc, char **argv)
{
#include "generated-readrecordlock-help:writerecord"
/*** XML Help:
<section id="c:writerecord">
<title><command>writerecord</command></title>
<para>Write to a locked record in a ctdb database</para>
<cmdsynopsis>
<command>writerecord</command>
<arg choice="req"><replaceable>db-id</replaceable></arg>
<arg choice="req"><replaceable>lock-id</replaceable></arg>
<arg choice="req"><replaceable>data</replaceable></arg>
</cmdsynopsis>
<para>Once a record is locked with
<command>readrecordlock</command>, you can write to it. </para>
</section>
*/
}
static int lock_destructor(struct lock *lock)
{
ctdb_release_lock(lock->db, lock->lock);
DLIST_REMOVE(locks, lock);
return 0;
}
static bool releaselock(int argc, char **argv)
{
struct ctdb_db *db;
struct lock *lock;
if (argc != 3) {
log_line(LOG_ALWAYS, "Need database number and lock number");
return false;
}
db = find_db_by_id(atoi(argv[1]));
if (!db) {
log_line(LOG_ALWAYS, "Unknown db number %s", argv[1]);
return false;
}
for (lock = locks; lock; lock = lock->next) {
if (lock->id == atoi(argv[2]))
break;
}
if (!lock) {
log_line(LOG_ALWAYS, "Unknown lock number %s", argv[2]);
return false;
}
talloc_free(lock);
return true;
}
static bool writerecord(int argc, char **argv)
{
struct ctdb_db *db;
struct lock *lock;
TDB_DATA data;
if (argc != 4) {
log_line(LOG_ALWAYS, "Need db-id, lock-id and data");
return false;
}
db = find_db_by_id(atoi(argv[1]));
if (!db) {
log_line(LOG_ALWAYS, "Unknown db number %s", argv[1]);
return false;
}
for (lock = locks; lock; lock = lock->next) {
if (lock->id == atoi(argv[2]))
break;
}
if (!lock) {
log_line(LOG_ALWAYS, "Unknown lock number %s", argv[2]);
return false;
}
data.dptr = (unsigned char *)argv[3];
data.dsize = strlen(argv[3]);
if (!ctdb_writerecord(db, lock->lock, data)) {
log_line(LOG_UI, "writerecordlock: failed %s", strerror(errno));
return false;
}
return true;
}
static bool readrecordlock(int argc, char **argv)
{
struct lock *lock = talloc(working, struct lock);
TDB_DATA key, data;
if (!get_ctdb()) {
log_line(LOG_ALWAYS, "No ctdb connection");
return false;
}
if (argc != 3) {
log_line(LOG_ALWAYS, "Need db-id and key");
return false;
}
lock->db = find_db_by_id(atoi(argv[1]));
if (!lock->db) {
log_line(LOG_ALWAYS, "Unknown db number %s", argv[1]);
return false;
}
key.dptr = (unsigned char *)argv[2];
key.dsize = strlen(argv[2]);
lock->lock = ctdb_readrecordlock(get_ctdb(), lock->db, key, &data);
if (!lock->lock) {
log_line(LOG_UI, "readrecordlock: failed %s", strerror(errno));
return false;
}
lock->id = ++lock_id;
DLIST_ADD(locks, lock);
talloc_set_destructor(lock, lock_destructor);
log_line(LOG_UI, "lock %u: data '%.*s'",
lock->id, data.dsize, (char *)data.dptr);
return true;
}
static void readrecordlock_init(void)
{
tui_register_command("readrecordlock",
readrecordlock, readrecordlock_help);
tui_register_command("releaselock", releaselock, releaselock_help);
tui_register_command("writerecord", writerecord, writerecord_help);
}
init_call(readrecordlock_init);
|