]> git.proxmox.com Git - pve-cluster.git/blob - data/src/cfs-plug-link.c
422921819192d1ad51c648ba27a24b0762c551c6
[pve-cluster.git] / data / src / cfs-plug-link.c
1 /*
2 Copyright (C) 2010 Proxmox Server Solutions GmbH
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU Affero General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Affero General Public License for more details.
13
14 You should have received a copy of the GNU Affero General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17 Author: Dietmar Maurer <dietmar@proxmox.com>
18
19 */
20
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif /* HAVE_CONFIG_H */
24
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <string.h>
28 #include <unistd.h>
29 #include <glib.h>
30 #include <sys/types.h>
31 #include <sys/stat.h>
32 #include <sys/file.h>
33 #include <fcntl.h>
34 #include <errno.h>
35 #include <dirent.h>
36
37 #include "cfs-utils.h"
38 #include "cfs-plug.h"
39 #include "status.h"
40
41 static struct cfs_operations cfs_ops;
42
43 static cfs_plug_t *cfs_plug_link_lookup_plug(cfs_plug_t *plug, char **path)
44 {
45 g_return_val_if_fail(plug != NULL, NULL);
46 g_return_val_if_fail(plug->ops == &cfs_ops, NULL);
47
48 return (!*path || !(*path)[0]) ? plug : NULL;
49 }
50
51 static int cfs_plug_link_getattr(cfs_plug_t *plug, const char *path, struct stat *stbuf)
52 {
53 g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
54 g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
55 g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
56 g_return_val_if_fail(stbuf != NULL, PARAM_CHECK_ERRNO);
57
58 cfs_debug("enter cfs_plug_link_getattr %s", path);
59
60 memset(stbuf, 0, sizeof(struct stat));
61
62 if (cfs_is_quorate()) {
63 stbuf->st_mode = S_IFLNK | 0777;
64 } else {
65 stbuf->st_mode = S_IFLNK | 0555;
66 }
67
68 stbuf->st_nlink = 1;
69
70 return 0;
71 }
72
73 static int cfs_plug_link_readlink(cfs_plug_t *plug, const char *path, char *buf, size_t max)
74 {
75 g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
76 g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
77 g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
78 g_return_val_if_fail(buf != NULL, PARAM_CHECK_ERRNO);
79
80 cfs_debug("enter cfs_plug_link_readlink %s", path);
81
82 int ret = -EACCES;
83
84 cfs_plug_link_t *lnk = (cfs_plug_link_t *)plug;
85
86 if (!lnk->symlink)
87 goto ret;
88
89 strncpy(buf, lnk->symlink, max);
90 if (max > 0)
91 buf[max - 1]= '\0';
92 ret = 0;
93
94 ret:
95 return ret;
96 }
97
98 static void cfs_plug_link_destroy(cfs_plug_t *plug)
99 {
100 g_return_if_fail(plug != NULL);
101 g_return_if_fail(plug->ops == &cfs_ops);
102
103 cfs_plug_link_t *lnk = (cfs_plug_link_t *)plug;
104
105 cfs_debug("enter cfs_plug_link_destroy %s", plug->name);
106
107 g_free(plug->name);
108
109 g_free(lnk->symlink);
110
111 g_free(plug);
112 }
113
114 static struct cfs_operations cfs_ops = {
115 .getattr = cfs_plug_link_getattr,
116 .readlink = cfs_plug_link_readlink,
117 };
118
119
120 cfs_plug_link_t *cfs_plug_link_new(const char *name, const char *symlink)
121 {
122 g_return_val_if_fail(name != NULL, NULL);
123 g_return_val_if_fail(symlink != NULL, NULL);
124
125 cfs_plug_link_t *lnk = g_new0(cfs_plug_link_t, 1);
126
127 lnk->plug.ops = &cfs_ops;
128
129 lnk->plug.lookup_plug = cfs_plug_link_lookup_plug;
130 lnk->plug.destroy_plug = cfs_plug_link_destroy;
131
132 lnk->plug.name = g_strdup(name);
133
134 lnk->symlink = g_strdup(symlink);
135
136 return lnk;
137 }
138