Line data Source code
1 : #include <stdlib.h>
2 : #include <string.h>
3 : #include <stdio.h>
4 : #include <unistd.h>
5 : #include <sys/file.h>
6 : #include <sys/types.h>
7 : #include <sys/stat.h>
8 : #include <sys/mount.h>
9 : #include <fcntl.h>
10 : #include <errno.h>
11 : #include <signal.h>
12 : #include <mntent.h>
13 : #include <libintl.h>
14 : #include <locale.h>
15 : #define _(String) gettext(String)
16 :
17 : #include "metafs.h"
18 :
19 : int metafs_interrupted;
20 :
21 0 : static int lock_for_admin(struct metafs *mfs, int debug)
22 : {
23 : int error;
24 :
25 0 : if (debug)
26 0 : printf(_("Trying to get admin lock..."));
27 :
28 0 : mfs->fd = open(mfs->path, O_RDONLY | O_NOFOLLOW);
29 0 : if (mfs->fd < 0)
30 0 : return -1;
31 :
32 0 : error = flock(mfs->fd, LOCK_EX);
33 0 : if (error) {
34 0 : close(mfs->fd);
35 0 : return -1;
36 : }
37 0 : if (debug)
38 0 : printf(_("locked.\n"));
39 0 : return 0;
40 : }
41 :
42 0 : static void sighandler(int error)
43 : {
44 0 : metafs_interrupted = 1;
45 0 : }
46 :
47 0 : static void setsigs(void (*handler)(int))
48 : {
49 0 : struct sigaction sa = { .sa_handler = handler };
50 :
51 0 : sigaction(SIGINT, &sa, NULL);
52 0 : sigaction(SIGILL, &sa, NULL);
53 0 : sigaction(SIGTERM, &sa, NULL);
54 0 : sigaction(SIGHUP, &sa, NULL);
55 0 : sigaction(SIGABRT, &sa, NULL);
56 0 : sigaction(SIGCONT, &sa, NULL);
57 0 : sigaction(SIGUSR1, &sa, NULL);
58 0 : sigaction(SIGUSR2, &sa, NULL);
59 0 : }
60 :
61 0 : int mount_gfs2_meta(struct metafs *mfs, const char *path, int debug)
62 : {
63 : int ret;
64 :
65 0 : mfs->path = strdup("/tmp/.gfs2meta.XXXXXX");
66 0 : if (mfs->path == NULL)
67 0 : return -1;
68 :
69 0 : if(!mkdtemp(mfs->path))
70 0 : goto err_free;
71 :
72 0 : setsigs(sighandler);
73 :
74 0 : ret = mount(path, mfs->path, "gfs2meta", 0, mfs->context);
75 0 : if (ret)
76 0 : goto err_rmdir;
77 :
78 0 : if (lock_for_admin(mfs, debug))
79 0 : goto err_umount;
80 :
81 0 : return 0;
82 :
83 0 : err_umount:
84 0 : if (umount(mfs->path))
85 : /* Translators: the first %s here is a path, the second is an error message */
86 0 : fprintf(stderr, _("Could not unmount %s: %s\n"),
87 0 : mfs->path, strerror(errno));
88 0 : setsigs(SIG_DFL);
89 0 : err_rmdir:
90 0 : rmdir(mfs->path);
91 0 : err_free:
92 0 : free(mfs->path);
93 0 : mfs->path = NULL;
94 0 : return -1;
95 : }
96 :
97 0 : void cleanup_metafs(struct metafs *mfs)
98 : {
99 : int ret;
100 :
101 0 : if (mfs->fd <= 0)
102 0 : return;
103 :
104 0 : fsync(mfs->fd);
105 0 : close(mfs->fd);
106 0 : ret = umount(mfs->path);
107 0 : if (ret)
108 : /* Translators: the first %s here is a path, the second is an error message */
109 0 : fprintf(stderr, "Could not unmount %s : %s\n",
110 0 : mfs->path, strerror(errno));
111 : else
112 0 : rmdir(mfs->path);
113 :
114 0 : setsigs(SIG_DFL);
115 0 : metafs_interrupted = 0;
116 :
117 0 : free(mfs->path);
118 0 : mfs->path = NULL;
119 0 : free(mfs->context);
120 0 : mfs->context = NULL;
121 : }
122 :
123 : /**
124 : * Returns a duplicate of the 'context' mount option, or NULL if not found.
125 : */
126 0 : char *copy_context_opt(struct mntent *mnt)
127 : {
128 : char *ctx, *end;
129 :
130 0 : ctx = hasmntopt(mnt, "context");
131 0 : if (ctx == NULL)
132 0 : return NULL;
133 :
134 0 : end = strchr(ctx, ',');
135 0 : if (end == NULL)
136 0 : return NULL;
137 :
138 0 : return strndup(ctx, end - ctx);
139 : }
|