glusterfs

Форк
0
/
glfs-lease-recall.c 
372 строки · 10.7 Кб
1
#include <glusterfs/api/glfs.h>
2
#include <glusterfs/api/glfs-handles.h>
3
#include <errno.h>
4
#include <stdio.h>
5
#include <stdlib.h>
6
#include <string.h>
7
#include <fcntl.h>
8
#include <sys/stat.h>
9

10
/* Few rules:
11
 * 1. A client may have multiple lease keys, but a lease key cannot be shared by
12
 * multiple clients.
13
 * 2. Lease key can be set before open, or in glfs_lease request. A lease key
14
 * set like this is valid for the lifetime of the fd, i.e. a fd cannot have
15
 * multiple lease key. But a lease key can be shared across multiple fds.
16
 */
17
glfs_t *client1 = NULL, *client2 = NULL;
18
glfs_fd_t *fd1 = NULL;
19
FILE *log_file = NULL;
20
char lid1[GLFS_LEASE_ID_SIZE] = "lid1-clnt1",
21
     lid2[GLFS_LEASE_ID_SIZE] = "lid2-clnt2";
22
char lid3[GLFS_LEASE_ID_SIZE] = "lid3-clnt2", lid4[GLFS_LEASE_ID_SIZE] = {
23
                                                  0,
24
};
25
char *volname = NULL, *glfs_log_file = NULL;
26
int upcall_recv = 0;
27

28
#define MAX_CLIENTS 4
29
#define MAX_FDS 4
30
#define TEST_FILE "/test/lease"
31
#define SHUD_PASS 0
32
#define SHUD_FAIL -1
33
#define NONE 0
34

35
static void
36
recall_cbk(struct glfs_lease lease, void *data);
37

38
static int
39
set_read_lease(glfs_fd_t *fd, char ld[])
40
{
41
    struct glfs_lease lease = {
42
        0,
43
    };
44
    int ret = 0;
45

46
    memset(&lease, 0, sizeof(lease));
47
    lease.cmd = GLFS_SET_LEASE;
48
    lease.lease_type = GLFS_RD_LEASE;
49
    memcpy(&lease.lease_id, ld, GLFS_LEASE_ID_SIZE);
50
    ret = glfs_lease(fd, &lease, &recall_cbk, fd);
51
    if (ret < 0) {
52
        fprintf(log_file, "\n    RD_LEASE failed with ret: %d (%s)", ret,
53
                strerror(errno));
54
        return -1;
55
    }
56
    fprintf(log_file, "\n    Took RD_LEASE");
57
    return ret;
58
}
59

60
static int
61
set_write_lease(glfs_fd_t *fd, char ld[])
62
{
63
    struct glfs_lease lease = {
64
        0,
65
    };
66
    int ret = 0;
67

68
    memset(&lease, 0, sizeof(lease));
69
    lease.cmd = GLFS_SET_LEASE;
70
    lease.lease_type = GLFS_RW_LEASE;
71
    memcpy(&lease.lease_id, ld, GLFS_LEASE_ID_SIZE);
72
    ret = glfs_lease(fd, &lease, &recall_cbk, NULL);
73
    if (ret < 0) {
74
        fprintf(log_file, "\n    RW_LEASE failed with ret: %d (%s)", ret,
75
                strerror(errno));
76
        return -1;
77
    }
78
    fprintf(log_file, "\n    Took RW_LEASE");
79
    return ret;
80
}
81

82
static int
83
get_lease(glfs_fd_t *fd, char ld[])
84
{
85
    struct glfs_lease lease = {
86
        0,
87
    };
88
    int ret = 0;
89

90
    memset(&lease, 0, sizeof(lease));
91
    lease.cmd = GLFS_GET_LEASE;
92
    lease.lease_type = -1;
93
    memcpy(&lease.lease_id, ld, GLFS_LEASE_ID_SIZE);
94
    ret = glfs_lease(fd, &lease, &recall_cbk, NULL);
95
    if (ret < 0) {
96
        fprintf(log_file, "\n    GET_LEASE failed with ret: %d (%s)", ret,
97
                strerror(errno));
98
        return -1;
99
    }
100
    if (lease.lease_type == GLFS_RD_LEASE)
101
        fprintf(log_file, "\n    Esisting Lease: RD_LEASE");
102
    else if (lease.lease_type == GLFS_RW_LEASE)
103
        fprintf(log_file, "\n    Esisting Lease: RW_LEASE");
104
    else if (lease.lease_type == 3)
105
        fprintf(log_file, "\n    Esisting Lease: RD_LEASE|RW_LEASE");
106
    else if (lease.lease_type == 0)
107
        fprintf(log_file, "\n    Esisting Lease: NONE");
108
    else
109
        fprintf(log_file, "\n    Existing lease type:%d", lease.lease_type);
110
    return lease.lease_type;
111
}
112

