lib: Make get_cluster_vnn return 0/errno
[obnox/samba/samba-obnox.git] / source3 / lib / ctdbd_conn.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Samba internal messaging functions
4    Copyright (C) 2007 by Volker Lendecke
5    Copyright (C) 2007 by Andrew Tridgell
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "includes.h"
22 #include "util_tdb.h"
23 #include "serverid.h"
24 #include "ctdbd_conn.h"
25 #include "system/select.h"
26 #include "lib/sys_rw_data.h"
27 #include "lib/util/iov_buf.h"
28
29 #include "messages.h"
30
31 /* paths to these include files come from --with-ctdb= in configure */
32
33 #include "ctdb.h"
34 #include "ctdb_private.h"
35
36 struct ctdbd_srvid_cb {
37         uint64_t srvid;
38         int (*cb)(uint32_t src_vnn, uint32_t dst_vnn,
39                   uint64_t dst_srvid,
40                   const uint8_t *msg, size_t msglen,
41                   void *private_data);
42         void *private_data;
43 };
44
45 struct ctdbd_connection {
46         const char *sockname;   /* Needed in ctdbd_traverse */
47         struct messaging_context *msg_ctx;
48         uint32_t reqid;
49         uint32_t our_vnn;
50         uint64_t rand_srvid;
51         struct ctdbd_srvid_cb *callbacks;
52         int fd;
53         struct tevent_fd *fde;
54         int timeout;
55 };
56
57 static uint32_t ctdbd_next_reqid(struct ctdbd_connection *conn)
58 {
59         conn->reqid += 1;
60         if (conn->reqid == 0) {
61                 conn->reqid += 1;
62         }
63         return conn->reqid;
64 }
65
66 static int ctdbd_control(struct ctdbd_connection *conn,
67                          uint32_t vnn, uint32_t opcode,
68                          uint64_t srvid, uint32_t flags,
69                          TDB_DATA data,
70                          TALLOC_CTX *mem_ctx, TDB_DATA *outdata,
71                          int *cstatus);
72
73 /*
74  * exit on fatal communications errors with the ctdbd daemon
75  */
76 static void cluster_fatal(const char *why)
77 {
78         DEBUG(0,("cluster fatal event: %s - exiting immediately\n", why));
79         /* we don't use smb_panic() as we don't want to delay to write
80            a core file. We need to release this process id immediately
81            so that someone else can take over without getting sharing
82            violations */
83         _exit(1);
84 }
85
86 /*
87  *
88  */
89 static void ctdb_packet_dump(struct ctdb_req_header *hdr)
90 {
91         if (DEBUGLEVEL < 11) {
92                 return;
93         }
94         DEBUGADD(11, ("len=%d, magic=%x, vers=%d, gen=%d, op=%d, reqid=%d\n",
95                       (int)hdr->length, (int)hdr->ctdb_magic,
96                       (int)hdr->ctdb_version, (int)hdr->generation,
97                       (int)hdr->operation, (int)hdr->reqid));
98 }
99
100 /*
101  * Register a srvid with ctdbd
102  */
103 int register_with_ctdbd(struct ctdbd_connection *conn, uint64_t srvid,
104                         int (*cb)(uint32_t src_vnn, uint32_t dst_vnn,
105                                   uint64_t dst_srvid,
106                                   const uint8_t *msg, size_t msglen,
107                                   void *private_data),
108                         void *private_data)
109 {
110
111         int ret, cstatus;
112         size_t num_callbacks;
113         struct ctdbd_srvid_cb *tmp;
114
115         ret = ctdbd_control(conn, CTDB_CURRENT_NODE,
116                             CTDB_CONTROL_REGISTER_SRVID, srvid, 0,
117                             tdb_null, NULL, NULL, &cstatus);
118         if (ret != 0) {
119                 return ret;
120         }
121
122         num_callbacks = talloc_array_length(conn->callbacks);
123
124         tmp = talloc_realloc(conn, conn->callbacks, struct ctdbd_srvid_cb,
125                              num_callbacks + 1);
126         if (tmp == NULL) {
127                 return ENOMEM;
128         }
129         conn->callbacks = tmp;
130
131         conn->callbacks[num_callbacks] = (struct ctdbd_srvid_cb) {
132                 .srvid = srvid, .cb = cb, .private_data = private_data
133         };
134
135         return 0;
136 }
137
138 static int ctdbd_msg_call_back(struct ctdbd_connection *conn,
139                                struct ctdb_req_message *msg)
140 {
141         size_t msg_len;
142         size_t i, num_callbacks;
143
144         msg_len = msg->hdr.length;
145         if (msg_len < offsetof(struct ctdb_req_message, data)) {
146                 DEBUG(10, ("%s: len %u too small\n", __func__,
147                            (unsigned)msg_len));
148                 return 0;
149         }
150         msg_len -= offsetof(struct ctdb_req_message, data);
151
152         if (msg_len < msg->datalen) {
153                 DEBUG(10, ("%s: msg_len=%u < msg->datalen=%u\n", __func__,
154                            (unsigned)msg_len, (unsigned)msg->datalen));
155                 return 0;
156         }
157
158         num_callbacks = talloc_array_length(conn->callbacks);
159
160         for (i=0; i<num_callbacks; i++) {
161                 struct ctdbd_srvid_cb *cb = &conn->callbacks[i];
162
163                 if ((cb->srvid == msg->srvid) && (cb->cb != NULL)) {
164                         int ret;
165
166                         ret = cb->cb(msg->hdr.srcnode, msg->hdr.destnode,
167                                      msg->srvid, msg->data, msg->datalen,
168                                      cb->private_data);
169                         if (ret != 0) {
170                                 return ret;
171                         }
172                 }
173         }
174         return 0;
175 }
176
177 /*
178  * get our vnn from the cluster
179  */
180 static int get_cluster_vnn(struct ctdbd_connection *conn, uint32_t *vnn)
181 {
182         int32_t cstatus=-1;
183         int ret;
184         ret = ctdbd_control(conn,
185                             CTDB_CURRENT_NODE, CTDB_CONTROL_GET_PNN, 0, 0,
186                             tdb_null, NULL, NULL, &cstatus);
187         if (ret != 0) {
188                 DEBUG(1, ("ctdbd_control failed: %s\n", strerror(ret)));
189                 return ret;
190         }
191         *vnn = (uint32_t)cstatus;
192         return ret;
193 }
194
195 /*
196  * Are we active (i.e. not banned or stopped?)
197  */
198 static bool ctdbd_working(struct ctdbd_connection *conn, uint32_t vnn)
199 {
200         int32_t cstatus=-1;
201         TDB_DATA outdata;
202         struct ctdb_node_map *m;
203         uint32_t failure_flags;
204         bool ok = false;
205         int i, ret;
206
207         ret = ctdbd_control(conn, CTDB_CURRENT_NODE,
208                             CTDB_CONTROL_GET_NODEMAP, 0, 0,
209                             tdb_null, talloc_tos(), &outdata, &cstatus);
210         if (ret != 0) {
211                 DEBUG(1, ("ctdbd_control failed: %s\n", strerror(ret)));
212                 return false;
213         }
214         if ((cstatus != 0) || (outdata.dptr == NULL)) {
215                 DEBUG(2, ("Received invalid ctdb data\n"));
216                 return false;
217         }
218
219         m = (struct ctdb_node_map *)outdata.dptr;
220
221         for (i=0; i<m->num; i++) {
222                 if (vnn == m->nodes[i].pnn) {
223                         break;
224                 }
225         }
226
227         if (i == m->num) {
228                 DEBUG(2, ("Did not find ourselves (node %d) in nodemap\n",
229                           (int)vnn));
230                 goto fail;
231         }
232
233         failure_flags = NODE_FLAGS_BANNED | NODE_FLAGS_DISCONNECTED
234                 | NODE_FLAGS_PERMANENTLY_DISABLED | NODE_FLAGS_STOPPED;
235
236         if ((m->nodes[i].flags & failure_flags) != 0) {
237                 DEBUG(2, ("Node has status %x, not active\n",
238                           (int)m->nodes[i].flags));
239                 goto fail;
240         }
241
242         ok = true;
243 fail:
244         TALLOC_FREE(outdata.dptr);
245         return ok;
246 }
247
248 uint32_t ctdbd_vnn(const struct ctdbd_connection *conn)
249 {
250         return conn->our_vnn;
251 }
252
253 /*
254  * Get us a ctdb connection
255  */
256
257 static int ctdbd_connect(const char *sockname, int *pfd)
258 {
259         struct sockaddr_un addr = { 0, };
260         int fd;
261         socklen_t salen;
262         size_t namelen;
263
264         fd = socket(AF_UNIX, SOCK_STREAM, 0);
265         if (fd == -1) {
266                 int err = errno;
267                 DEBUG(3, ("Could not create socket: %s\n", strerror(err)));
268                 return err;
269         }
270
271         addr.sun_family = AF_UNIX;
272
273         namelen = strlcpy(addr.sun_path, sockname, sizeof(addr.sun_path));
274         if (namelen >= sizeof(addr.sun_path)) {
275                 DEBUG(3, ("%s: Socket name too long: %s\n", __func__,
276                           sockname));
277                 close(fd);
278                 return ENAMETOOLONG;
279         }
280
281         salen = sizeof(struct sockaddr_un);
282
283         if (connect(fd, (struct sockaddr *)(void *)&addr, salen) == -1) {
284                 int err = errno;
285                 DEBUG(1, ("connect(%s) failed: %s\n", sockname,
286                           strerror(err)));
287                 close(fd);
288                 return err;
289         }
290
291         *pfd = fd;
292         return 0;
293 }
294
295 static int ctdb_read_packet(int fd, int timeout, TALLOC_CTX *mem_ctx,
296                             struct ctdb_req_header **result)
297 {
298         struct ctdb_req_header *req;
299         int ret, revents;
300         uint32_t msglen;
301         ssize_t nread;
302
303         if (timeout != -1) {
304                 ret = poll_one_fd(fd, POLLIN, timeout, &revents);
305                 if (ret == -1) {
306                         return errno;
307                 }
308                 if (ret == 0) {
309                         return ETIMEDOUT;
310                 }
311                 if (ret != 1) {
312                         return EIO;
313                 }
314         }
315
316         nread = read_data(fd, &msglen, sizeof(msglen));
317         if (nread == -1) {
318                 return errno;
319         }
320         if (nread == 0) {
321                 return EIO;
322         }
323
324         if (msglen < sizeof(struct ctdb_req_header)) {
325                 return EIO;
326         }
327
328         req = talloc_size(mem_ctx, msglen);
329         if (req == NULL) {
330                 return ENOMEM;
331         }
332         talloc_set_name_const(req, "struct ctdb_req_header");
333
334         req->length = msglen;
335
336         nread = read_data(fd, ((char *)req) + sizeof(msglen),
337                           msglen - sizeof(msglen));
338         if (nread == -1) {
339                 TALLOC_FREE(req);
340                 return errno;
341         }
342         if (nread == 0) {
343                 TALLOC_FREE(req);
344                 return EIO;
345         }
346
347         *result = req;
348         return 0;
349 }
350
351 /*
352  * Read a full ctdbd request. If we have a messaging context, defer incoming
353  * messages that might come in between.
354  */
355
356 static int ctdb_read_req(struct ctdbd_connection *conn, uint32_t reqid,
357                          TALLOC_CTX *mem_ctx, struct ctdb_req_header **result)
358 {
359         struct ctdb_req_header *hdr;
360         int ret;
361
362  next_pkt:
363
364         ret = ctdb_read_packet(conn->fd, conn->timeout, mem_ctx, &hdr);
365         if (ret != 0) {
366                 DEBUG(0, ("ctdb_read_packet failed: %s\n", strerror(ret)));
367                 cluster_fatal("ctdbd died\n");
368         }
369
370         DEBUG(11, ("Received ctdb packet\n"));
371         ctdb_packet_dump(hdr);
372
373         if (hdr->operation == CTDB_REQ_MESSAGE) {
374                 struct ctdb_req_message *msg = (struct ctdb_req_message *)hdr;
375
376                 if (conn->msg_ctx == NULL) {
377                         DEBUG(1, ("Got a message without having a msg ctx, "
378                                   "dropping msg %llu\n",
379                                   (long long unsigned)msg->srvid));
380                         TALLOC_FREE(hdr);
381                         goto next_pkt;
382                 }
383
384                 ret = ctdbd_msg_call_back(conn, msg);
385                 if (ret != 0) {
386                         TALLOC_FREE(hdr);
387                         return ret;
388                 }
389
390                 TALLOC_FREE(hdr);
391                 goto next_pkt;
392         }
393
394         if ((reqid != 0) && (hdr->reqid != reqid)) {
395                 /* we got the wrong reply */
396                 DEBUG(0,("Discarding mismatched ctdb reqid %u should have "
397                          "been %u\n", hdr->reqid, reqid));
398                 TALLOC_FREE(hdr);
399                 goto next_pkt;
400         }
401
402         *result = talloc_move(mem_ctx, &hdr);
403
404         return 0;
405 }
406
407 static int ctdbd_connection_destructor(struct ctdbd_connection *c)
408 {
409         TALLOC_FREE(c->fde);
410         if (c->fd != -1) {
411                 close(c->fd);
412                 c->fd = -1;
413         }
414         return 0;
415 }
416 /*
417  * Get us a ctdbd connection
418  */
419
420 static NTSTATUS ctdbd_init_connection(TALLOC_CTX *mem_ctx,
421                                       const char *sockname, int timeout,
422                                       struct ctdbd_connection **pconn)
423 {
424         struct ctdbd_connection *conn;
425         int ret;
426         NTSTATUS status;
427
428         if (!(conn = talloc_zero(mem_ctx, struct ctdbd_connection))) {
429                 DEBUG(0, ("talloc failed\n"));
430                 return NT_STATUS_NO_MEMORY;
431         }
432
433         conn->sockname = talloc_strdup(conn, sockname);
434         if (conn->sockname == NULL) {
435                 DBG_ERR("%s: talloc failed\n", __func__);
436                 status = NT_STATUS_NO_MEMORY;
437                 goto fail;
438         }
439
440         conn->timeout = timeout;
441
442         if (conn->timeout == 0) {
443                 conn->timeout = -1;
444         }
445
446         ret = ctdbd_connect(conn->sockname, &conn->fd);
447         if (ret != 0) {
448                 status = map_nt_error_from_unix(ret);
449                 DEBUG(1, ("ctdbd_connect failed: %s\n", strerror(ret)));
450                 goto fail;
451         }
452         talloc_set_destructor(conn, ctdbd_connection_destructor);
453
454         ret = get_cluster_vnn(conn, &conn->our_vnn);
455
456         if (ret != 0) {
457                 DEBUG(10, ("get_cluster_vnn failed: %s\n", strerror(ret)));
458                 status = map_nt_error_from_unix(ret);
459                 goto fail;
460         }
461
462         if (!ctdbd_working(conn, conn->our_vnn)) {
463                 DEBUG(2, ("Node is not working, can not connect\n"));
464                 status = NT_STATUS_INTERNAL_DB_ERROR;
465                 goto fail;
466         }
467
468         generate_random_buffer((unsigned char *)&conn->rand_srvid,
469                                sizeof(conn->rand_srvid));
470
471         ret = register_with_ctdbd(conn, conn->rand_srvid, NULL, NULL);
472
473         if (ret != 0) {
474                 DEBUG(5, ("Could not register random srvid: %s\n",
475                           strerror(ret)));
476                 status = map_nt_error_from_unix(ret);
477                 goto fail;
478         }
479
480         *pconn = conn;
481         return NT_STATUS_OK;
482
483  fail:
484         TALLOC_FREE(conn);
485         return status;
486 }
487
488 /*
489  * Get us a ctdbd connection and register us as a process
490  */
491
492 NTSTATUS ctdbd_messaging_connection(TALLOC_CTX *mem_ctx,
493                                     const char *sockname, int timeout,
494                                     struct ctdbd_connection **pconn)
495 {
496         struct ctdbd_connection *conn;
497         NTSTATUS status;
498         int ret;
499
500         status = ctdbd_init_connection(mem_ctx, sockname, timeout, &conn);
501
502         if (!NT_STATUS_IS_OK(status)) {
503                 return status;
504         }
505
506         ret = register_with_ctdbd(conn, MSG_SRVID_SAMBA, NULL, NULL);
507         if (ret != 0) {
508                 status = map_nt_error_from_unix(ret);
509                 goto fail;
510         }
511
512         *pconn = conn;
513         return NT_STATUS_OK;
514
515  fail:
516         TALLOC_FREE(conn);
517         return status;
518 }
519
520 struct messaging_context *ctdb_conn_msg_ctx(struct ctdbd_connection *conn)
521 {
522         return conn->msg_ctx;
523 }
524
525 int ctdbd_conn_get_fd(struct ctdbd_connection *conn)
526 {
527         return conn->fd;
528 }
529
530 /*
531  * Packet handler to receive and handle a ctdb message
532  */
533 static int ctdb_handle_message(struct ctdbd_connection *conn,
534                                struct ctdb_req_header *hdr)
535 {
536         struct ctdb_req_message *msg;
537
538         if (hdr->operation != CTDB_REQ_MESSAGE) {
539                 DEBUG(0, ("Received async msg of type %u, discarding\n",
540                           hdr->operation));
541                 return EINVAL;
542         }
543
544         msg = (struct ctdb_req_message *)hdr;
545
546         ctdbd_msg_call_back(conn, msg);
547
548         return 0;
549 }
550
551 /*
552  * The ctdbd socket is readable asynchronuously
553  */
554
555 static void ctdbd_socket_handler(struct tevent_context *event_ctx,
556                                  struct tevent_fd *event,
557                                  uint16_t flags,
558                                  void *private_data)
559 {
560         struct ctdbd_connection *conn = talloc_get_type_abort(
561                 private_data, struct ctdbd_connection);
562         struct ctdb_req_header *hdr = NULL;
563         int ret;
564
565         ret = ctdb_read_packet(conn->fd, conn->timeout, talloc_tos(), &hdr);
566         if (ret != 0) {
567                 DEBUG(0, ("ctdb_read_packet failed: %s\n", strerror(ret)));
568                 cluster_fatal("ctdbd died\n");
569         }
570
571         ret = ctdb_handle_message(conn, hdr);
572
573         TALLOC_FREE(hdr);
574
575         if (ret != 0) {
576                 DEBUG(10, ("could not handle incoming message: %s\n",
577                            strerror(ret)));
578         }
579 }
580
581 /*
582  * Prepare a ctdbd connection to receive messages
583  */
584
585 NTSTATUS ctdbd_register_msg_ctx(struct ctdbd_connection *conn,
586                                 struct messaging_context *msg_ctx)
587 {
588         SMB_ASSERT(conn->msg_ctx == NULL);
589         SMB_ASSERT(conn->fde == NULL);
590
591         if (!(conn->fde = tevent_add_fd(messaging_tevent_context(msg_ctx),
592                                        conn,
593                                        conn->fd,
594                                        TEVENT_FD_READ,
595                                        ctdbd_socket_handler,
596                                        conn))) {
597                 DEBUG(0, ("event_add_fd failed\n"));
598                 return NT_STATUS_NO_MEMORY;
599         }
600
601         conn->msg_ctx = msg_ctx;
602
603         return NT_STATUS_OK;
604 }
605
606 NTSTATUS ctdbd_messaging_send_iov(struct ctdbd_connection *conn,
607                                   uint32_t dst_vnn, uint64_t dst_srvid,
608                                   const struct iovec *iov, int iovlen)
609 {
610         struct ctdb_req_message r;
611         struct iovec iov2[iovlen+1];
612         size_t buflen = iov_buflen(iov, iovlen);
613         ssize_t nwritten;
614
615         r.hdr.length = offsetof(struct ctdb_req_message, data) + buflen;
616         r.hdr.ctdb_magic = CTDB_MAGIC;
617         r.hdr.ctdb_version = CTDB_PROTOCOL;
618         r.hdr.generation = 1;
619         r.hdr.operation  = CTDB_REQ_MESSAGE;
620         r.hdr.destnode   = dst_vnn;
621         r.hdr.srcnode    = conn->our_vnn;
622         r.hdr.reqid      = 0;
623         r.srvid          = dst_srvid;
624         r.datalen        = buflen;
625
626         DEBUG(10, ("ctdbd_messaging_send: Sending ctdb packet\n"));
627         ctdb_packet_dump(&r.hdr);
628
629         iov2[0].iov_base = &r;
630         iov2[0].iov_len = offsetof(struct ctdb_req_message, data);
631         memcpy(&iov2[1], iov, iovlen * sizeof(struct iovec));
632
633         nwritten = write_data_iov(conn->fd, iov2, iovlen+1);
634         if (nwritten == -1) {
635                 DEBUG(3, ("write_data_iov failed: %s\n", strerror(errno)));
636                 cluster_fatal("cluster dispatch daemon msg write error\n");
637         }
638
639         return NT_STATUS_OK;
640 }
641
642 /*
643  * send/recv a generic ctdb control message
644  */
645 static int ctdbd_control(struct ctdbd_connection *conn,
646                          uint32_t vnn, uint32_t opcode,
647                          uint64_t srvid, uint32_t flags,
648                          TDB_DATA data,
649                          TALLOC_CTX *mem_ctx, TDB_DATA *outdata,
650                          int *cstatus)
651 {
652         struct ctdb_req_control req;
653         struct ctdb_req_header *hdr;
654         struct ctdb_reply_control *reply = NULL;
655         struct iovec iov[2];
656         ssize_t nwritten;
657         int ret;
658
659         ZERO_STRUCT(req);
660         req.hdr.length = offsetof(struct ctdb_req_control, data) + data.dsize;
661         req.hdr.ctdb_magic   = CTDB_MAGIC;
662         req.hdr.ctdb_version = CTDB_PROTOCOL;
663         req.hdr.operation    = CTDB_REQ_CONTROL;
664         req.hdr.reqid        = ctdbd_next_reqid(conn);
665         req.hdr.destnode     = vnn;
666         req.opcode           = opcode;
667         req.srvid            = srvid;
668         req.datalen          = data.dsize;
669         req.flags            = flags;
670
671         DEBUG(10, ("ctdbd_control: Sending ctdb packet\n"));
672         ctdb_packet_dump(&req.hdr);
673
674         iov[0].iov_base = &req;
675         iov[0].iov_len = offsetof(struct ctdb_req_control, data);
676         iov[1].iov_base = data.dptr;
677         iov[1].iov_len = data.dsize;
678
679         nwritten = write_data_iov(conn->fd, iov, ARRAY_SIZE(iov));
680         if (nwritten == -1) {
681                 DEBUG(3, ("write_data_iov failed: %s\n", strerror(errno)));
682                 cluster_fatal("cluster dispatch daemon msg write error\n");
683         }
684
685         if (flags & CTDB_CTRL_FLAG_NOREPLY) {
686                 if (cstatus) {
687                         *cstatus = 0;
688                 }
689                 return 0;
690         }
691
692         ret = ctdb_read_req(conn, req.hdr.reqid, NULL, &hdr);
693         if (ret != 0) {
694                 DEBUG(10, ("ctdb_read_req failed: %s\n", strerror(ret)));
695                 return ret;
696         }
697
698         if (hdr->operation != CTDB_REPLY_CONTROL) {
699                 DEBUG(0, ("received invalid reply\n"));
700                 TALLOC_FREE(hdr);
701                 return EIO;
702         }
703         reply = (struct ctdb_reply_control *)hdr;
704
705         if (outdata) {
706                 if (!(outdata->dptr = (uint8_t *)talloc_memdup(
707                               mem_ctx, reply->data, reply->datalen))) {
708                         TALLOC_FREE(reply);
709                         return ENOMEM;
710                 }
711                 outdata->dsize = reply->datalen;
712         }
713         if (cstatus) {
714                 (*cstatus) = reply->status;
715         }
716
717         TALLOC_FREE(reply);
718         return ret;
719 }
720
721 /*
722  * see if a remote process exists
723  */
724 bool ctdbd_process_exists(struct ctdbd_connection *conn, uint32_t vnn, pid_t pid)
725 {
726         struct server_id id;
727         bool result;
728
729         id.pid = pid;
730         id.vnn = vnn;
731
732         if (!ctdb_processes_exist(conn, &id, 1, &result)) {
733                 DEBUG(10, ("ctdb_processes_exist failed\n"));
734                 return false;
735         }
736         return result;
737 }
738
739 bool ctdb_processes_exist(struct ctdbd_connection *conn,
740                           const struct server_id *pids, int num_pids,
741                           bool *results)
742 {
743         TALLOC_CTX *frame = talloc_stackframe();
744         int i, num_received;
745         uint32_t *reqids;
746         bool result = false;
747
748         reqids = talloc_array(talloc_tos(), uint32_t, num_pids);
749         if (reqids == NULL) {
750                 goto fail;
751         }
752
753         for (i=0; i<num_pids; i++) {
754                 struct ctdb_req_control req;
755                 pid_t pid;
756                 struct iovec iov[2];
757                 ssize_t nwritten;
758
759                 results[i] = false;
760                 reqids[i] = ctdbd_next_reqid(conn);
761
762                 ZERO_STRUCT(req);
763
764                 /*
765                  * pids[i].pid is uint64_t, scale down to pid_t which
766                  * is the wire protocol towards ctdb.
767                  */
768                 pid = pids[i].pid;
769
770                 DEBUG(10, ("Requesting PID %d/%d, reqid=%d\n",
771                            (int)pids[i].vnn, (int)pid,
772                            (int)reqids[i]));
773
774                 req.hdr.length = offsetof(struct ctdb_req_control, data);
775                 req.hdr.length += sizeof(pid);
776                 req.hdr.ctdb_magic   = CTDB_MAGIC;
777                 req.hdr.ctdb_version = CTDB_PROTOCOL;
778                 req.hdr.operation    = CTDB_REQ_CONTROL;
779                 req.hdr.reqid        = reqids[i];
780                 req.hdr.destnode     = pids[i].vnn;
781                 req.opcode           = CTDB_CONTROL_PROCESS_EXISTS;
782                 req.srvid            = 0;
783                 req.datalen          = sizeof(pid);
784                 req.flags            = 0;
785
786                 DEBUG(10, ("ctdbd_control: Sending ctdb packet\n"));
787                 ctdb_packet_dump(&req.hdr);
788
789                 iov[0].iov_base = &req;
790                 iov[0].iov_len = offsetof(struct ctdb_req_control, data);
791                 iov[1].iov_base = &pid;
792                 iov[1].iov_len = sizeof(pid);
793
794                 nwritten = write_data_iov(conn->fd, iov, ARRAY_SIZE(iov));
795                 if (nwritten == -1) {
796                         DEBUG(10, ("write_data_iov failed: %s\n",
797                                    strerror(errno)));
798                         goto fail;
799                 }
800         }
801
802         num_received = 0;
803
804         while (num_received < num_pids) {
805                 struct ctdb_req_header *hdr;
806                 struct ctdb_reply_control *reply;
807                 uint32_t reqid;
808                 int ret;
809
810                 ret = ctdb_read_req(conn, 0, talloc_tos(), &hdr);
811                 if (ret != 0) {
812                         DEBUG(10, ("ctdb_read_req failed: %s\n",
813                                    strerror(ret)));
814                         goto fail;
815                 }
816
817                 if (hdr->operation != CTDB_REPLY_CONTROL) {
818                         DEBUG(10, ("Received invalid reply\n"));
819                         goto fail;
820                 }
821                 reply = (struct ctdb_reply_control *)hdr;
822
823                 reqid = reply->hdr.reqid;
824
825                 DEBUG(10, ("Received reqid %d\n", (int)reqid));
826
827                 for (i=0; i<num_pids; i++) {
828                         if (reqid == reqids[i]) {
829                                 break;
830                         }
831                 }
832                 if (i == num_pids) {
833                         DEBUG(10, ("Received unknown record number %u\n",
834                                    (unsigned)reqid));
835                         goto fail;
836                 }
837                 results[i] = ((reply->status) == 0);
838                 TALLOC_FREE(reply);
839                 num_received += 1;
840         }
841
842         result = true;
843 fail:
844         TALLOC_FREE(frame);
845         return result;
846 }
847
848 /*
849  * Get a db path
850  */
851 char *ctdbd_dbpath(struct ctdbd_connection *conn,
852                    TALLOC_CTX *mem_ctx, uint32_t db_id)
853 {
854         int ret;
855         TDB_DATA data;
856         TDB_DATA rdata = {0};
857         int32_t cstatus = 0;
858
859         data.dptr = (uint8_t*)&db_id;
860         data.dsize = sizeof(db_id);
861
862         ret = ctdbd_control(conn, CTDB_CURRENT_NODE,
863                             CTDB_CONTROL_GETDBPATH, 0, 0, data,
864                             mem_ctx, &rdata, &cstatus);
865         if ((ret != 0) || cstatus != 0) {
866                 DEBUG(0, (__location__ " ctdb_control for getdbpath failed: %s\n",
867                           strerror(ret)));
868                 return NULL;
869         }
870
871         return (char *)rdata.dptr;
872 }
873
874 /*
875  * attach to a ctdb database
876  */
877 NTSTATUS ctdbd_db_attach(struct ctdbd_connection *conn,
878                          const char *name, uint32_t *db_id, int tdb_flags)
879 {
880         int ret;
881         TDB_DATA data;
882         int32_t cstatus;
883         bool persistent = (tdb_flags & TDB_CLEAR_IF_FIRST) == 0;
884
885         data = string_term_tdb_data(name);
886
887         ret = ctdbd_control(conn, CTDB_CURRENT_NODE,
888                             persistent
889                             ? CTDB_CONTROL_DB_ATTACH_PERSISTENT
890                             : CTDB_CONTROL_DB_ATTACH,
891                             tdb_flags, 0, data, NULL, &data, &cstatus);
892         if (ret != 0) {
893                 DEBUG(0, (__location__ " ctdb_control for db_attach "
894                           "failed: %s\n", strerror(ret)));
895                 return map_nt_error_from_unix(ret);
896         }
897
898         if (cstatus != 0 || data.dsize != sizeof(uint32_t)) {
899                 DEBUG(0,(__location__ " ctdb_control for db_attach failed\n"));
900                 return NT_STATUS_INTERNAL_ERROR;
901         }
902
903         *db_id = *(uint32_t *)data.dptr;
904         talloc_free(data.dptr);
905
906         if (!(tdb_flags & TDB_SEQNUM)) {
907                 return NT_STATUS_OK;
908         }
909
910         data.dptr = (uint8_t *)db_id;
911         data.dsize = sizeof(*db_id);
912
913         ret = ctdbd_control(conn, CTDB_CURRENT_NODE,
914                             CTDB_CONTROL_ENABLE_SEQNUM, 0, 0, data,
915                             NULL, NULL, &cstatus);
916         if ((ret != 0) || cstatus != 0) {
917                 DEBUG(0, (__location__ " ctdb_control for enable seqnum "
918                           "failed: %s\n", strerror(ret)));
919                 return (ret == 0) ? NT_STATUS_INTERNAL_ERROR :
920                         map_nt_error_from_unix(ret);
921         }
922
923         return NT_STATUS_OK;
924 }
925
926 /*
927  * force the migration of a record to this node
928  */
929 NTSTATUS ctdbd_migrate(struct ctdbd_connection *conn, uint32_t db_id,
930                        TDB_DATA key)
931 {
932         struct ctdb_req_call req;
933         struct ctdb_req_header *hdr;
934         struct iovec iov[2];
935         ssize_t nwritten;
936         NTSTATUS status;
937         int ret;
938
939         ZERO_STRUCT(req);
940
941         req.hdr.length = offsetof(struct ctdb_req_call, data) + key.dsize;
942         req.hdr.ctdb_magic   = CTDB_MAGIC;
943         req.hdr.ctdb_version = CTDB_PROTOCOL;
944         req.hdr.operation    = CTDB_REQ_CALL;
945         req.hdr.reqid        = ctdbd_next_reqid(conn);
946         req.flags            = CTDB_IMMEDIATE_MIGRATION;
947         req.callid           = CTDB_NULL_FUNC;
948         req.db_id            = db_id;
949         req.keylen           = key.dsize;
950
951         DEBUG(10, ("ctdbd_migrate: Sending ctdb packet\n"));
952         ctdb_packet_dump(&req.hdr);
953
954         iov[0].iov_base = &req;
955         iov[0].iov_len = offsetof(struct ctdb_req_call, data);
956         iov[1].iov_base = key.dptr;
957         iov[1].iov_len = key.dsize;
958
959         nwritten = write_data_iov(conn->fd, iov, ARRAY_SIZE(iov));
960         if (nwritten == -1) {
961                 DEBUG(3, ("write_data_iov failed: %s\n", strerror(errno)));
962                 cluster_fatal("cluster dispatch daemon msg write error\n");
963         }
964
965         ret = ctdb_read_req(conn, req.hdr.reqid, NULL, &hdr);
966         if (ret != 0) {
967                 DEBUG(10, ("ctdb_read_req failed: %s\n", strerror(ret)));
968                 status = map_nt_error_from_unix(ret);
969                 goto fail;
970         }
971
972         if (hdr->operation != CTDB_REPLY_CALL) {
973                 DEBUG(0, ("received invalid reply\n"));
974                 status = NT_STATUS_INTERNAL_ERROR;
975                 goto fail;
976         }
977
978         status = NT_STATUS_OK;
979  fail:
980
981         TALLOC_FREE(hdr);
982         return status;
983 }
984
985 /*
986  * Fetch a record and parse it
987  */
988 NTSTATUS ctdbd_parse(struct ctdbd_connection *conn, uint32_t db_id,
989                      TDB_DATA key, bool local_copy,
990                      void (*parser)(TDB_DATA key, TDB_DATA data,
991                                     void *private_data),
992                      void *private_data)
993 {
994         struct ctdb_req_call req;
995         struct ctdb_req_header *hdr = NULL;
996         struct ctdb_reply_call *reply;
997         struct iovec iov[2];
998         ssize_t nwritten;
999         NTSTATUS status;
1000         uint32_t flags;
1001         int ret;
1002
1003         flags = local_copy ? CTDB_WANT_READONLY : 0;
1004
1005         ZERO_STRUCT(req);
1006
1007         req.hdr.length = offsetof(struct ctdb_req_call, data) + key.dsize;
1008         req.hdr.ctdb_magic   = CTDB_MAGIC;
1009         req.hdr.ctdb_version = CTDB_PROTOCOL;
1010         req.hdr.operation    = CTDB_REQ_CALL;
1011         req.hdr.reqid        = ctdbd_next_reqid(conn);
1012         req.flags            = flags;
1013         req.callid           = CTDB_FETCH_FUNC;
1014         req.db_id            = db_id;
1015         req.keylen           = key.dsize;
1016
1017         iov[0].iov_base = &req;
1018         iov[0].iov_len = offsetof(struct ctdb_req_call, data);
1019         iov[1].iov_base = key.dptr;
1020         iov[1].iov_len = key.dsize;
1021
1022         nwritten = write_data_iov(conn->fd, iov, ARRAY_SIZE(iov));
1023         if (nwritten == -1) {
1024                 DEBUG(3, ("write_data_iov failed: %s\n", strerror(errno)));
1025                 cluster_fatal("cluster dispatch daemon msg write error\n");
1026         }
1027
1028         ret = ctdb_read_req(conn, req.hdr.reqid, NULL, &hdr);
1029         if (ret != 0) {
1030                 DEBUG(10, ("ctdb_read_req failed: %s\n", strerror(ret)));
1031                 status = map_nt_error_from_unix(ret);
1032                 goto fail;
1033         }
1034
1035         if ((hdr == NULL) || (hdr->operation != CTDB_REPLY_CALL)) {
1036                 DEBUG(0, ("received invalid reply\n"));
1037                 status = NT_STATUS_INTERNAL_ERROR;
1038                 goto fail;
1039         }
1040         reply = (struct ctdb_reply_call *)hdr;
1041
1042         if (reply->datalen == 0) {
1043                 /*
1044                  * Treat an empty record as non-existing
1045                  */
1046                 status = NT_STATUS_NOT_FOUND;
1047                 goto fail;
1048         }
1049
1050         parser(key, make_tdb_data(&reply->data[0], reply->datalen),
1051                private_data);
1052
1053         status = NT_STATUS_OK;
1054  fail:
1055         TALLOC_FREE(hdr);
1056         return status;
1057 }
1058
1059 /*
1060   Traverse a ctdb database. This uses a kind-of hackish way to open a second
1061   connection to ctdbd to avoid the hairy recursive and async problems with
1062   everything in-line.
1063 */
1064
1065 NTSTATUS ctdbd_traverse(struct ctdbd_connection *master, uint32_t db_id,
1066                         void (*fn)(TDB_DATA key, TDB_DATA data,
1067                                    void *private_data),
1068                         void *private_data)
1069 {
1070         struct ctdbd_connection *conn;
1071         NTSTATUS status;
1072         int ret;
1073         TDB_DATA key, data;
1074         struct ctdb_traverse_start t;
1075         int cstatus;
1076
1077         become_root();
1078         status = ctdbd_init_connection(NULL, master->sockname, master->timeout,
1079                                        &conn);
1080         unbecome_root();
1081         if (!NT_STATUS_IS_OK(status)) {
1082                 DEBUG(0, ("ctdbd_init_connection failed: %s\n",
1083                           nt_errstr(status)));
1084                 return status;
1085         }
1086
1087         t.db_id = db_id;
1088         t.srvid = conn->rand_srvid;
1089         t.reqid = ctdbd_next_reqid(conn);
1090
1091         data.dptr = (uint8_t *)&t;
1092         data.dsize = sizeof(t);
1093
1094         ret = ctdbd_control(conn, CTDB_CURRENT_NODE,
1095                             CTDB_CONTROL_TRAVERSE_START, conn->rand_srvid,
1096                             0, data, NULL, NULL, &cstatus);
1097
1098         if ((ret != 0) || (cstatus != 0)) {
1099                 status = map_nt_error_from_unix(ret);
1100
1101                 DEBUG(0,("ctdbd_control failed: %s, %d\n", strerror(ret),
1102                          cstatus));
1103
1104                 if (NT_STATUS_IS_OK(status)) {
1105                         /*
1106                          * We need a mapping here
1107                          */
1108                         status = NT_STATUS_UNSUCCESSFUL;
1109                 }
1110                 TALLOC_FREE(conn);
1111                 return status;
1112         }
1113
1114         while (True) {
1115                 struct ctdb_req_header *hdr = NULL;
1116                 struct ctdb_req_message *m;
1117                 struct ctdb_rec_data *d;
1118
1119                 ret = ctdb_read_packet(conn->fd, conn->timeout, conn, &hdr);
1120                 if (ret != 0) {
1121                         DEBUG(0, ("ctdb_read_packet failed: %s\n",
1122                                   strerror(ret)));
1123                         cluster_fatal("ctdbd died\n");
1124                 }
1125
1126                 if (hdr->operation != CTDB_REQ_MESSAGE) {
1127                         DEBUG(0, ("Got operation %u, expected a message\n",
1128                                   (unsigned)hdr->operation));
1129                         TALLOC_FREE(conn);
1130                         return NT_STATUS_UNEXPECTED_IO_ERROR;
1131                 }
1132
1133                 m = (struct ctdb_req_message *)hdr;
1134                 d = (struct ctdb_rec_data *)&m->data[0];
1135                 if (m->datalen < sizeof(uint32_t) || m->datalen != d->length) {
1136                         DEBUG(0, ("Got invalid traverse data of length %d\n",
1137                                   (int)m->datalen));
1138                         TALLOC_FREE(conn);
1139                         return NT_STATUS_UNEXPECTED_IO_ERROR;
1140                 }
1141
1142                 key.dsize = d->keylen;
1143                 key.dptr  = &d->data[0];
1144                 data.dsize = d->datalen;
1145                 data.dptr = &d->data[d->keylen];
1146
1147                 if (key.dsize == 0 && data.dsize == 0) {
1148                         /* end of traverse */
1149                         TALLOC_FREE(conn);
1150                         return NT_STATUS_OK;
1151                 }
1152
1153                 if (data.dsize < sizeof(struct ctdb_ltdb_header)) {
1154                         DEBUG(0, ("Got invalid ltdb header length %d\n",
1155                                   (int)data.dsize));
1156                         TALLOC_FREE(conn);
1157                         return NT_STATUS_UNEXPECTED_IO_ERROR;
1158                 }
1159                 data.dsize -= sizeof(struct ctdb_ltdb_header);
1160                 data.dptr += sizeof(struct ctdb_ltdb_header);
1161
1162                 if (fn != NULL) {
1163                         fn(key, data, private_data);
1164                 }
1165         }
1166         return NT_STATUS_OK;
1167 }
1168
1169 /*
1170    This is used to canonicalize a ctdb_sock_addr structure.
1171 */
1172 static void smbd_ctdb_canonicalize_ip(const struct sockaddr_storage *in,
1173                                       struct sockaddr_storage *out)
1174 {
1175         memcpy(out, in, sizeof (*out));
1176
1177 #ifdef HAVE_IPV6
1178         if (in->ss_family == AF_INET6) {
1179                 const char prefix[12] = { 0,0,0,0,0,0,0,0,0,0,0xff,0xff };
1180                 const struct sockaddr_in6 *in6 =
1181                         (const struct sockaddr_in6 *)in;
1182                 struct sockaddr_in *out4 = (struct sockaddr_in *)out;
1183                 if (memcmp(&in6->sin6_addr, prefix, 12) == 0) {
1184                         memset(out, 0, sizeof(*out));
1185 #ifdef HAVE_SOCK_SIN_LEN
1186                         out4->sin_len = sizeof(*out);
1187 #endif
1188                         out4->sin_family = AF_INET;
1189                         out4->sin_port   = in6->sin6_port;
1190                         memcpy(&out4->sin_addr, &in6->sin6_addr.s6_addr[12], 4);
1191                 }
1192         }
1193 #endif
1194 }
1195
1196 /*
1197  * Register us as a server for a particular tcp connection
1198  */
1199
1200 NTSTATUS ctdbd_register_ips(struct ctdbd_connection *conn,
1201                             const struct sockaddr_storage *_server,
1202                             const struct sockaddr_storage *_client,
1203                             int (*cb)(uint32_t src_vnn, uint32_t dst_vnn,
1204                                       uint64_t dst_srvid,
1205                                       const uint8_t *msg, size_t msglen,
1206                                       void *private_data),
1207                             void *private_data)
1208 {
1209         struct ctdb_control_tcp_addr p;
1210         TDB_DATA data = { .dptr = (uint8_t *)&p, .dsize = sizeof(p) };
1211         int ret;
1212         struct sockaddr_storage client;
1213         struct sockaddr_storage server;
1214
1215         /*
1216          * Only one connection so far
1217          */
1218
1219         smbd_ctdb_canonicalize_ip(_client, &client);
1220         smbd_ctdb_canonicalize_ip(_server, &server);
1221
1222         switch (client.ss_family) {
1223         case AF_INET:
1224                 memcpy(&p.dest.ip, &server, sizeof(p.dest.ip));
1225                 memcpy(&p.src.ip, &client, sizeof(p.src.ip));
1226                 break;
1227         case AF_INET6:
1228                 memcpy(&p.dest.ip6, &server, sizeof(p.dest.ip6));
1229                 memcpy(&p.src.ip6, &client, sizeof(p.src.ip6));
1230                 break;
1231         default:
1232                 return NT_STATUS_INTERNAL_ERROR;
1233         }
1234
1235         /*
1236          * We want to be told about IP releases
1237          */
1238
1239         ret = register_with_ctdbd(conn, CTDB_SRVID_RELEASE_IP,
1240                                   cb, private_data);
1241         if (ret != 0) {
1242                 return map_nt_error_from_unix(ret);
1243         }
1244
1245         /*
1246          * inform ctdb of our tcp connection, so if IP takeover happens ctdb
1247          * can send an extra ack to trigger a reset for our client, so it
1248          * immediately reconnects
1249          */
1250         ret = ctdbd_control(conn, CTDB_CURRENT_NODE,
1251                             CTDB_CONTROL_TCP_CLIENT, 0,
1252                             CTDB_CTRL_FLAG_NOREPLY, data, NULL, NULL,
1253                             NULL);
1254         if (ret != 0) {
1255                 return map_nt_error_from_unix(ret);
1256         }
1257         return NT_STATUS_OK;
1258 }
1259
1260 /*
1261   call a control on the local node
1262  */
1263 NTSTATUS ctdbd_control_local(struct ctdbd_connection *conn, uint32_t opcode,
1264                              uint64_t srvid, uint32_t flags, TDB_DATA data,
1265                              TALLOC_CTX *mem_ctx, TDB_DATA *outdata,
1266                              int *cstatus)
1267 {
1268         int ret;
1269
1270         ret = ctdbd_control(conn, CTDB_CURRENT_NODE, opcode, srvid, flags, data,
1271                             mem_ctx, outdata, cstatus);
1272         if (ret != 0) {
1273                 return map_nt_error_from_unix(ret);
1274         }
1275         return NT_STATUS_OK;
1276 }
1277
1278 NTSTATUS ctdb_watch_us(struct ctdbd_connection *conn)
1279 {
1280         struct ctdb_client_notify_register reg_data;
1281         size_t struct_len;
1282         NTSTATUS status;
1283         int cstatus;
1284
1285         reg_data.srvid = CTDB_SRVID_SAMBA_NOTIFY;
1286         reg_data.len = 1;
1287         reg_data.notify_data[0] = 0;
1288
1289         struct_len = offsetof(struct ctdb_client_notify_register,
1290                               notify_data) + reg_data.len;
1291
1292         status = ctdbd_control_local(
1293                 conn, CTDB_CONTROL_REGISTER_NOTIFY, conn->rand_srvid, 0,
1294                 make_tdb_data((uint8_t *)&reg_data, struct_len),
1295                 NULL, NULL, &cstatus);
1296         if (!NT_STATUS_IS_OK(status)) {
1297                 DEBUG(1, ("ctdbd_control_local failed: %s\n",
1298                           nt_errstr(status)));
1299         }
1300         return status;
1301 }
1302
1303 NTSTATUS ctdb_unwatch(struct ctdbd_connection *conn)
1304 {
1305         struct ctdb_client_notify_deregister dereg_data;
1306         NTSTATUS status;
1307         int cstatus;
1308
1309         dereg_data.srvid = CTDB_SRVID_SAMBA_NOTIFY;
1310
1311         status = ctdbd_control_local(
1312                 conn, CTDB_CONTROL_DEREGISTER_NOTIFY, conn->rand_srvid, 0,
1313                 make_tdb_data((uint8_t *)&dereg_data, sizeof(dereg_data)),
1314                 NULL, NULL, &cstatus);
1315         if (!NT_STATUS_IS_OK(status)) {
1316                 DEBUG(1, ("ctdbd_control_local failed: %s\n",
1317                           nt_errstr(status)));
1318         }
1319         return status;
1320 }
1321
1322 NTSTATUS ctdbd_probe(const char *sockname, int timeout)
1323 {
1324         /*
1325          * Do a very early check if ctdbd is around to avoid an abort and core
1326          * later
1327          */
1328         struct ctdbd_connection *conn = NULL;
1329         NTSTATUS status;
1330
1331         status = ctdbd_messaging_connection(talloc_tos(), sockname, timeout,
1332                                             &conn);
1333
1334         /*
1335          * We only care if we can connect.
1336          */
1337         TALLOC_FREE(conn);
1338
1339         return status;
1340 }