]> git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/storage/rbd.c
storage: s/MAXPATHLEN/PATH_MAX/g
[mirror_lxc.git] / src / lxc / storage / rbd.c
1 /*
2 * lxc: linux Container library
3 *
4 * (C) Copyright IBM Corp. 2007, 2008
5 *
6 * Authors:
7 * Daniel Lezcano <daniel.lezcano at free.fr>
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24 #ifndef _GNU_SOURCE
25 #define _GNU_SOURCE 1
26 #endif
27 #define __STDC_FORMAT_MACROS /* Required for PRIu64 to work. */
28 #include <inttypes.h> /* Required for PRIu64 to work. */
29 #include <stdint.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33
34 #include "config.h"
35 #include "log.h"
36 #include "storage.h"
37 #include "storage_utils.h"
38 #include "utils.h"
39
40 #ifndef HAVE_STRLCPY
41 #include "include/strlcpy.h"
42 #endif
43
44 lxc_log_define(rbd, lxc);
45
46 struct rbd_args {
47 const char *osd_pool_name;
48 const char *rbd_name;
49 const char *size;
50 };
51
52 int rbd_create_wrapper(void *data)
53 {
54 struct rbd_args *args = data;
55
56 execlp("rbd", "rbd", "create", "--pool", args->osd_pool_name,
57 args->rbd_name, "--size", args->size, (char *)NULL);
58
59 return -1;
60 }
61
62 int rbd_map_wrapper(void *data)
63 {
64 struct rbd_args *args = data;
65
66 execlp("rbd", "rbd", "map", "--pool", args->osd_pool_name,
67 args->rbd_name, (char *)NULL);
68
69 return -1;
70 }
71
72 int rbd_unmap_wrapper(void *data)
73 {
74 struct rbd_args *args = data;
75
76 execlp("rbd", "rbd", "unmap", args->rbd_name, (char *)NULL);
77
78 return -1;
79 }
80
81 int rbd_delete_wrapper(void *data)
82 {
83 struct rbd_args *args = data;
84
85 execlp("rbd", "rbd", "rm", args->rbd_name, (char *)NULL);
86
87 return -1;
88 }
89
90 int rbd_clonepaths(struct lxc_storage *orig, struct lxc_storage *new,
91 const char *oldname, const char *cname, const char *oldpath,
92 const char *lxcpath, int snap, uint64_t newsize,
93 struct lxc_conf *conf)
94 {
95 ERROR("rbd clonepaths not implemented");
96 return -1;
97 }
98
99 int rbd_create(struct lxc_storage *bdev, const char *dest, const char *n,
100 struct bdev_specs *specs)
101 {
102 const char *rbdpool, *fstype;
103 uint64_t size;
104 int ret, len;
105 char sz[24];
106 const char *cmd_args[2];
107 char cmd_output[PATH_MAX];
108 const char *rbdname = n;
109 struct rbd_args args = {0};
110
111 if (!specs)
112 return -1;
113
114 rbdpool = specs->rbd.rbdpool;
115 if (!rbdpool)
116 rbdpool = lxc_global_config_value("lxc.bdev.rbd.rbdpool");
117
118 if (specs->rbd.rbdname)
119 rbdname = specs->rbd.rbdname;
120
121 /* source device /dev/rbd/lxc/ctn */
122 len = strlen(rbdpool) + strlen(rbdname) + 4 + 11;
123 bdev->src = malloc(len);
124 if (!bdev->src) {
125 ERROR("Failed to allocate memory");
126 return -1;
127 }
128
129 ret = snprintf(bdev->src, len, "rbd:/dev/rbd/%s/%s", rbdpool, rbdname);
130 if (ret < 0 || ret >= len) {
131 ERROR("Failed to create string");
132 return -1;
133 }
134
135 /* fssize is in bytes */
136 size = specs->fssize;
137 if (!size)
138 size = DEFAULT_FS_SIZE;
139
140 /* in megabytes for rbd tool */
141 ret = snprintf(sz, 24, "%" PRIu64, size / 1024 / 1024);
142 if (ret < 0 || ret >= 24) {
143 ERROR("Failed to create string");
144 return -1;
145 }
146
147 args.osd_pool_name = rbdpool;
148 args.rbd_name = rbdname;
149 args.size = sz;
150 ret = run_command(cmd_output, sizeof(cmd_output), rbd_create_wrapper,
151 (void *)&args);
152 if (ret < 0) {
153 ERROR("Failed to create rbd storage volume \"%s\": %s", rbdname,
154 cmd_output);
155 return -1;
156 }
157
158 ret = run_command(cmd_output, sizeof(cmd_output), rbd_map_wrapper,
159 (void *)&args);
160 if (ret < 0) {
161 ERROR("Failed to map rbd storage volume \"%s\": %s", rbdname,
162 cmd_output);
163 return -1;
164 }
165
166 fstype = specs->fstype;
167 if (!fstype)
168 fstype = DEFAULT_FSTYPE;
169
170 cmd_args[0] = fstype;
171 cmd_args[1] = lxc_storage_get_path(bdev->src, bdev->type);
172 ret = run_command(cmd_output, sizeof(cmd_output), do_mkfs_exec_wrapper,
173 (void *)cmd_args);
174 if (ret < 0) {
175 ERROR("Failed to map rbd storage volume \"%s\": %s", rbdname,
176 cmd_output);
177 return -1;
178 }
179
180 bdev->dest = strdup(dest);
181 if (!bdev->dest) {
182 ERROR("Failed to duplicate string \"%s\"", dest);
183 return -1;
184 }
185
186 ret = mkdir_p(bdev->dest, 0755);
187 if (ret < 0 && errno != EEXIST) {
188 ERROR("Failed to create directory \"%s\"", bdev->dest);
189 return -1;
190 }
191
192 TRACE("Created rbd storage volume \"%s\"", bdev->dest);
193 return 0;
194 }
195
196 int rbd_destroy(struct lxc_storage *orig)
197 {
198 int ret;
199 const char *src;
200 char *rbdfullname;
201 char cmd_output[PATH_MAX];
202 struct rbd_args args = {0};
203 size_t len;
204
205 src = lxc_storage_get_path(orig->src, orig->type);
206 if (file_exists(src)) {
207 args.rbd_name = src;
208 ret = run_command(cmd_output, sizeof(cmd_output),
209 rbd_unmap_wrapper, (void *)&args);
210 if (ret < 0) {
211 ERROR("Failed to map rbd storage volume \"%s\": %s",
212 src, cmd_output);
213 return -1;
214 }
215 }
216
217 len = strlen(src);
218 rbdfullname = alloca(len - 8);
219 (void)strlcpy(rbdfullname, &src[9], len - 8);
220 args.rbd_name = rbdfullname;
221
222 ret = run_command(cmd_output, sizeof(cmd_output),
223 rbd_delete_wrapper, (void *)&args);
224 if (ret < 0) {
225 ERROR("Failed to delete rbd storage volume \"%s\": %s",
226 rbdfullname, cmd_output);
227 return -1;
228 }
229
230 return 0;
231 }
232
233 bool rbd_detect(const char *path)
234 {
235 if (!strncmp(path, "rbd:", 4))
236 return true;
237
238 if (!strncmp(path, "/dev/rbd/", 9))
239 return true;
240
241 return false;
242 }
243
244 int rbd_mount(struct lxc_storage *bdev)
245 {
246 const char *src;
247
248 if (strcmp(bdev->type, "rbd"))
249 return -22;
250
251 if (!bdev->src || !bdev->dest)
252 return -22;
253
254 src = lxc_storage_get_path(bdev->src, bdev->type);
255 if (!file_exists(src)) {
256 /* If blkdev does not exist it should be mapped, because it is
257 * not persistent on reboot.
258 */
259 ERROR("Block device %s is not mapped.", bdev->src);
260 return -1;
261 }
262
263 return mount_unknown_fs(src, bdev->dest, bdev->mntopts);
264 }
265
266 int rbd_umount(struct lxc_storage *bdev)
267 {
268 if (strcmp(bdev->type, "rbd"))
269 return -22;
270
271 if (!bdev->src || !bdev->dest)
272 return -22;
273
274 return umount(bdev->dest);
275 }