1 #include <config.h>
2
3 #include "viralloc.h"
4 #include "virerror.h"
5 #include "virfile.h"
6 #include "storage_backend_vstorage.h"
7 #include "virlog.h"
8 #include "virstring.h"
9 #include "virutil.h"
10 #include <mntent.h>
11 #include <paths.h>
12 #include <pwd.h>
13 #include <grp.h>
14 #include <unistd.h>
15 #include "storage_util.h"
16
17 #define VIR_FROM_THIS VIR_FROM_STORAGE
18
19 VIR_LOG_INIT("storage.storage_backend_vstorage");
20
21
22 /**
23 * @pool storage pool to build
24 * @flags controls the pool formatting behaviour
25 *
26 * Does not support @flags, if provided an error will occur.
27 *
28 * Returns 0 on success, -1 on error
29 */
30 static int
virStorageBackendVzPoolBuild(virStoragePoolObj * pool,unsigned int flags)31 virStorageBackendVzPoolBuild(virStoragePoolObj *pool,
32 unsigned int flags)
33 {
34 virCheckFlags(0, -1);
35
36 return virStorageBackendBuildLocal(pool);
37 }
38
39
40 static int
virStorageBackendVzPoolStart(virStoragePoolObj * pool)41 virStorageBackendVzPoolStart(virStoragePoolObj *pool)
42 {
43 virStoragePoolDef *def = virStoragePoolObjGetDef(pool);
44 g_autofree char *grp_name = NULL;
45 g_autofree char *usr_name = NULL;
46 g_autofree char *mode = NULL;
47 g_autoptr(virCommand) cmd = NULL;
48 int ret;
49
50 /* Check the permissions */
51 if (def->target.perms.mode == (mode_t)-1)
52 def->target.perms.mode = VIR_STORAGE_DEFAULT_POOL_PERM_MODE;
53 if (def->target.perms.uid == (uid_t)-1)
54 def->target.perms.uid = geteuid();
55 if (def->target.perms.gid == (gid_t)-1)
56 def->target.perms.gid = getegid();
57
58 /* Convert ids to names because vstorage uses names */
59
60 if (!(grp_name = virGetGroupName(def->target.perms.gid)))
61 return -1;
62
63 if (!(usr_name = virGetUserName(def->target.perms.uid)))
64 return -1;
65
66 mode = g_strdup_printf("%o", def->target.perms.mode);
67
68 cmd = virCommandNewArgList("vstorage-mount",
69 "-c", def->source.name,
70 def->target.path,
71 "-m", mode,
72 "-g", grp_name, "-u", usr_name,
73 NULL);
74
75 /* Mounting a shared FS might take a long time. Don't hold
76 * the pool locked meanwhile. */
77 virObjectUnlock(pool);
78 ret = virCommandRun(cmd, NULL);
79 virObjectLock(pool);
80
81 return ret;
82 }
83
84
85 static int
virStorageBackendVzIsMounted(virStoragePoolObj * pool)86 virStorageBackendVzIsMounted(virStoragePoolObj *pool)
87 {
88 int ret = -1;
89 virStoragePoolDef *def = virStoragePoolObjGetDef(pool);
90 FILE *mtab;
91 struct mntent ent;
92 char buf[1024];
93 g_autofree char *cluster = NULL;
94
95 cluster = g_strdup_printf("vstorage://%s", def->source.name);
96
97 if ((mtab = fopen(_PATH_MOUNTED, "r")) == NULL) {
98 virReportSystemError(errno,
99 _("cannot read mount list '%s'"),
100 _PATH_MOUNTED);
101 goto cleanup;
102 }
103
104 while ((getmntent_r(mtab, &ent, buf, sizeof(buf))) != NULL) {
105
106 if (STREQ(ent.mnt_dir, def->target.path) &&
107 STREQ(ent.mnt_fsname, cluster)) {
108 ret = 1;
109 goto cleanup;
110 }
111 }
112
113 ret = 0;
114
115 cleanup:
116 VIR_FORCE_FCLOSE(mtab);
117 return ret;
118 }
119
120
121 static int
virStorageBackendVzPoolStop(virStoragePoolObj * pool)122 virStorageBackendVzPoolStop(virStoragePoolObj *pool)
123 {
124 virStoragePoolDef *def = virStoragePoolObjGetDef(pool);
125 int rc;
126 g_autoptr(virCommand) cmd = NULL;
127
128 /* Short-circuit if already unmounted */
129 if ((rc = virStorageBackendVzIsMounted(pool)) != 1)
130 return rc;
131
132 cmd = virCommandNewArgList("umount", def->target.path, NULL);
133 return virCommandRun(cmd, NULL);
134 }
135
136
137 /*
138 * Check whether the cluster is mounted
139 */
140 static int
virStorageBackendVzCheck(virStoragePoolObj * pool,bool * isActive)141 virStorageBackendVzCheck(virStoragePoolObj *pool,
142 bool *isActive)
143 {
144 int ret = -1;
145 *isActive = false;
146 if ((ret = virStorageBackendVzIsMounted(pool)) != 0) {
147 if (ret < 0)
148 return -1;
149 *isActive = true;
150 }
151
152 return 0;
153 }
154
155
156 virStorageBackend virStorageBackendVstorage = {
157 .type = VIR_STORAGE_POOL_VSTORAGE,
158
159 .buildPool = virStorageBackendVzPoolBuild,
160 .startPool = virStorageBackendVzPoolStart,
161 .stopPool = virStorageBackendVzPoolStop,
162 .deletePool = virStorageBackendDeleteLocal,
163 .refreshPool = virStorageBackendRefreshLocal,
164 .checkPool = virStorageBackendVzCheck,
165 .buildVol = virStorageBackendVolBuildLocal,
166 .buildVolFrom = virStorageBackendVolBuildFromLocal,
167 .createVol = virStorageBackendVolCreateLocal,
168 .refreshVol = virStorageBackendVolRefreshLocal,
169 .deleteVol = virStorageBackendVolDeleteLocal,
170 .resizeVol = virStorageBackendVolResizeLocal,
171 .uploadVol = virStorageBackendVolUploadLocal,
172 .downloadVol = virStorageBackendVolDownloadLocal,
173 .wipeVol = virStorageBackendVolWipeLocal,
174 };
175
176
177 int
virStorageBackendVstorageRegister(void)178 virStorageBackendVstorageRegister(void)
179 {
180 return virStorageBackendRegister(&virStorageBackendVstorage);
181 }
182