From a08b6ac19506160f3fb5925ea025027dce07781d Mon Sep 17 00:00:00 2001 From: Amitay Isaacs Date: Mon, 22 Apr 2013 15:36:27 +1000 Subject: [PATCH 1/1] locking: Add a standalone helper to lock record/db Signed-off-by: Amitay Isaacs --- Makefile.in | 8 +- packaging/RPM/ctdb.spec.in | 1 + server/ctdb_lock_helper.c | 148 +++++++++++++++++++++++++++++++++++++ 3 files changed, 156 insertions(+), 1 deletion(-) create mode 100644 server/ctdb_lock_helper.c diff --git a/Makefile.in b/Makefile.in index 9f94aee7..71c3f318 100755 --- a/Makefile.in +++ b/Makefile.in @@ -107,7 +107,8 @@ TEST_BINS=tests/bin/ctdb_bench tests/bin/ctdb_fetch tests/bin/ctdb_fetch_one \ tests/bin/ctdb_porting_tests \ @INFINIBAND_BINS@ -BINS = bin/ctdb @CTDB_SCSI_IO@ bin/smnotify bin/ping_pong bin/ltdbtool @CTDB_PMDA@ +BINS = bin/ctdb @CTDB_SCSI_IO@ bin/smnotify bin/ping_pong bin/ltdbtool \ + bin/ctdb_lock_helper @CTDB_PMDA@ SBINS = bin/ctdbd @@ -176,6 +177,10 @@ bin/ltdbtool: tools/ltdbtool.o $(TDB_OBJ) @echo Linking $@ @$(CC) $(CFLAGS) -o $@ $+ $(TDB_LIBS) $(LIB_FLAGS) +bin/ctdb_lock_helper: server/ctdb_lock_helper.o lib/util/util_file.o $(TALLOC_OBJ) $(TDB_OBJ) + @echo Linking $@ + @$(CC) $(CFLAGS) -o $@ $+ $(TDB_LIBS) $(LIB_FLAGS) + bin/smnotify: utils/smnotify/gen_xdr.o utils/smnotify/gen_smnotify.o utils/smnotify/smnotify.o $(POPT_OBJ) @echo Linking $@ @$(CC) $(CFLAGS) -o $@ utils/smnotify/smnotify.o utils/smnotify/gen_xdr.o utils/smnotify/gen_smnotify.o $(POPT_OBJ) $(LIB_FLAGS) @@ -327,6 +332,7 @@ install: all manpages $(PMDA_INSTALL) ${INSTALLCMD} -m 755 bin/smnotify $(DESTDIR)$(bindir) $(INSTALLCMD) -m 755 bin/ping_pong $(DESTDIR)$(bindir) $(INSTALLCMD) -m 755 bin/ltdbtool $(DESTDIR)$(bindir) + $(INSTALLCMD) -m 755 bin/ctdb_lock_helper $(DESTDIR)$(bindir) $(INSTALLCMD) -m 755 libctdb/libctdb.a $(DESTDIR)$(libdir) ${INSTALLCMD} -m 644 include/ctdb.h $(DESTDIR)$(includedir) ${INSTALLCMD} -m 644 include/ctdb_client.h $(DESTDIR)$(includedir) diff --git a/packaging/RPM/ctdb.spec.in b/packaging/RPM/ctdb.spec.in index 910b59ac..98724279 100644 --- a/packaging/RPM/ctdb.spec.in +++ b/packaging/RPM/ctdb.spec.in @@ -166,6 +166,7 @@ rm -rf $RPM_BUILD_ROOT %{_sysconfdir}/ctdb/notify.d/README %{_sbindir}/ctdbd %{_bindir}/ctdb +%{_bindir}/ctdb_lock_helper %{_bindir}/smnotify %{_bindir}/ping_pong %{_bindir}/ltdbtool diff --git a/server/ctdb_lock_helper.c b/server/ctdb_lock_helper.c new file mode 100644 index 00000000..d8a1d249 --- /dev/null +++ b/server/ctdb_lock_helper.c @@ -0,0 +1,148 @@ +/* + ctdb lock helper + + Copyright (C) Amitay Isaacs 2013 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see . +*/ + +#include "includes.h" +#include "tdb.h" +#include "system/filesys.h" +#include "../include/ctdb_private.h" + +static char *progname = NULL; + +static void send_result(int fd, char result) +{ + write(fd, &result, 1); + if (result == 1) { + exit(1); + } +} + + +static void usage(void) +{ + fprintf(stderr, "\n"); + fprintf(stderr, "Usage: %s RECORD \n", + progname); + fprintf(stderr, " %s DB [ ...]\n", + progname); +} + + +static int lock_record(const char *dbpath, const char *dbkey) +{ + TDB_DATA key; + struct tdb_context *tdb; + + /* Convert hex key to key */ + if (strcmp(dbkey, "NULL") == 0) { + key.dptr = NULL; + key.dsize = 0; + } else { + key.dptr = hex_decode_talloc(NULL, dbkey, &key.dsize); + } + + tdb = tdb_open(dbpath, 0, TDB_DEFAULT, O_RDWR, 0600); + if (tdb == NULL) { + fprintf(stderr, "%s: Error opening database %s\n", progname, dbpath); + return 1; + } + + if (tdb_chainlock(tdb, key) < 0) { + fprintf(stderr, "%s: Error getting record lock (%s)\n", + progname, tdb_errorstr(tdb)); + return 1; + } + + return 0; + +} + + +static int lock_db(const char *dbpath) +{ + struct tdb_context *tdb; + + tdb = tdb_open(dbpath, 0, TDB_DEFAULT, O_RDWR, 0600); + if (tdb == NULL) { + fprintf(stderr, "%s: Error opening database %s\n", progname, dbpath); + return 1; + } + + if (tdb_lockall(tdb) < 0) { + fprintf(stderr, "%s: Error getting db lock (%s)\n", + progname, tdb_errorstr(tdb)); + return 1; + } + + return 0; +} + + +int main(int argc, char *argv[]) +{ + int write_fd; + char result = 0; + int ppid; + const char *lock_type; + + progname = argv[0]; + + if (argc < 4) { + usage(); + exit(1); + } + + ppid = atoi(argv[1]); + write_fd = atoi(argv[2]); + lock_type = argv[3]; + + if (strcmp(lock_type, "RECORD") == 0) { + if (argc != 6) { + fprintf(stderr, "%s: Invalid number of arguments (%d)\n", + progname, argc); + usage(); + exit(1); + } + result = lock_record(argv[4], argv[5]); + + } else if (strcmp(lock_type, "DB") == 0) { + int n; + + /* If there are no databases specified, no need for lock */ + if (argc > 4) { + for (n=4; n