summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2010-03-12 14:22:54 +0100
committerVolker Lendecke <vl@samba.org>2010-03-12 14:23:25 +0100
commit79100c242153ea174a4405afd45cbf635da313aa (patch)
treea48e26f1a73fb0ff1ebb592ac7b8c405004e2620
parent1728b5fa6f0efd443799550ab630abd8282a3c9c (diff)
downloadsamba-79100c242153ea174a4405afd45cbf635da313aa.tar.gz
samba-79100c242153ea174a4405afd45cbf635da313aa.tar.bz2
samba-79100c242153ea174a4405afd45cbf635da313aa.zip
s3: Add "g_lock_do" as a convenience wrapper function
-rw-r--r--source3/include/g_lock.h4
-rw-r--r--source3/lib/g_lock.c64
-rw-r--r--source3/utils/net_g_lock.c49
3 files changed, 90 insertions, 27 deletions
diff --git a/source3/include/g_lock.h b/source3/include/g_lock.h
index 13daf3f556..becb71bb67 100644
--- a/source3/include/g_lock.h
+++ b/source3/include/g_lock.h
@@ -43,6 +43,10 @@ NTSTATUS g_lock_unlock(struct g_lock_ctx *ctx, const char *name);
NTSTATUS g_lock_get(struct g_lock_ctx *ctx, const char *name,
struct server_id *pid);
+NTSTATUS g_lock_do(const char *name, enum g_lock_type lock_type,
+ struct timeval timeout,
+ void (*fn)(void *private_data), void *private_data);
+
int g_lock_locks(struct g_lock_ctx *ctx,
int (*fn)(const char *name, void *private_data),
void *private_data);
diff --git a/source3/lib/g_lock.c b/source3/lib/g_lock.c
index e4c6d7c660..1726047886 100644
--- a/source3/lib/g_lock.c
+++ b/source3/lib/g_lock.c
@@ -700,3 +700,67 @@ NTSTATUS g_lock_get(struct g_lock_ctx *ctx, const char *name,
}
return NT_STATUS_OK;
}
+
+static bool g_lock_init_all(TALLOC_CTX *mem_ctx,
+ struct tevent_context **pev,
+ struct messaging_context **pmsg,
+ struct g_lock_ctx **pg_ctx)
+{
+ struct tevent_context *ev = NULL;
+ struct messaging_context *msg = NULL;
+ struct g_lock_ctx *g_ctx = NULL;
+
+ ev = tevent_context_init(mem_ctx);
+ if (ev == NULL) {
+ d_fprintf(stderr, "ERROR: could not init event context\n");
+ goto fail;
+ }
+ msg = messaging_init(mem_ctx, procid_self(), ev);
+ if (msg == NULL) {
+ d_fprintf(stderr, "ERROR: could not init messaging context\n");
+ goto fail;
+ }
+ g_ctx = g_lock_ctx_init(mem_ctx, msg);
+ if (g_ctx == NULL) {
+ d_fprintf(stderr, "ERROR: could not init g_lock context\n");
+ goto fail;
+ }
+
+ *pev = ev;
+ *pmsg = msg;
+ *pg_ctx = g_ctx;
+ return true;
+fail:
+ TALLOC_FREE(g_ctx);
+ TALLOC_FREE(msg);
+ TALLOC_FREE(ev);
+ return false;
+}
+
+NTSTATUS g_lock_do(const char *name, enum g_lock_type lock_type,
+ struct timeval timeout,
+ void (*fn)(void *private_data), void *private_data)
+{
+ struct tevent_context *ev = NULL;
+ struct messaging_context *msg = NULL;
+ struct g_lock_ctx *g_ctx = NULL;
+ NTSTATUS status;
+
+ if (!g_lock_init_all(talloc_tos(), &ev, &msg, &g_ctx)) {
+ status = NT_STATUS_ACCESS_DENIED;
+ goto done;
+ }
+
+ status = g_lock_lock(g_ctx, name, lock_type, timeout);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+ fn(private_data);
+ g_lock_unlock(g_ctx, name);
+
+done:
+ TALLOC_FREE(g_ctx);
+ TALLOC_FREE(msg);
+ TALLOC_FREE(ev);
+ return status;
+}
diff --git a/source3/utils/net_g_lock.c b/source3/utils/net_g_lock.c
index 54cb2d439e..a683b552de 100644
--- a/source3/utils/net_g_lock.c
+++ b/source3/utils/net_g_lock.c
@@ -57,17 +57,24 @@ fail:
return false;
}
+struct net_g_lock_do_state {
+ const char *cmd;
+ int result;
+};
+
+static void net_g_lock_do_fn(void *private_data)
+{
+ struct net_g_lock_do_state *state =
+ (struct net_g_lock_do_state *)private_data;
+ state->result = system(state->cmd);
+}
static int net_g_lock_do(struct net_context *c, int argc, const char **argv)
{
- struct tevent_context *ev = NULL;
- struct messaging_context *msg = NULL;
- struct g_lock_ctx *g_ctx = NULL;
+ struct net_g_lock_do_state state;
const char *name, *cmd;
- int timeout, res;
- bool locked = false;
+ int timeout;
NTSTATUS status;
- int ret = -1;
if (argc != 3) {
d_printf("Usage: net g_lock do <lockname> <timeout> "
@@ -78,38 +85,26 @@ static int net_g_lock_do(struct net_context *c, int argc, const char **argv)
timeout = atoi(argv[1]);
cmd = argv[2];
- if (!net_g_lock_init(talloc_tos(), &ev, &msg, &g_ctx)) {
- goto done;
- }
+ state.cmd = cmd;
+ state.result = -1;
- status = g_lock_lock(g_ctx, name, G_LOCK_WRITE,
- timeval_set(timeout / 1000, timeout % 1000));
+ status = g_lock_do(name, G_LOCK_WRITE,
+ timeval_set(timeout / 1000, timeout % 1000),
+ net_g_lock_do_fn, &state);
if (!NT_STATUS_IS_OK(status)) {
- d_fprintf(stderr, "ERROR: Could not get lock: %s\n",
+ d_fprintf(stderr, "ERROR: g_lock_do failed: %s\n",
nt_errstr(status));
goto done;
}
- locked = true;
-
- res = system(cmd);
-
- if (res == -1) {
+ if (state.result == -1) {
d_fprintf(stderr, "ERROR: system() returned %s\n",
strerror(errno));
goto done;
}
- d_fprintf(stderr, "command returned %d\n", res);
-
- ret = 0;
+ d_fprintf(stderr, "command returned %d\n", state.result);
done:
- if (locked) {
- g_lock_unlock(g_ctx, name);
- }
- TALLOC_FREE(g_ctx);
- TALLOC_FREE(msg);
- TALLOC_FREE(ev);
- return ret;
+ return state.result;
}
static int net_g_lock_dump_fn(struct server_id pid, enum g_lock_type lock_type,