1
/* -*- mode: c; c-basic-offset: 8; -*-
2
* vim: noexpandtab sw=8 ts=8 sts=0:
5
/******************************************************************************
6
*******************************************************************************
8
** Copyright (C) 2005 Red Hat, Inc. All rights reserved.
10
** This copyrighted material is made available to anyone wishing to use,
11
** modify, copy, or redistribute it subject to the terms and conditions
12
** of the GNU General Public License v.2.
14
*******************************************************************************
15
******************************************************************************/
18
* Copyright (C) 2007 Oracle. All rights reserved.
20
* This copyrighted material is made available to anyone wishing to use,
21
* modify, copy, or redistribute it subject to the terms and conditions
22
* of the GNU General Public License v.2.
34
#include "ocfs2-kernel/kernel-list.h"
35
#include "o2cb/o2cb.h"
37
#include "ocfs2_controld.h"
41
static char * clustername;
42
static cman_cluster_t cluster;
43
static cman_handle_t ch;
44
static cman_handle_t ch_admin;
45
extern struct list_head mounts;
46
static cman_node_t old_nodes[O2NM_MAX_NODES];
47
static int old_node_count;
48
static cman_node_t cman_nodes[O2NM_MAX_NODES];
49
static int cman_node_count;
51
const char *stackname = "cman";
53
int kill_stack_node(int nodeid)
57
log_debug("killing node %d", nodeid);
59
error = cman_kill_node(ch_admin, nodeid);
61
log_debug("Unable to kill node %d, %d %d", nodeid, error,
67
static int is_member(cman_node_t *node_list, int count, int nodeid)
71
for (i = 0; i < count; i++) {
72
if (node_list[i].cn_nodeid == nodeid)
73
return node_list[i].cn_member;
78
static int is_old_member(int nodeid)
80
return is_member(old_nodes, old_node_count, nodeid);
83
static int is_cman_member(int nodeid)
85
return is_member(cman_nodes, cman_node_count, nodeid);
88
static cman_node_t *find_cman_node(int nodeid)
92
for (i = 0; i < cman_node_count; i++) {
93
if (cman_nodes[i].cn_nodeid == nodeid)
94
return &cman_nodes[i];
99
char *nodeid2name(int nodeid)
103
cn = find_cman_node(nodeid);
109
int validate_cluster(const char *cluster)
112
log_error("Trying to validate before cman is alive");
119
return !strcmp(cluster, clustername);
122
int get_clustername(const char **cluster)
125
log_error("Trying to validate before cman is alive");
130
log_error("NULL passed!");
134
*cluster = clustername;
139
/* keep track of the nodes */
140
static void statechange(void)
144
old_node_count = cman_node_count;
145
memcpy(&old_nodes, &cman_nodes, sizeof(old_nodes));
148
memset(&cman_nodes, 0, sizeof(cman_nodes));
149
rv = cman_get_nodes(ch, O2NM_MAX_NODES, &cman_node_count,
152
log_debug("cman_get_nodes error %d %d", rv, errno);
156
for (i = 0; i < old_node_count; i++) {
157
if (old_nodes[i].cn_member &&
158
!is_cman_member(old_nodes[i].cn_nodeid)) {
160
log_debug("cman: node %d removed",
161
old_nodes[i].cn_nodeid);
165
for (i = 0; i < cman_node_count; i++) {
166
if (cman_nodes[i].cn_member &&
167
!is_old_member(cman_nodes[i].cn_nodeid)) {
169
log_debug("cman: node %d added",
170
cman_nodes[i].cn_nodeid);
175
static void cman_callback(cman_handle_t h, void *private, int reason, int arg)
178
case CMAN_REASON_TRY_SHUTDOWN:
180
cman_replyto_shutdown(ch, 1);
182
log_debug("no to cman shutdown");
183
cman_replyto_shutdown(ch, 0);
187
case CMAN_REASON_STATECHANGE:
193
static void dead_cman(int ci)
196
log_error("Unknown connection %d", ci);
200
log_error("cman connection died");
205
static void process_cman(int ci)
210
log_error("Unknown connection %d", ci);
214
rv = cman_dispatch(ch, CMAN_DISPATCH_ALL);
215
if (rv == -1 && errno == EHOSTDOWN) {
216
log_error("cman connection died");
221
int setup_stack(void)
226
ch = cman_init(NULL);
228
log_error("cman_init error %d", errno);
233
ch_admin = cman_admin_init(NULL);
235
log_error("cman_admin_init error %d", errno);
240
rv = cman_start_notification(ch, cman_callback);
242
log_error("cman_start_notification error %d %d", rv, errno);
246
/* FIXME: wait here for us to be a member of the cluster */
248
memset(&cluster, 0, sizeof(cluster));
249
rv = cman_get_cluster(ch, &cluster);
251
log_error("cman_get_cluster error %d %d", rv, errno);
254
clustername = cluster.ci_name;
256
memset(&node, 0, sizeof(node));
257
rv = cman_get_node(ch, CMAN_NODEID_US, &node);
259
log_error("cman_get_node error %d %d", rv, errno);
262
our_nodeid = node.cn_nodeid;
264
fd = cman_get_fd(ch);
267
memset(&old_nodes, 0, sizeof(old_nodes));
269
memset(&cman_nodes, 0, sizeof(cman_nodes));
271
/* Fill the node list */
274
cman_ci = connection_add(fd, process_cman, dead_cman);
277
log_error("Unable to add cman client: %s",
285
cman_stop_notification(ch);
288
cman_finish(ch_admin);
291
ch = ch_admin = NULL;
295
void exit_stack(void)
298
cman_finish(ch_admin);
300
log_debug("closing cman connection");
301
cman_stop_notification(ch);