mirror of
https://github.com/samba-team/samba.git
synced 2025-01-11 05:18:09 +03:00
s3: Add "g_lock_do" as a convenience wrapper function
This commit is contained in:
parent
1728b5fa6f
commit
79100c2421
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user