113
static int
114
unlk_write_lease(glfs_fd_t *fd, char ld[])
115
{
116
    struct glfs_lease lease = {
117
        0,
118
    };
119
    int ret = 0;
120

121
    memset(&lease, 0, sizeof(lease));
122
    lease.cmd = GLFS_UNLK_LEASE;
123
    lease.lease_type = GLFS_RW_LEASE;
124
    memcpy(&lease.lease_id, ld, GLFS_LEASE_ID_SIZE);
125
    ret = glfs_lease(fd, &lease, &recall_cbk, NULL);
126
    if (ret < 0) {
127
        fprintf(log_file, "\n    Unlock RW_LESAE failed with ret: %d (%s)", ret,
128
                strerror(errno));
129
        return -1;
130
    }
131
    fprintf(log_file, "\n    Unlocked RW_LEASE");
132
    return ret;
133
}
134

135
static int
136
unlk_read_lease(glfs_fd_t *fd, char ld[])
137
{
138
    struct glfs_lease lease = {
139
        0,
140
    };
141
    int ret = 0;
142

143
    memset(&lease, 0, sizeof(lease));
144
    lease.cmd = GLFS_UNLK_LEASE;
145
    lease.lease_type = GLFS_RD_LEASE;
146
    memcpy(&lease.lease_id, ld, GLFS_LEASE_ID_SIZE);
147

148
    ret = glfs_lease(fd, &lease, &recall_cbk, NULL);
149
    if (ret < 0) {
150
        fprintf(log_file, "\n    Unlock RD_LEASE failed with ret: %d (%s)", ret,
151
                strerror(errno));
152
        return -1;
153
    }
154
    fprintf(log_file, "\n    Unlocked RD_LEASE");
155
    return ret;
156
}
157

158
void
159
up_async_lease_recall(struct glfs_upcall *up_arg, void *data)
160
{
161
    struct glfs_upcall_lease *in_arg = NULL;
162
    enum glfs_upcall_reason reason = 0;
163
    struct glfs_object *object = NULL;
164
    uint64_t flags = 0;
165
    uint64_t expire = 0;
166

167
    if (!up_arg)
168
        return;
169

170
    reason = glfs_upcall_get_reason(up_arg);
171

172
    /* Expect 'GLFS_UPCALL_RECALL_LEASE' upcall event. */
173

174
    if (reason == GLFS_UPCALL_RECALL_LEASE) {
175
        in_arg = glfs_upcall_get_event(up_arg);
176

177
        object = glfs_upcall_lease_get_object(in_arg);
178

179
        fprintf(log_file,
180
                " upcall event type - %d,"
181
                " object(%p)\n",
182
                reason, object);
183
        upcall_recv = 1;
184
    }
185

186
    glfs_free(up_arg);
187
    return;
188
}
189

190
glfs_t *
191
setup_new_client(char *volname, char *log_fileile)
192
{
193
    int ret = 0;
194
    glfs_t *fs = NULL;
195
    int up_events = GLFS_EVENT_ANY;
196

197
    fs = glfs_new(volname);
198
    if (!fs) {
199
        fprintf(log_file, "\nglfs_new: returned NULL (%s)\n", strerror(errno));
200
        goto error;
201
    }
202

203
    ret = glfs_set_volfile_server(fs, "tcp", "localhost", 24007);
204
    if (ret < 0) {
205
        fprintf(log_file, "\nglfs_set_volfile_server failed ret:%d (%s)\n", ret,
206
                strerror(errno));
207
        goto error;
208
    }
209

210
    ret = glfs_set_logging(fs, log_fileile, 7);
211
    if (ret < 0) {
212
        fprintf(log_file, "\nglfs_set_logging failed with ret: %d (%s)\n", ret,
213
                strerror(errno));
214
        goto error;
215
    }
216

217
    ret = glfs_init(fs);
218
    if (ret < 0) {
219
        fprintf(log_file, "\nglfs_init failed with ret: %d (%s)\n", ret,
220
                strerror(errno));
221
        goto error;
222
    }
223

224
    /* Register Upcalls */
225
    ret = glfs_upcall_register(fs, up_events, up_async_lease_recall, NULL);
226

227
    /* Check if the return mask contains the event */
228
    if ((ret < 0) || !(ret & GLFS_EVENT_RECALL_LEASE)) {
229
        fprintf(stderr,
230
                "glfs_upcall_register return doesn't contain"
231
                " upcall event - GLFS_EVENT_RECALL_LEASE\n");
232
        goto error;
233
    }
234

235
    return fs;
236
error:
237
    if (fs)
238
        glfs_fini(fs);
239
    return NULL;
240
}
241

