1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-25 23:21:54 +03:00

libctdb: test: add readrecordlock support

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>


(This used to be ctdb commit 1a23581c70a0c8c3b9c8fd4651ce1b2bb4464f97)
This commit is contained in:
Rusty Russell 2010-06-21 16:06:00 +09:30
parent 0be60b6a7a
commit 505e481588
5 changed files with 231 additions and 0 deletions

View File

@ -20,6 +20,17 @@ struct db {
uint32_t tdb_flags;
};
struct ctdb_db *find_db_by_id(unsigned int id)
{
struct db *db;
for (db = dbs; db; db = db->next) {
if (db->num == id)
return db->db;
}
return NULL;
}
static void attachdb_help(int agc, char **argv)
{
#include "generated-attachdb-help:attachdb"

View File

@ -23,4 +23,6 @@ void check_databases(void);
void *save_databases(void);
void restore_databases(void *);
struct ctdb_db *find_db_by_id(unsigned int id);
#endif /* __HAVE_CTDB_TEST_H */

View File

@ -0,0 +1,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);

View File

@ -0,0 +1,8 @@
connect
# This is just a sanity check
expect attachdb attached: 1
attachdb test.tdb false
# This is just a sanity check
expect readrecordlock lock 1: data ''
readrecordlock 1 testkey
releaselock 1 1

View File

@ -0,0 +1,13 @@
connect
# This is just a sanity check
expect attachdb attached: 1
attachdb test.tdb false
# This is just a sanity check
expect readrecordlock lock 1: data ''
readrecordlock 1 testkey
writerecord 1 1 test-contents
releaselock 1 1
expect readrecordlock lock 2: data 'test-contents'
readrecordlock 1 testkey
releaselock 1 2