43
38
#include <linux/types.h>
40
#include "o2cb/o2cb.h"
41
#include "o2cb/o2cb_client_proto.h"
46
42
#include "o2cb_abi.h"
47
43
#include "o2cb_crc32.h"
48
#include "ocfs2_nodemanager.h"
45
#define CLUSTER_STACK_FILE "/sys/fs/ocfs2/cluster_stack"
46
#define LOCKING_PROTOCOL_FILE "/sys/fs/ocfs2/max_locking_protocol"
47
#define OCFS2_STACK_LABEL_LEN 4
48
#define CONTROL_DEVICE "/dev/misc/ocfs2_control"
51
struct o2cb_stack_ops {
52
errcode_t (*list_clusters)(char ***clusters);
53
errcode_t (*begin_group_join)(struct o2cb_cluster_desc *cluster,
54
struct o2cb_region_desc *region);
55
errcode_t (*complete_group_join)(struct o2cb_cluster_desc *cluster,
56
struct o2cb_region_desc *region,
58
errcode_t (*group_leave)(struct o2cb_cluster_desc *cluster,
59
struct o2cb_region_desc *region);
63
char s_name[OCFS2_STACK_LABEL_LEN + 1];
64
struct o2cb_stack_ops *s_ops;
67
static errcode_t classic_list_clusters(char ***clusters);
68
static errcode_t classic_begin_group_join(struct o2cb_cluster_desc *cluster,
69
struct o2cb_region_desc *region);
70
static errcode_t classic_complete_group_join(struct o2cb_cluster_desc *cluster,
71
struct o2cb_region_desc *region,
73
static errcode_t classic_group_leave(struct o2cb_cluster_desc *cluster,
74
struct o2cb_region_desc *region);
75
static struct o2cb_stack_ops classic_ops = {
76
.list_clusters = classic_list_clusters,
77
.begin_group_join = classic_begin_group_join,
78
.complete_group_join = classic_complete_group_join,
79
.group_leave = classic_group_leave,
81
static struct o2cb_stack classic_stack = {
83
.s_ops = &classic_ops,
86
static errcode_t user_list_clusters(char ***clusters);
87
static errcode_t user_begin_group_join(struct o2cb_cluster_desc *cluster,
88
struct o2cb_region_desc *region);
89
static errcode_t user_complete_group_join(struct o2cb_cluster_desc *cluster,
90
struct o2cb_region_desc *region,
92
static errcode_t user_group_leave(struct o2cb_cluster_desc *cluster,
93
struct o2cb_region_desc *region);
94
static struct o2cb_stack_ops user_ops = {
95
.list_clusters = user_list_clusters,
96
.begin_group_join = user_begin_group_join,
97
.complete_group_join = user_complete_group_join,
98
.group_leave = user_group_leave,
100
static struct o2cb_stack user_stack = {
104
static struct o2cb_stack *current_stack;
105
static int control_daemon_fd = -1;
106
static int control_device_fd = -1;
50
108
static char *configfs_path;
111
static ssize_t read_single_line_file(const char *file, char *line,
117
f = fopen(file, "r");
119
if (fgets(line, count, f))
128
static ssize_t read_stack_file(char *line, size_t count)
130
return read_single_line_file(CLUSTER_STACK_FILE, line, count);
133
static errcode_t determine_stack(void)
137
errcode_t err = O2CB_ET_SERVICE_UNAVAILABLE;
139
len = read_stack_file(line, sizeof(line));
141
if (line[len - 1] == '\n') {
142
line[len - 1] = '\0';
146
if (len != OCFS2_STACK_LABEL_LEN)
147
err = O2CB_ET_INTERNAL_FAILURE;
148
else if (!strcmp(line, classic_stack.s_name)) {
149
current_stack = &classic_stack;
152
strncpy(user_stack.s_name, line,
153
OCFS2_STACK_LABEL_LEN);
154
current_stack = &user_stack;
157
} else if (len == -ENOENT) {
158
current_stack = &classic_stack;
165
errcode_t o2cb_get_stack_name(const char **name)
168
return O2CB_ET_SERVICE_UNAVAILABLE;
170
*name = current_stack->s_name;
174
static ssize_t read_locking_proto_file(char *line, size_t count)
176
return read_single_line_file(LOCKING_PROTOCOL_FILE, line, count);
179
errcode_t o2cb_get_max_locking_protocol(struct ocfs2_protocol_version *proto)
184
unsigned int major, minor;
186
len = read_locking_proto_file(line, sizeof(line));
191
err = O2CB_ET_PERMISSION_DENIED;
195
err = O2CB_ET_NO_MEMORY;
201
err = O2CB_ET_SERVICE_UNAVAILABLE;
205
err = O2CB_ET_INTERNAL_FAILURE;
211
if (line[len - 1] == '\n') {
212
line[len - 1] = '\0';
216
err = O2CB_ET_SERVICE_UNAVAILABLE;
217
if (sscanf(line, "%u.%u", &major, &minor) != 2)
219
/* Major and minor can't be more than a u8 */
220
if ((major > (uint8_t)-1) || (minor > (uint8_t)-1))
223
proto->pv_major = major;
224
proto->pv_minor = minor;
52
232
errcode_t o2cb_create_cluster(const char *cluster_name)
54
234
char path[PATH_MAX];
1080
errcode_t o2cb_start_heartbeat_region(const char *cluster_name,
1081
struct o2cb_region_desc *desc)
1083
return __o2cb_start_heartbeat_region(cluster_name, desc, 1);
1086
errcode_t o2cb_stop_heartbeat_region(const char *cluster_name,
1087
const char *region_name)
1089
return __o2cb_stop_heartbeat_region(cluster_name, region_name, 1);
1092
errcode_t o2cb_start_heartbeat_region_perm(const char *cluster_name,
1093
struct o2cb_region_desc *desc)
1095
return __o2cb_start_heartbeat_region(cluster_name, desc, 0);
1098
errcode_t o2cb_stop_heartbeat_region_perm(const char *cluster_name,
1099
const char *region_name)
1101
return __o2cb_stop_heartbeat_region(cluster_name, region_name, 0);
1266
static errcode_t classic_complete_group_join(struct o2cb_cluster_desc *cluster,
1267
struct o2cb_region_desc *region,
1273
ret = classic_group_leave(cluster, region);
1278
static errcode_t user_parse_status(char **args, int *error, char **error_msg)
1280
errcode_t err = O2CB_ET_IO;
1284
result = strtol(args[0], &ptr, 10);
1285
if (ptr && *ptr != '\0') {
1286
/* fprintf(stderr, "Invalid error code string: %s", args[0]); */
1287
} else if ((result == LONG_MIN) || (result == LONG_MAX) ||
1288
(result < INT_MIN) || (result > INT_MAX)) {
1289
/* fprintf(stderr, "Error code %ld out of range", err); */
1291
*error_msg = args[1];
1299
static errcode_t user_begin_group_join(struct o2cb_cluster_desc *cluster,
1300
struct o2cb_region_desc *region)
1306
client_message message;
1307
char *argv[OCFS2_CONTROLD_MAXARGS + 1];
1308
char buf[OCFS2_CONTROLD_MAXLINE];
1310
if (control_daemon_fd != -1) {
1311
/* fprintf(stderr, "Join already in progress!\n"); */
1312
err = O2CB_ET_INTERNAL_FAILURE;
1316
rc = ocfs2_client_connect();
1318
/* fprintf(stderr, "Unable to connect to ocfs2_controld: %s\n",
1323
err = O2CB_ET_PERMISSION_DENIED;
1327
err = O2CB_ET_SERVICE_UNAVAILABLE;
1332
control_daemon_fd = rc;
1334
rc = send_message(control_daemon_fd, CM_MOUNT, OCFS2_FS_NAME,
1335
region->r_name, cluster->c_cluster,
1336
region->r_device_name, region->r_service);
1338
/* fprintf(stderr, "Unable to send MOUNT message: %s\n",
1344
rc = receive_message(control_daemon_fd, buf, &message, argv);
1346
/* fprintf(stderr, "Error reading from daemon: %s\n",
1354
err = user_parse_status(argv, &error, &error_msg);
1356
/* fprintf(stderr, "Bad status message: %s\n",
1360
if (error && (error != EALREADY)) {
1362
"Error %d from daemon: %s\n",
1363
error, error_msg); */
1364
err = O2CB_ET_CONFIGURATION_ERROR;
1371
"Unexpected message %s from daemon\n",
1372
message_to_string(message)); */
1373
err = O2CB_ET_INTERNAL_FAILURE;
1381
if (err && (control_daemon_fd != -1)) {
1382
close(control_daemon_fd);
1383
control_daemon_fd = -1;
1389
static errcode_t user_complete_group_join(struct o2cb_cluster_desc *cluster,
1390
struct o2cb_region_desc *region,
1393
errcode_t err = O2CB_ET_SERVICE_UNAVAILABLE;
1397
client_message message;
1398
char *argv[OCFS2_CONTROLD_MAXARGS + 1];
1399
char buf[OCFS2_CONTROLD_MAXLINE];
1401
if (control_daemon_fd == -1) {
1402
/* fprintf(stderr, "Join not started!\n"); */
1403
err = O2CB_ET_SERVICE_UNAVAILABLE;
1407
rc = send_message(control_daemon_fd, CM_MRESULT, OCFS2_FS_NAME,
1408
region->r_name, result, region->r_service);
1410
/* fprintf(stderr, "Unable to send MRESULT message: %s\n",
1416
rc = receive_message(control_daemon_fd, buf, &message, argv);
1418
/* fprintf(stderr, "Error reading from daemon: %s\n",
1426
err = user_parse_status(argv, &error, &error_msg);
1428
/* fprintf(stderr, "Bad status message: %s\n",
1434
"Error %d from daemon: %s\n",
1435
error, error_msg); */
1436
err = O2CB_ET_CONFIGURATION_ERROR;
1442
"Unexpected message %s from daemon\n",
1443
message_to_string(message)); */
1444
err = O2CB_ET_INTERNAL_FAILURE;
1452
if (control_daemon_fd != -1) {
1453
close(control_daemon_fd);
1454
control_daemon_fd = -1;
1460
static errcode_t user_group_leave(struct o2cb_cluster_desc *cluster,
1461
struct o2cb_region_desc *region)
1463
errcode_t err = O2CB_ET_SERVICE_UNAVAILABLE;
1467
client_message message;
1468
char *argv[OCFS2_CONTROLD_MAXARGS + 1];
1469
char buf[OCFS2_CONTROLD_MAXLINE];
1471
if (control_daemon_fd != -1) {
1472
/* fprintf(stderr, "Join in progress!\n"); */
1473
err = O2CB_ET_INTERNAL_FAILURE;
1477
rc = ocfs2_client_connect();
1479
/* fprintf(stderr, "Unable to connect to ocfs2_controld: %s\n",
1484
err = O2CB_ET_PERMISSION_DENIED;
1488
err = O2CB_ET_SERVICE_UNAVAILABLE;
1493
control_daemon_fd = rc;
1495
rc = send_message(control_daemon_fd, CM_UNMOUNT, OCFS2_FS_NAME,
1496
region->r_name, region->r_service);
1498
/* fprintf(stderr, "Unable to send UNMOUNT message: %s\n",
1504
rc = receive_message(control_daemon_fd, buf, &message, argv);
1506
/* fprintf(stderr, "Error reading from daemon: %s\n",
1514
err = user_parse_status(argv, &error, &error_msg);
1516
/* fprintf(stderr, "Bad status message: %s\n",
1522
"Error %d from daemon: %s\n",
1523
error, error_msg); */
1524
err = O2CB_ET_CONFIGURATION_ERROR;
1531
"Unexpected message %s from daemon\n",
1532
message_to_string(message)); */
1533
err = O2CB_ET_INTERNAL_FAILURE;
1541
if (control_daemon_fd != -1) {
1542
close(control_daemon_fd);
1543
control_daemon_fd = -1;
1549
static errcode_t o2cb_validate_cluster_desc(struct o2cb_cluster_desc *desc)
1555
return O2CB_ET_INVALID_STACK_NAME;
1557
if (desc->c_stack && !desc->c_cluster)
1558
return O2CB_ET_INVALID_STACK_NAME;
1560
err = o2cb_get_stack_name(&name);
1564
if (desc->c_stack) {
1565
if (strcmp(desc->c_stack, name))
1566
return O2CB_ET_INVALID_STACK_NAME;
1567
} else if (strcmp(name, classic_stack.s_name))
1568
return O2CB_ET_INVALID_STACK_NAME;
1573
errcode_t o2cb_begin_group_join(struct o2cb_cluster_desc *cluster,
1574
struct o2cb_region_desc *region)
1577
struct o2cb_cluster_desc desc;
1578
char _fake_cluster_name[NAME_MAX];
1581
return O2CB_ET_SERVICE_UNAVAILABLE;
1583
err = o2cb_validate_cluster_desc(cluster);
1588
if (!desc.c_cluster) {
1589
err = _fake_default_cluster(_fake_cluster_name);
1592
desc.c_cluster = _fake_cluster_name;
1595
return current_stack->s_ops->begin_group_join(&desc, region);
1598
errcode_t o2cb_complete_group_join(struct o2cb_cluster_desc *cluster,
1599
struct o2cb_region_desc *region,
1603
struct o2cb_cluster_desc desc;
1604
char _fake_cluster_name[NAME_MAX];
1607
return O2CB_ET_SERVICE_UNAVAILABLE;
1609
err = o2cb_validate_cluster_desc(cluster);
1614
if (!desc.c_cluster) {
1615
err = _fake_default_cluster(_fake_cluster_name);
1618
desc.c_cluster = _fake_cluster_name;
1621
return current_stack->s_ops->complete_group_join(&desc, region,
1625
errcode_t o2cb_group_leave(struct o2cb_cluster_desc *cluster,
1626
struct o2cb_region_desc *region)
1629
struct o2cb_cluster_desc desc;
1630
char _fake_cluster_name[NAME_MAX];
1633
return O2CB_ET_SERVICE_UNAVAILABLE;
1635
err = o2cb_validate_cluster_desc(cluster);
1640
if (!desc.c_cluster) {
1641
err = _fake_default_cluster(_fake_cluster_name);
1644
desc.c_cluster = _fake_cluster_name;
1647
return current_stack->s_ops->group_leave(&desc, region);
1650
void o2cb_free_cluster_desc(struct o2cb_cluster_desc *cluster)
1652
if (cluster->c_stack)
1653
free(cluster->c_stack);
1654
if (cluster->c_cluster)
1655
free(cluster->c_cluster);
1658
errcode_t o2cb_running_cluster_desc(struct o2cb_cluster_desc *cluster)
1662
char **clusters = NULL;
1664
err = o2cb_get_stack_name(&stack);
1668
if (!strcmp(stack, classic_stack.s_name)) {
1669
cluster->c_stack = NULL;
1670
cluster->c_cluster = NULL;
1674
cluster->c_stack = strdup(stack);
1675
if (!cluster->c_stack)
1676
return O2CB_ET_NO_MEMORY;
1678
err = o2cb_list_clusters(&clusters);
1680
free(cluster->c_stack);
1684
/* The first cluster is the default cluster */
1686
cluster->c_cluster = strdup(clusters[0]);
1687
if (!cluster->c_cluster) {
1688
free(cluster->c_stack);
1689
err = O2CB_ET_NO_MEMORY;
1692
o2cb_free_cluster_list(clusters);
1104
1697
static inline int is_dots(const char *name)
2049
* The handshake is pretty simple. We need to read all supported control
2050
* device protocols from the kernel. Once we've read them, we can write
2051
* the protocol we want to use. After that, we're good to go.
2053
* Right now, we will just allow the T01 protocol and not write any
2054
* code to handle multiples. We'll add that later if and when it is
2057
* The versions read from the kernel are all 4 characers including the
2060
#define OCFS2_CONTROL_PROTO "T01\n"
2061
#define OCFS2_CONTROL_PROTO_LEN 4
2062
#define OCFS2_CONTROL_MESSAGE_SETNODE_OP "SETN"
2063
#define OCFS2_CONTROL_MESSAGE_SETNODE_TOTAL_LEN 14
2064
#define OCFS2_CONTROL_MESSAGE_SETVERSION_OP "SETV"
2065
#define OCFS2_CONTROL_MESSAGE_SETVERSION_TOTAL_LEN 11
2066
#define OCFS2_CONTROL_MESSAGE_DOWN_OP "DOWN"
2067
#define OCFS2_CONTROL_MESSAGE_DOWN_TOTAL_LEN 47
2068
#define OCFS2_CONTROL_MESSAGE_NODENUM_LEN 8
2069
static errcode_t o2cb_control_handshake(unsigned int this_node,
2070
struct ocfs2_protocol_version *proto)
2075
char buf[OCFS2_CONTROL_MESSAGE_SETNODE_TOTAL_LEN + 1];
2077
if (control_device_fd == -1) {
2078
err = O2CB_ET_INTERNAL_FAILURE;
2082
buf[OCFS2_CONTROL_PROTO_LEN] = '\0';
2085
ret = read(control_device_fd, buf, OCFS2_CONTROL_PROTO_LEN);
2086
if (ret == OCFS2_CONTROL_PROTO_LEN) {
2087
if (!found && !strcmp(buf,
2088
OCFS2_CONTROL_PROTO))
2096
err = O2CB_ET_SERVICE_UNAVAILABLE; /* no match */
2103
ret = write(control_device_fd, OCFS2_CONTROL_PROTO,
2104
OCFS2_CONTROL_PROTO_LEN);
2105
if (ret != OCFS2_CONTROL_PROTO_LEN) {
2110
snprintf(buf, OCFS2_CONTROL_MESSAGE_SETNODE_TOTAL_LEN + 1,
2111
OCFS2_CONTROL_MESSAGE_SETNODE_OP " %08X\n", this_node);
2112
ret = write(control_device_fd, buf,
2113
OCFS2_CONTROL_MESSAGE_SETNODE_TOTAL_LEN);
2114
if (ret != OCFS2_CONTROL_MESSAGE_SETNODE_TOTAL_LEN)
2117
snprintf(buf, OCFS2_CONTROL_MESSAGE_SETVERSION_TOTAL_LEN + 1,
2118
OCFS2_CONTROL_MESSAGE_SETVERSION_OP " %02X %02X\n",
2119
proto->pv_major, proto->pv_minor);
2120
ret = write(control_device_fd, buf,
2121
OCFS2_CONTROL_MESSAGE_SETVERSION_TOTAL_LEN);
2122
if (ret != OCFS2_CONTROL_MESSAGE_SETVERSION_TOTAL_LEN)
2129
errcode_t o2cb_control_open(unsigned int this_node,
2130
struct ocfs2_protocol_version *proto)
2135
if (!current_stack) {
2136
err = O2CB_ET_SERVICE_UNAVAILABLE;
2140
if (control_device_fd != -1)
2143
rc = open(CONTROL_DEVICE, O_RDWR);
2147
err = O2CB_ET_INTERNAL_FAILURE;
2153
err = O2CB_ET_SERVICE_UNAVAILABLE;
2159
err = O2CB_ET_PERMISSION_DENIED;
2165
control_device_fd = rc;
2167
err = o2cb_control_handshake(this_node, proto);
2169
close(control_device_fd);
2170
control_device_fd = -1;
2177
void o2cb_control_close(void)
2179
if (control_device_fd != -1) {
2180
close(control_device_fd);
2181
control_device_fd = -1;
2185
errcode_t o2cb_control_node_down(const char *uuid, unsigned int nodeid)
2189
char buf[OCFS2_CONTROL_MESSAGE_DOWN_TOTAL_LEN + 1];
2191
if (control_device_fd == -1)
2192
return O2CB_ET_INTERNAL_FAILURE;
2194
snprintf(buf, OCFS2_CONTROL_MESSAGE_DOWN_TOTAL_LEN + 1,
2195
"DOWN %.32s %08X\n", uuid, nodeid);
2196
ret = write(control_device_fd, buf,
2197
OCFS2_CONTROL_MESSAGE_DOWN_TOTAL_LEN);
2198
if (ret != OCFS2_CONTROL_MESSAGE_DOWN_TOTAL_LEN)
1309
2204
errcode_t o2cb_get_hb_ctl_path(char *buf, int count)