diff options
Diffstat (limited to 'source3')
-rw-r--r-- | source3/include/g_lock.h | 4 | ||||
-rw-r--r-- | source3/lib/g_lock.c | 64 | ||||
-rw-r--r-- | source3/utils/net_g_lock.c | 49 |
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, |