glusterfs

Форк
0
/
mandatory-lock-forced.c 
143 строки · 3.8 Кб
1
#include <stdio.h>
2
#include <fcntl.h>
3
#include <errno.h>
4
#include <unistd.h>
5
#include <stdlib.h>
6
#include <string.h>
7
#include <sys/wait.h>
8

9
#define LOG_ERR(func, err)                                                     \
10
    do {                                                                       \
11
        fprintf(stderr, "%s : returned error (%s)\n", func, strerror(err));    \
12
        exit(err);                                                             \
13
    } while (0)
14

15
int fd;
16
struct flock lock;
17
char *buf = "ten bytes!";
18
char *fname = "/mnt/glusterfs/0/mand.lock";
19
int open_flags, child, err, status, blocked = 0;
20

21
int
22
do_child(char *argv[])
23
{
24
    /* Initialize file open flags */
25
    if (strcmp(argv[2], "BLOCK") == 0)
26
        open_flags = O_RDWR;
27
    else if (strcmp(argv[2], "TRUNC") == 0)
28
        open_flags = O_RDWR | O_TRUNC | O_NONBLOCK;
29
    else if (strcmp(argv[2], "NONE") == 0)
30
        open_flags = O_RDWR | O_NONBLOCK;
31
    else
32
        LOG_ERR("Invalid option:", EINVAL);
33

34
    /* Open the file */
35
    fd = open(fname, open_flags);
36
    if (fd == -1)
37
        LOG_ERR("Child open", errno);
38

39
    /* Perform the file operation*/
40
    if (strcmp(argv[3], "READ") == 0) {
41
        buf = NULL;
42
        err = read(fd, buf, 10);
43
        if (err == -1)
44
            LOG_ERR("Child read", errno);
45
    } else if (strcmp(argv[3], "WRITE") == 0) {
46
        err = write(fd, buf, 10);
47
        if (err == -1)
48
            LOG_ERR("Child write", errno);
49
    } else if (strcmp(argv[3], "FTRUNCATE") == 0) {
50
        err = ftruncate(fd, 5);
51
        if (err)
52
            LOG_ERR("Child ftruncate", errno);
53
    } else
54
        LOG_ERR("Invalid operation:", EINVAL);
55

56
    /* Close child fd */
57
    err = close(fd);
58
    if (err)
59
        LOG_ERR("Child close", errno);
60

61
    /* Exit success */
62
    exit(0);
63
}
64

65
int
66
main(int argc, char *argv[])
67
{
68
    if (argc < 4) {
69
        fprintf(stderr,
70
                "Wrong usage: Use as ./mandatory-lock "
71
                "<RD_LCK/WR_LCK> <BLOCK/TRUNC/NONE> "
72
                "<READ/WRITE/FTRUNCATE\n");
73
        exit(EINVAL);
74
    }
75
    /* Create an empty lock file */
76
    fd = open(fname, O_CREAT | O_RDWR, 0755);
77
    if (fd == -1)
78
        LOG_ERR("Parent create", errno);
79

80
    /* Determine the type of lock */
81
    if (strcmp(argv[1], "RD_LCK") == 0)
82
        lock.l_type = F_RDLCK;
83
    else if (strcmp(argv[1], "WR_LCK") == 0)
84
        lock.l_type = F_WRLCK;
85
    else
86
        LOG_ERR("Parent lock type", EINVAL);
87

88
    lock.l_whence = SEEK_SET;
89
    lock.l_start = 0L;
90
    lock.l_len = 0L;
91

92
    /* Let parent acquire the initial lock */
93
    err = fcntl(fd, F_SETLK, &lock);
94
    if (err)
95
        LOG_ERR("Parent lock", errno);
96

97
    /* Now fork a child */
98
    child = fork();
99
    if (child == 0)
100
        /* Perform the child operations */
101
        do_child(argv);
102
    else {
103
        /* If blocking mode, then sleep for 2 seconds
104
         * and wait for the child */
105
        if (strcmp(argv[2], "NONE") != 0) {
106
            sleep(2);
107
            if (waitpid(child, &status, WNOHANG) == 0)
108
                blocked = 1;
109
            /* Release the parent lock so that the
110
             * child can terminate */
111
            lock.l_type = F_UNLCK;
112
            err = fcntl(fd, F_SETLK, &lock);
113
            if (err)
114
                LOG_ERR("Parent unlock", errno);
115
        }
116

117
        /* Wait for child to finish */
118
        waitpid(child, &status, 0);
119

120
        /* Close the parent fd */
121
        err = close(fd);
122
        if (err)
123
            LOG_ERR("Parent close", errno);
124

125
        /* Remove the lock file*/
126
        err = unlink(fname);
127
        if (err)
128
            LOG_ERR("Parent unlink", errno);
129

130
        /* If not blocked, exit with child exit status*/
131
        errno = WEXITSTATUS(status);
132

133
        /* If blocked, exit with corresponding
134
         * error code */
135
        if (blocked)
136
            errno = EWOULDBLOCK;
137

138
        if (errno != 0)
139
            printf("%s\n", strerror(errno));
140

141
        exit(errno);
142
    }
143
}
144

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

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

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

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