1/* 2 Unix SMB/CIFS implementation. 3 Samba internal messaging functions 4 Copyright (C) 2007 by Volker Lendecke 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 3 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program. If not, see <http://www.gnu.org/licenses/>. 18*/ 19 20#include "includes.h" 21 22#ifdef CLUSTER_SUPPORT 23 24#include "librpc/gen_ndr/messaging.h" 25#include "ctdb.h" 26#include "ctdb_private.h" 27#include "ctdbd_conn.h" 28 29 30struct messaging_ctdbd_context { 31 struct ctdbd_connection *conn; 32}; 33 34/* 35 * This is a Samba3 hack/optimization. Routines like process_exists need to 36 * talk to ctdbd, and they don't get handed a messaging context. 37 */ 38static struct ctdbd_connection *global_ctdbd_connection; 39static int global_ctdb_connection_pid; 40 41struct ctdbd_connection *messaging_ctdbd_connection(void) 42{ 43 if (global_ctdb_connection_pid == 0 && 44 global_ctdbd_connection == NULL) { 45 struct event_context *ev; 46 struct messaging_context *msg; 47 48 ev = event_context_init(NULL); 49 if (!ev) { 50 DEBUG(0,("event_context_init failed\n")); 51 } 52 53 msg = messaging_init(NULL, procid_self(), ev); 54 if (!msg) { 55 DEBUG(0,("messaging_init failed\n")); 56 return NULL; 57 } 58 } 59 60 if (global_ctdb_connection_pid != getpid()) { 61 DEBUG(0,("messaging_ctdbd_connection():" 62 "valid for pid[%d] but it's [%d]\n", 63 global_ctdb_connection_pid, getpid())); 64 smb_panic("messaging_ctdbd_connection() invalid process\n"); 65 } 66 67 return global_ctdbd_connection; 68} 69 70static NTSTATUS messaging_ctdb_send(struct messaging_context *msg_ctx, 71 struct server_id pid, int msg_type, 72 const DATA_BLOB *data, 73 struct messaging_backend *backend) 74{ 75 struct messaging_ctdbd_context *ctx = talloc_get_type_abort( 76 backend->private_data, struct messaging_ctdbd_context); 77 78 struct messaging_rec msg; 79 80 msg.msg_version = MESSAGE_VERSION; 81 msg.msg_type = msg_type; 82 msg.dest = pid; 83 msg.src = procid_self(); 84 msg.buf = *data; 85 86 return ctdbd_messaging_send(ctx->conn, pid.vnn, pid.pid, &msg); 87} 88 89static int messaging_ctdbd_destructor(struct messaging_ctdbd_context *ctx) 90{ 91 /* 92 * The global connection just went away 93 */ 94 global_ctdb_connection_pid = 0; 95 global_ctdbd_connection = NULL; 96 return 0; 97} 98 99NTSTATUS messaging_ctdbd_init(struct messaging_context *msg_ctx, 100 TALLOC_CTX *mem_ctx, 101 struct messaging_backend **presult) 102{ 103 struct messaging_backend *result; 104 struct messaging_ctdbd_context *ctx; 105 NTSTATUS status; 106 107 if (!(result = TALLOC_P(mem_ctx, struct messaging_backend))) { 108 DEBUG(0, ("talloc failed\n")); 109 return NT_STATUS_NO_MEMORY; 110 } 111 112 if (!(ctx = TALLOC_P(result, struct messaging_ctdbd_context))) { 113 DEBUG(0, ("talloc failed\n")); 114 TALLOC_FREE(result); 115 return NT_STATUS_NO_MEMORY; 116 } 117 118 status = ctdbd_messaging_connection(ctx, &ctx->conn); 119 120 if (!NT_STATUS_IS_OK(status)) { 121 DEBUG(10, ("ctdbd_messaging_connection failed: %s\n", 122 nt_errstr(status))); 123 TALLOC_FREE(result); 124 return status; 125 } 126 127 status = ctdbd_register_msg_ctx(ctx->conn, msg_ctx); 128 129 if (!NT_STATUS_IS_OK(status)) { 130 DEBUG(10, ("ctdbd_register_msg_ctx failed: %s\n", 131 nt_errstr(status))); 132 TALLOC_FREE(result); 133 return status; 134 } 135 136 global_ctdb_connection_pid = getpid(); 137 global_ctdbd_connection = ctx->conn; 138 talloc_set_destructor(ctx, messaging_ctdbd_destructor); 139 140 set_my_vnn(ctdbd_vnn(ctx->conn)); 141 142 result->send_fn = messaging_ctdb_send; 143 result->private_data = (void *)ctx; 144 145 *presult = result; 146 return NT_STATUS_OK; 147} 148 149#else 150 151NTSTATUS messaging_ctdbd_init(struct messaging_context *msg_ctx, 152 TALLOC_CTX *mem_ctx, 153 struct messaging_backend **presult) 154{ 155 return NT_STATUS_NOT_IMPLEMENTED; 156} 157 158#endif 159