glusterfs
1#include <sys/file.h>2#include <stdio.h>3#include <string.h>4#include <errno.h>5#include <sys/types.h>6#include <sys/stat.h>7#include <fcntl.h>8#include <sys/wait.h>9
10#ifndef linux11#define fstat64(fd, st) fstat(fd, st)12#endif13
14int
15run_child(char *filename)16{
17int fd = -1, ret = -1;18
19fd = open(filename, O_RDWR);20if (fd < 0) {21fprintf(stderr, "open failed (%s)\n", strerror(errno));22goto out;23}24
25ret = flock(fd, LOCK_EX | LOCK_NB);26if ((ret == 0) || (errno != EWOULDBLOCK)) {27fprintf(stderr,28"no locks present, though parent has held "29"one\n");30ret = -1;31goto out;32}33
34ret = 0;35out:36return ret;37}
38
39int
40main(int argc, char *argv[])41{
42int fd = -1, ret = -1, status = 0;43char *filename = NULL, *cmd = NULL;44struct stat stbuf = {450,46};47
48if (argc != 3) {49fprintf(stderr,50"Usage: %s <filename> "51"<gluster-cmd-to-trigger-graph-switch>\n",52argv[0]);53goto out;54}55
56filename = argv[1];57cmd = argv[2];58
59fd = open(filename, O_RDWR | O_CREAT, 0);60if (fd < 0) {61fprintf(stderr, "open (%s) failed (%s)\n", filename, strerror(errno));62goto out;63}64
65ret = flock(fd, LOCK_EX);66if (ret < 0) {67fprintf(stderr, "flock failed (%s)\n", strerror(errno));68goto out;69}70
71system(cmd);72
73/* wait till graph switch completes */74ret = fstat64(fd, &stbuf);75if (ret < 0) {76fprintf(stderr, "fstat64 failure (%s)\n", strerror(errno));77goto out;78}79
80sleep(10);81
82/* By now old-graph would be disconnected and locks should be cleaned83* up if they are not migrated. Check that by trying to acquire a lock
84* on a new fd opened by another process on same file
85*/
86ret = fork();87if (ret == 0) {88ret = run_child(filename);89} else {90wait(&status);91if (WIFEXITED(status)) {92ret = WEXITSTATUS(status);93} else {94ret = 0;95}96}97
98out:99return ret;100}
101