libctdb: first cut, supports getrecmaster only
[metze/ctdb/wip.git] / libctdb / sync.c
1 /*
2    synchronous wrappers for libctdb
3
4    Copyright (C) Rusty Russell 2010
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 #include <ctdb.h>
20 #include <stdbool.h>
21 #include <poll.h>
22 #include <errno.h>
23 #include <stdlib.h>
24
25 /* FIXME: Find a way to share more code here. */
26 struct ctdb_getrecmaster {
27         bool done;
28         int status;
29         uint32_t *recmaster;
30 };
31
32 static bool ctdb_service_flush(struct ctdb_connection *ctdb)
33 {
34         struct pollfd fds;
35
36         fds.fd = ctdb_get_fd(ctdb);
37         fds.events = ctdb_which_events(ctdb);
38         if (poll(&fds, 1, -1) < 0) {
39                 /* Signalled is OK, other error is bad. */
40                 return errno == EINTR;
41         }
42         return ctdb_service(ctdb, fds.revents) >= 0;
43 }
44
45 static void getrecmaster_done(int status, uint32_t recmaster, void *priv_data)
46 {
47         struct ctdb_getrecmaster *grm = priv_data;
48         *grm->recmaster = recmaster;
49         grm->status = status;
50         grm->done = true;
51 }
52
53 int ctdb_getrecmaster(struct ctdb_connection *ctdb,
54                       uint32_t destnode, uint32_t *recmaster)
55 {
56         struct ctdb_request *req;
57         struct ctdb_getrecmaster grm;
58
59         grm.done = false;
60         grm.recmaster = recmaster;
61         req = ctdb_getrecmaster_send(ctdb, destnode, getrecmaster_done, &grm);
62         if (!req)
63                 return -1;
64
65         while (!grm.done) {
66                 if (!ctdb_service_flush(ctdb)) {
67                         ctdb_cancel(req);
68                         return -1;
69                 }
70         }
71         return grm.status;
72 }
73
74 struct ctdb_attachdb {
75         bool done;
76         int status;
77         struct ctdb_db *ctdb_db;
78 };
79
80 static void attachdb_sync_done(int status,
81                                struct ctdb_db *ctdb_db, void *private_data)
82 {
83         struct ctdb_attachdb *atb = private_data;
84         atb->ctdb_db = ctdb_db;
85         atb->status = status;
86         atb->done = true;
87 }
88
89 struct ctdb_db *ctdb_attachdb(struct ctdb_connection *ctdb,
90                               const char *name, int persistent,
91                               uint32_t tdb_flags)
92 {
93         struct ctdb_request *req;
94         struct ctdb_attachdb atb;
95
96         atb.done = false;
97         req = ctdb_attachdb_send(ctdb, name, persistent, tdb_flags,
98                                  attachdb_sync_done, &atb);
99         if (!req)
100                 return NULL;
101
102         while (!atb.done) {
103                 if (!ctdb_service_flush(ctdb)) {
104                         ctdb_cancel(req);
105                         return NULL;
106                 }
107         }
108         if (atb.status != 0)
109                 return NULL;
110         return atb.ctdb_db;
111 }