glusterfs

Форк
0
/
br-stub.c 
195 строк · 3.9 Кб
1
#define _GNU_SOURCE
2

3
#include <stdio.h>
4
#include <stdlib.h>
5
#include <string.h>
6
#include <limits.h>
7
#include <unistd.h>
8
#include <fcntl.h>
9
#include <stdint.h>
10
#include <sys/types.h>
11
#include <sys/xattr.h>
12
#include <errno.h>
13

14
#include "bit-rot-object-version.h"
15

16
/* NOTE: no size discovery */
17
int
18
brstub_validate_version(char *bpath, unsigned long version)
19
{
20
    int ret = 0;
21
    int match = 0;
22
    size_t xsize = 0;
23
    br_version_t *xv = NULL;
24

25
    xsize = sizeof(br_version_t);
26

27
    xv = calloc(1, xsize);
28
    if (!xv) {
29
        match = -1;
30
        goto err;
31
    }
32

33
    ret = getxattr(bpath, "trusted.bit-rot.version", xv, xsize);
34
    if (ret < 0) {
35
        if (errno == ENODATA)
36
            match = -2;
37
        goto err;
38
    }
39

40
    if (xv->ongoingversion != version) {
41
        match = -3;
42
        fprintf(stderr, "ongoingversion: %lu\n", xv->ongoingversion);
43
    }
44
    free(xv);
45

46
err:
47
    return match;
48
}
49

50
int
51
brstub_write_validation(char *filp, char *bpath, unsigned long startversion)
52
{
53
    int fd1 = 0;
54
    int fd2 = 0;
55
    int ret = 0;
56
    char *string = "string\n";
57

58
    /* read only check */
59
    fd1 = open(filp, O_RDONLY);
60
    if (fd1 < 0)
61
        goto err;
62
    close(fd1);
63

64
    ret = brstub_validate_version(bpath, startversion);
65
    if (ret != -2)
66
        goto err;
67

68
    /* single open (write/) check */
69
    fd1 = open(filp, O_RDWR);
70
    if (fd1 < 0)
71
        goto err;
72

73
    ret = write(fd1, string, strlen(string));
74
    if (ret <= 0)
75
        goto err;
76
    /**
77
     * Fsync is done so that the write call has properly reached the
78
     * disk. For fuse mounts write-behind xlator would have held the
79
     * writes with itself and for nfs, client would have held the
80
     * write in its cache. So write fop would not have triggered the
81
     * versioning as it would have not reached the bit-rot-stub.
82
     */
83
    fsync(fd1);
84
    ret = brstub_validate_version(bpath, startversion);
85
    if (ret != 0)
86
        goto err;
87
    ret = write(fd1, string, strlen(string));
88
    if (ret <= 0)
89
        goto err;
90
    fsync(fd1); /* let it reach the disk */
91

92
    ret = brstub_validate_version(bpath, startversion);
93
    if (ret != 0)
94
        goto err;
95

96
    close(fd1);
97

98
    /**
99
     * Well, this is not a _real_ test per se . For this test to pass
100
     * the inode should not get a forget() in the interim. Therefore,
101
     * perform this test asap.
102
     */
103

104
    /* multi open (write/) check */
105
    fd1 = open(filp, O_RDWR);
106
    if (fd1 < 0)
107
        goto err;
108
    fd2 = open(filp, O_WRONLY);
109
    if (fd1 < 0)
110
        goto err;
111

112
    ret = write(fd1, string, strlen(string));
113
    if (ret <= 0)
114
        goto err;
115

116
    ret = write(fd2, string, strlen(string));
117
    if (ret <= 0)
118
        goto err;
119

120
    /* probably do a syncfs() */
121
    fsync(fd1);
122
    fsync(fd2);
123

124
    close(fd1);
125
    close(fd2);
126

127
    /**
128
     * incremented once per write()/write().../close()/close() sequence
129
     */
130
    ret = brstub_validate_version(bpath, startversion);
131
    if (ret != 0)
132
        goto err;
133

134
    return 0;
135

136
err:
137
    return -1;
138
}
139

140
int
141
brstub_new_object_validate(char *filp, char *brick)
142
{
143
    int ret = 0;
144
    char *fname = NULL;
145
    char bpath[PATH_MAX] = {
146
        0,
147
    };
148

149
    fname = basename(filp);
150
    if (!fname)
151
        goto err;
152

153
    (void)snprintf(bpath, PATH_MAX, "%s/%s", brick, fname);
154

155
    printf("Validating initial version..\n");
156
    ret = brstub_validate_version(bpath, 2);
157
    if (ret != -2) /* version _should_ be missing */
158
        goto err;
159

160
    printf("Validating version on modifications..\n");
161
    ret = brstub_write_validation(filp, bpath, 2);
162
    if (ret < 0)
163
        goto err;
164

165
    return 0;
166

167
err:
168
    return -1;
169
}
170

171
int
172
main(int argc, char **argv)
173
{
174
    int ret = 0;
175
    char *filp = NULL;
176
    char *brick = NULL;
177

178
    if (argc != 3) {
179
        printf("Usage: %s <path> <brick>\n", argv[0]);
180
        goto err;
181
    }
182

183
    filp = argv[1];
184
    brick = argv[2];
185

186
    printf("Validating object version [%s]\n", filp);
187
    ret = brstub_new_object_validate(filp, brick);
188
    if (ret < 0)
189
        goto err;
190

191
    return 0;
192

193
err:
194
    return -1;
195
}
196

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

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

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

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