summaryrefslogtreecommitdiffstats
path: root/extras/geo-rep/gsync-sync-gfid.c
blob: 601f4720e251578c99207ef137d42872710aaab9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <limits.h>
#include <sys/types.h>
#include <attr/xattr.h>
#include <libgen.h>
#include <ctype.h>
#include <stdlib.h>

#ifndef UUID_CANONICAL_FORM_LEN
#define UUID_CANONICAL_FORM_LEN 36
#endif

#ifndef GF_FUSE_AUX_GFID_HEAL
#define GF_FUSE_AUX_GFID_HEAL    "glusterfs.gfid.heal"
#endif

#define GLFS_LINE_MAX           (PATH_MAX + (2 * UUID_CANONICAL_FORM_LEN))

int
main (int argc, char *argv[])
{
        char *file                = NULL;
        char *tmp = NULL;
        char *tmp1 = NULL;
        char *parent_dir = NULL;
        char *gfid                = NULL;
        char *bname = NULL;
        int   ret                 = -1;
        int len = 0;
        FILE *fp                  = NULL;
        char  line[GLFS_LINE_MAX] = {0,};
        char *path = NULL;
        void  *blob               = NULL;
        void  *tmp_blob               = NULL;

        if (argc != 2) {
                /* each line in the file has the following format
                 * uuid-in-canonical-form path-relative-to-gluster-mount.
                 * Both uuid and relative path are from master mount.
                 */
                fprintf (stderr, "usage: %s <file-of-paths-to-be-synced>\n",
                         argv[0]);
                goto out;
        }

        file = argv[1];

        fp = fopen (file, "r");
        if (fp == NULL) {
                fprintf (stderr, "cannot open %s for reading (%s)\n",
                         file, strerror (errno));
                goto out;
        }

        while (fgets (line, GLFS_LINE_MAX, fp) != NULL) {
                tmp = line;
                path = gfid = line;

                path += UUID_CANONICAL_FORM_LEN + 1;

                while(isspace (*path))
                        path++;

                if ((strlen (line) < GLFS_LINE_MAX) &&
                    (line[strlen (line) - 1] == '\n'))
                        line[strlen (line) - 1] = '\0';

                line[UUID_CANONICAL_FORM_LEN] = '\0';

                tmp = strdup (path);
                tmp1 = strdup (path);
                parent_dir = dirname (tmp);
                bname = basename (tmp1);

                /* gfid + '\0' + bname + '\0' */
                len = UUID_CANONICAL_FORM_LEN + 1 + strlen (bname) + 1;

                blob = calloc (1, len);

                memcpy (blob, gfid, UUID_CANONICAL_FORM_LEN);

                tmp_blob = blob + UUID_CANONICAL_FORM_LEN + 1;

                memcpy (tmp_blob, bname, strlen (bname));

                ret = setxattr (parent_dir, GF_FUSE_AUX_GFID_HEAL, blob, len,
                                0);
                if (ret < 0) {
                        fprintf (stderr, "setxattr on %s/%s failed (%s)\n",
                                 parent_dir, bname, strerror (errno));
                }
                memset (line, 0, GLFS_LINE_MAX);

                free (blob);
                free (tmp); free (tmp1);
                blob = NULL;
        }

        ret = 0;
out:
        return ret;
}