+++ /dev/null
-/*
- Unix SMB/CIFS implementation.
- Samba internal messaging functions
- Copyright (C) 2007 by Volker Lendecke
-
- 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 <http://www.gnu.org/licenses/>.
-*/
-
-#include "includes.h"
-#include "lib/messages_ctdbd.h"
-#include "lib/util/server_id.h"
-#include "messages.h"
-#include "util_tdb.h"
-#include "lib/util/iov_buf.h"
-#include "lib/messages_util.h"
-#include "ctdbd_conn.h"
-#include "lib/cluster_support.h"
-
-struct messaging_ctdbd_context;
-
-struct messaging_ctdbd_fde_ev {
- struct messaging_ctdbd_fde_ev *prev, *next;
-
- /*
- * Backreference to enable DLIST_REMOVE from our
- * destructor. Also, set to NULL when the dgm_context dies
- * before the messaging_dgm_fde_ev.
- */
- struct messaging_ctdbd_context *ctx;
-
- struct tevent_context *ev;
- struct tevent_fd *fde;
-};
-
-struct messaging_ctdbd_context {
- struct ctdbd_connection *conn;
-
- struct messaging_ctdbd_fde_ev *fde_evs;
-
- void (*recv_cb)(struct tevent_context *ev,
- const uint8_t *msg, size_t msg_len,
- int *fds, size_t num_fds,
- void *private_data);
- void *private_data;
-};
-
-/*
- * This is a Samba3 hack/optimization. Routines like process_exists need to
- * talk to ctdbd, and they don't get handed a messaging context.
- */
-static struct ctdbd_connection *global_ctdbd_connection;
-static int global_ctdb_connection_pid;
-
-struct ctdbd_connection *messaging_ctdbd_connection(void)
-{
- if (!lp_clustering()) {
- return NULL;
- }
-
- if (global_ctdb_connection_pid == 0 &&
- global_ctdbd_connection == NULL) {
- struct tevent_context *ev;
- struct messaging_context *msg;
-
- ev = samba_tevent_context_init(NULL);
- if (!ev) {
- DEBUG(0,("samba_tevent_context_init failed\n"));
- return NULL;
- }
-
- msg = messaging_init(NULL, ev);
- if (!msg) {
- DEBUG(0,("messaging_init failed\n"));
- return NULL;
- }
- }
-
- if (global_ctdb_connection_pid != getpid()) {
- DEBUG(0,("messaging_ctdbd_connection():"
- "valid for pid[%jd] but it's [%jd]\n",
- (intmax_t)global_ctdb_connection_pid,
- (intmax_t)getpid()));
- smb_panic("messaging_ctdbd_connection() invalid process\n");
- }
-
- return global_ctdbd_connection;
-}
-
-static int messaging_ctdb_send(struct server_id src,
- struct server_id pid, int msg_type,
- const struct iovec *iov, int iovlen,
- const int *fds, size_t num_fds,
- struct messaging_backend *backend)
-{
- struct messaging_ctdbd_context *ctx = talloc_get_type_abort(
- backend->private_data, struct messaging_ctdbd_context);
- uint8_t hdr[MESSAGE_HDR_LENGTH];
- struct iovec iov2[iovlen+1];
-
- if (num_fds > 0) {
- return ENOSYS;
- }
-
- message_hdr_put(hdr, msg_type, src, pid);
- iov2[0] = (struct iovec){ .iov_base = hdr, .iov_len = sizeof(hdr) };
- memcpy(&iov2[1], iov, iovlen * sizeof(*iov));
-
- return ctdbd_messaging_send_iov(ctx->conn, pid.vnn, pid.pid,
- iov2, iovlen+1);
-}
-
-static int messaging_ctdbd_destructor(struct messaging_ctdbd_context *ctx)
-{
- /*
- * The global connection just went away
- */
- global_ctdb_connection_pid = 0;
- global_ctdbd_connection = NULL;
- return 0;
-}
-
-static int messaging_ctdb_recv(
- struct tevent_context *ev,
- uint32_t src_vnn, uint32_t dst_vnn, uint64_t dst_srvid,
- const uint8_t *msg, size_t msg_len, void *private_data)
-{
- struct messaging_ctdbd_context *ctx = talloc_get_type_abort(
- private_data, struct messaging_ctdbd_context);
-
- ctx->recv_cb(ev, msg, msg_len, NULL, 0, ctx->private_data);
-
- return 0;
-}
-
-static void messaging_ctdbd_readable(struct tevent_context *ev,
- struct tevent_fd *fde,
- uint16_t flags,
- void *private_data)
-{
- struct ctdbd_connection *conn = talloc_get_type_abort(
- private_data, struct ctdbd_connection);
-
- if ((flags & TEVENT_FD_READ) == 0) {
- return;
- }
- ctdbd_socket_readable(ev, conn);
-}
-
-static int messaging_ctdbd_init_internal(
- struct messaging_context *msg_ctx, TALLOC_CTX *mem_ctx,
- struct messaging_ctdbd_context *ctx,
- void (*recv_cb)(struct tevent_context *ev,
- const uint8_t *msg, size_t msg_len,
- int *fds, size_t num_fds,
- void *private_data),
- void *private_data,
- bool reinit)
-{
- int ret;
-
- if (reinit) {
- ret = ctdbd_reinit_connection(ctx,
- lp_ctdbd_socket(),
- lp_ctdb_timeout(),
- ctx->conn);
- if (ret != 0) {
- DBG_ERR("ctdbd_reinit_connection failed: %s\n",
- strerror(ret));
- return ret;
- }
- } else {
- ret = ctdbd_init_connection(ctx,
- lp_ctdbd_socket(),
- lp_ctdb_timeout(),
- &ctx->conn);
- if (ret != 0) {
- DBG_ERR("ctdbd_init_connection failed: %s\n",
- strerror(ret));
- return ret;
- }
- }
-
- ret = register_with_ctdbd(ctx->conn, MSG_SRVID_SAMBA, NULL, NULL);
- if (ret != 0) {
- DBG_DEBUG("Could not register MSG_SRVID_SAMBA: %s\n",
- strerror(ret));
- return ret;
- }
-
- ctx->recv_cb = recv_cb;
- ctx->private_data = private_data;
-
- ret = register_with_ctdbd(ctx->conn, getpid(),
- messaging_ctdb_recv, ctx);
- if (ret != 0) {
- DEBUG(10, ("register_with_ctdbd failed: %s\n",
- strerror(ret)));
- return ret;
- }
-
- global_ctdb_connection_pid = getpid();
- global_ctdbd_connection = ctx->conn;
- talloc_set_destructor(ctx, messaging_ctdbd_destructor);
-
- set_my_vnn(ctdbd_vnn(ctx->conn));
-
- return 0;
-}
-
-int messaging_ctdbd_init(struct messaging_context *msg_ctx,
- TALLOC_CTX *mem_ctx,
- void (*recv_cb)(struct tevent_context *ev,
- const uint8_t *msg, size_t msg_len,
- int *fds, size_t num_fds,
- void *private_data),
- void *private_data,
- struct messaging_backend **presult)
-{
- struct messaging_backend *result;
- struct messaging_ctdbd_context *ctx;
- int ret;
-
- if (!(result = talloc(mem_ctx, struct messaging_backend))) {
- DEBUG(0, ("talloc failed\n"));
- return ENOMEM;
- }
-
- if (!(ctx = talloc_zero(result, struct messaging_ctdbd_context))) {
- DEBUG(0, ("talloc failed\n"));
- TALLOC_FREE(result);
- return ENOMEM;
- }
-
- ret = messaging_ctdbd_init_internal(msg_ctx, mem_ctx, ctx,
- recv_cb, private_data, false);
- if (ret != 0) {
- TALLOC_FREE(result);
- return ret;
- }
-
- result->send_fn = messaging_ctdb_send;
- result->private_data = (void *)ctx;
-
- *presult = result;
- return 0;
-}
-
-int messaging_ctdbd_reinit(struct messaging_context *msg_ctx,
- TALLOC_CTX *mem_ctx,
- void (*recv_cb)(struct tevent_context *ev,
- const uint8_t *msg, size_t msg_len,
- int *fds, size_t num_fds,
- void *private_data),
- void *private_data,
- struct messaging_backend *backend)
-{
- struct messaging_ctdbd_context *ctx = talloc_get_type_abort(
- backend->private_data, struct messaging_ctdbd_context);
- int ret;
-
- ret = messaging_ctdbd_init_internal(msg_ctx, mem_ctx, ctx,
- recv_cb, private_data, true);
- if (ret != 0) {
- return ret;
- }
-
- return 0;
-}
-
-struct messaging_ctdbd_fde {
- struct tevent_fd *fde;
-};
-
-static int messaging_ctdbd_fde_ev_destructor(
- struct messaging_ctdbd_fde_ev *fde_ev)
-{
- if (fde_ev->ctx != NULL) {
- DLIST_REMOVE(fde_ev->ctx->fde_evs, fde_ev);
- fde_ev->ctx = NULL;
- }
- return 0;
-}
-
-struct messaging_ctdbd_fde *messaging_ctdbd_register_tevent_context(
- TALLOC_CTX *mem_ctx, struct tevent_context *ev,
- struct messaging_backend *backend)
-{
- struct messaging_ctdbd_context *ctx = talloc_get_type_abort(
- backend->private_data, struct messaging_ctdbd_context);
- struct messaging_ctdbd_fde_ev *fde_ev;
- struct messaging_ctdbd_fde *fde;
-
- if (ctx == NULL) {
- return NULL;
- }
-
- fde = talloc(mem_ctx, struct messaging_ctdbd_fde);
- if (fde == NULL) {
- return NULL;
- }
-
- for (fde_ev = ctx->fde_evs; fde_ev != NULL; fde_ev = fde_ev->next) {
- if ((fde_ev->ev == ev) &&
- (tevent_fd_get_flags(fde_ev->fde) != 0)) {
- break;
- }
- }
-
- if (fde_ev == NULL) {
- int fd = ctdbd_conn_get_fd(ctx->conn);
-
- fde_ev = talloc(fde, struct messaging_ctdbd_fde_ev);
- if (fde_ev == NULL) {
- return NULL;
- }
- fde_ev->fde = tevent_add_fd(
- ev, fde_ev, fd, TEVENT_FD_READ,
- messaging_ctdbd_readable, ctx->conn);
- if (fde_ev->fde == NULL) {
- TALLOC_FREE(fde);
- return NULL;
- }
- fde_ev->ev = ev;
- fde_ev->ctx = ctx;
- DLIST_ADD(ctx->fde_evs, fde_ev);
- talloc_set_destructor(
- fde_ev, messaging_ctdbd_fde_ev_destructor);
- } else {
- /*
- * Same trick as with tdb_wrap: The caller will never
- * see the talloc_referenced object, the
- * messaging_ctdbd_fde_ev, so problems with
- * talloc_unlink will not happen.
- */
- if (talloc_reference(fde, fde_ev) == NULL) {
- TALLOC_FREE(fde);
- return NULL;
- }
- }
-
- fde->fde = fde_ev->fde;
- return fde;
-}
+++ /dev/null
-/*
- * Unix SMB/CIFS implementation.
- * messages_ctdb.c header
- * Copyright (C) Volker Lendecke 2017
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-#ifndef _MESSAGES_CTDB_H_
-#define _MESSAGES_CTDB_H_
-
-#include "replace.h"
-#include <talloc.h>
-
-struct messaging_context;
-struct messaging_backend;
-struct ctdbd_connection;
-
-int messaging_ctdbd_init(struct messaging_context *msg_ctx,
- TALLOC_CTX *mem_ctx,
- void (*recv_cb)(struct tevent_context *ev,
- const uint8_t *msg, size_t msg_len,
- int *fds, size_t num_fds,
- void *private_data),
- void *private_data,
- struct messaging_backend **presult);
-int messaging_ctdbd_reinit(struct messaging_context *msg_ctx,
- TALLOC_CTX *mem_ctx,
- void (*recv_cb)(struct tevent_context *ev,
- const uint8_t *msg, size_t msg_len,
- int *fds, size_t num_fds,
- void *private_data),
- void *private_data,
- struct messaging_backend *backend);
-struct ctdbd_connection *messaging_ctdbd_connection(void);
-
-struct messaging_ctdbd_fde;
-struct messaging_ctdbd_fde *messaging_ctdbd_register_tevent_context(
- TALLOC_CTX *mem_ctx, struct tevent_context *ev,
- struct messaging_backend *backend);
-
-#endif