242
#define OPEN(client, flags, fd, lease_id)                                      \
243
    do {                                                                       \
244
        int ret_val = 0;                                                       \
245
        ret_val = glfs_setfsleaseid(lease_id);                                 \
246
        if (ret_val) {                                                         \
247
            fprintf(log_file,                                                  \
248
                    "\nglfs_setfsleaseid failed with ret: %d (%s)\n", ret,     \
249
                    strerror(errno));                                          \
250
            return -1;                                                         \
251
        }                                                                      \
252
        fd = glfs_open(client, TEST_FILE, flags);                              \
253
        if (fd == NULL) {                                                      \
254
            fprintf(log_file, "\nglfs_open failed with ret: %d (%s)\n", ret,   \
255
                    strerror(errno));                                          \
256
            return -1;                                                         \
257
        }                                                                      \
258
    } while (0)
259

260
#define VERIFY_RESULT(test_case, ret, value)                                   \
261
    do {                                                                       \
262
        if (ret != value) {                                                    \
263
            fprintf(log_file,                                                  \
264
                    "\n    Testcase %d failed, ret = %d, value=%d\n",          \
265
                    test_case, ret, value);                                    \
266
            goto error; /*test unsuccessful*/                                  \
267
        }                                                                      \
268
        fprintf(log_file, "\n    Testcase %d Succeeded\n", test_case);         \
269
    } while (0)
270

271
static void
272
recall_cbk(struct glfs_lease lease, void *data)
273
{
274
    int ret = -1;
275
    char ld[GLFS_LEASE_ID_SIZE] = "";
276

277
    fprintf(log_file, "\nRECALL received on lease_id:(%s)", lease.lease_id);
278
    memcpy(ld, lease.lease_id, GLFS_LEASE_ID_SIZE);
279
    ret = unlk_write_lease((glfs_fd_t *)data, ld);
280
    VERIFY_RESULT(500, ret, SHUD_PASS);
281
error:
282
    return;
283
}
284

285
static int
286
testcase_recall_conflict_lease()
287
{
288
    struct glfs_object *obj = NULL;
289
    glfs_fd_t *fd1 = NULL;
290
    int ret = 0;
291
    struct glfs_lease lease = {
292
        0,
293
    };
294

295
    fprintf(log_file,
296
            "\n Basic test case for conflicting lease causing recall");
297

298
    memset(&lease, 0, sizeof(lease));
299
    lease.cmd = GLFS_SET_LEASE;
300
    lease.lease_type = GLFS_RD_LEASE;
301
    memcpy(&lease.lease_id, lid2, GLFS_LEASE_ID_SIZE);
302
    /* Open fd on client 1 in RD mode */
303
    OPEN(client1, O_RDWR, fd1, lid1);
304
    ret = set_write_lease(fd1, lid1);
305
    VERIFY_RESULT(1, ret, SHUD_PASS);
306

307
    /* reset counter */
308
    upcall_recv = 0;
309

310
    obj = glfs_h_lookupat(client2, NULL, TEST_FILE, NULL, 0);
311
    ret = glfs_h_lease(client2, obj, &lease);
312
    VERIFY_RESULT(2, ret, SHUD_FAIL);
313

314
    sleep(3);
315
    /* should recv upcall */
316
    VERIFY_RESULT(6, !upcall_recv, SHUD_PASS);
317

318
    ret = unlk_write_lease(fd1, lid1);
319
    VERIFY_RESULT(5, ret, SHUD_PASS);
320

321
    ret = glfs_h_close(obj);
322
    VERIFY_RESULT(3, ret, SHUD_PASS);
323
    ret = glfs_close(fd1);
324
    VERIFY_RESULT(4, ret, SHUD_PASS);
325

326
    return 0;
327
error:
328
    return -1;
329
}
330

331
int
332
main(int argc, char *argv[])
333
{
334
    int ret = 0;
335
    int i = 0;
336
    glfs_fd_t *fd = NULL;
337
    glfs_fd_t *fd1 = NULL;
338
    char *topdir = "topdir", *filename = "file1";
339
    char *buf = NULL;
340
    int x = 0;
341
    ssize_t xattr_size = -1;
342

343
    if (argc != 4) {
344
        fprintf(stderr,
345
                "Expect following args %s <Vol> <glfs client log file> "
346
                "<testcase log file>\n",
347
                argv[0]);
348
        return -1;
349
    }
350

351
    log_file = fopen(argv[3], "w");
352
    if (!log_file)
353
        goto error;
354

355
    volname = argv[1];
356
    glfs_log_file = argv[2];
357

358
    /* Setup 2 clients */
359
    client1 = setup_new_client(volname, glfs_log_file);
360
    client2 = setup_new_client(volname, glfs_log_file);
361

362
    ret = testcase_recall_conflict_lease();
363
    VERIFY_RESULT(101, ret, SHUD_PASS);
364

365
    glfs_fini(client1);
366
    glfs_fini(client2);
367

368
    fclose(log_file);
369
    return 0;
370
error:
371
    return -1;
372
}
373

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.