]> git.proxmox.com Git - mirror_lxc.git/blame - src/lxc/storage/rbd.c
tree-wide: struct bdev -> struct lxc_storage
[mirror_lxc.git] / src / lxc / storage / rbd.c
CommitLineData
3ceb2820
CB
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#define _GNU_SOURCE
25#define __STDC_FORMAT_MACROS /* Required for PRIu64 to work. */
7b22b3e9 26#include <inttypes.h> /* Required for PRIu64 to work. */
3ceb2820
CB
27#include <stdint.h>
28#include <stdio.h>
29#include <stdlib.h>
30#include <string.h>
31
3ceb2820 32#include "log.h"
28d832c4 33#include "storage.h"
f2d5a09d 34#include "storage_utils.h"
3ceb2820
CB
35#include "utils.h"
36
10bc1861 37lxc_log_define(rbd, lxc);
3ceb2820 38
3b0e906f
CB
39struct rbd_args {
40 const char *osd_pool_name;
41 const char *rbd_name;
42 const char *size;
43};
44
45int rbd_create_wrapper(void *data)
46{
47 struct rbd_args *args = data;
48
49 execlp("rbd", "rbd", "create", "--pool", args->osd_pool_name,
50 args->rbd_name, "--size", args->size, (char *)NULL);
51
52 return -1;
53}
54
55int rbd_map_wrapper(void *data)
56{
57 struct rbd_args *args = data;
58
59 execlp("rbd", "rbd", "map", "--pool", args->osd_pool_name,
60 args->rbd_name, (char *)NULL);
61
62 return -1;
63}
64
65int rbd_unmap_wrapper(void *data)
66{
67 struct rbd_args *args = data;
68
69 execlp("rbd", "rbd", "unmap", args->rbd_name, (char *)NULL);
70
71 return -1;
72}
73
74int rbd_delete_wrapper(void *data)
75{
76 struct rbd_args *args = data;
77
78 execlp("rbd", "rbd", "rm", args->rbd_name, (char *)NULL);
79
80 return -1;
81}
82
10bc1861
CB
83int rbd_clonepaths(struct lxc_storage *orig, struct lxc_storage *new,
84 const char *oldname, const char *cname, const char *oldpath,
85 const char *lxcpath, int snap, uint64_t newsize,
86 struct lxc_conf *conf)
3ceb2820
CB
87{
88 ERROR("rbd clonepaths not implemented");
89 return -1;
90}
91
10bc1861 92int rbd_create(struct lxc_storage *bdev, const char *dest, const char *n,
7b22b3e9 93 struct bdev_specs *specs)
3ceb2820 94{
3b0e906f 95 const char *rbdpool, *fstype;
3ceb2820
CB
96 uint64_t size;
97 int ret, len;
98 char sz[24];
a5b18cb1
CB
99 const char *cmd_args[2];
100 char cmd_output[MAXPATHLEN];
3b0e906f
CB
101 const char *rbdname = n;
102 struct rbd_args args = {0};
3ceb2820
CB
103
104 if (!specs)
105 return -1;
106
107 rbdpool = specs->rbd.rbdpool;
108 if (!rbdpool)
109 rbdpool = lxc_global_config_value("lxc.bdev.rbd.rbdpool");
110
111 if (specs->rbd.rbdname)
112 rbdname = specs->rbd.rbdname;
113
114 /* source device /dev/rbd/lxc/ctn */
43bd0ebf 115 len = strlen(rbdpool) + strlen(rbdname) + 4 + 11;
3ceb2820 116 bdev->src = malloc(len);
3b0e906f
CB
117 if (!bdev->src) {
118 ERROR("Failed to allocate memory");
3ceb2820 119 return -1;
3b0e906f 120 }
3ceb2820 121
43bd0ebf 122 ret = snprintf(bdev->src, len, "rbd:/dev/rbd/%s/%s", rbdpool, rbdname);
3b0e906f
CB
123 if (ret < 0 || ret >= len) {
124 ERROR("Failed to create string");
3ceb2820 125 return -1;
3b0e906f 126 }
3ceb2820 127
7b22b3e9 128 /* fssize is in bytes */
3ceb2820
CB
129 size = specs->fssize;
130 if (!size)
131 size = DEFAULT_FS_SIZE;
132
7b22b3e9
CB
133 /* in megabytes for rbd tool */
134 ret = snprintf(sz, 24, "%" PRIu64, size / 1024 / 1024);
3b0e906f
CB
135 if (ret < 0 || ret >= 24) {
136 ERROR("Failed to create string");
3ceb2820 137 return -1;
3ceb2820 138 }
3ceb2820 139
3b0e906f
CB
140 args.osd_pool_name = rbdpool;
141 args.rbd_name = rbdname;
142 args.size = sz;
143 ret = run_command(cmd_output, sizeof(cmd_output), rbd_create_wrapper,
144 (void *)&args);
145 if (ret < 0) {
146 ERROR("Failed to create rbd storage volume \"%s\": %s", rbdname,
147 cmd_output);
3ceb2820 148 return -1;
3ceb2820 149 }
3b0e906f
CB
150
151 ret = run_command(cmd_output, sizeof(cmd_output), rbd_map_wrapper,
152 (void *)&args);
153 if (ret < 0) {
154 ERROR("Failed to map rbd storage volume \"%s\": %s", rbdname,
155 cmd_output);
3ceb2820 156 return -1;
3b0e906f 157 }
3ceb2820
CB
158
159 fstype = specs->fstype;
160 if (!fstype)
161 fstype = DEFAULT_FSTYPE;
162
a5b18cb1 163 cmd_args[0] = fstype;
3b0e906f 164 cmd_args[1] = lxc_storage_get_path(bdev->src, bdev->type);
a5b18cb1
CB
165 ret = run_command(cmd_output, sizeof(cmd_output), do_mkfs_exec_wrapper,
166 (void *)cmd_args);
3b0e906f
CB
167 if (ret < 0) {
168 ERROR("Failed to map rbd storage volume \"%s\": %s", rbdname,
169 cmd_output);
3ceb2820 170 return -1;
3b0e906f 171 }
a5b18cb1 172
3b0e906f
CB
173 bdev->dest = strdup(dest);
174 if (!bdev->dest) {
175 ERROR("Failed to duplicate string \"%s\"", dest);
3ceb2820 176 return -1;
3b0e906f 177 }
3ceb2820 178
3b0e906f
CB
179 ret = mkdir_p(bdev->dest, 0755);
180 if (ret < 0 && errno != EEXIST) {
181 ERROR("Failed to create directory \"%s\"", bdev->dest);
3ceb2820
CB
182 return -1;
183 }
184
3b0e906f 185 TRACE("Created rbd storage volume \"%s\"", bdev->dest);
3ceb2820
CB
186 return 0;
187}
188
10bc1861 189int rbd_destroy(struct lxc_storage *orig)
3ceb2820 190{
3b0e906f 191 int ret;
43bd0ebf 192 char *src;
3ceb2820 193 char *rbdfullname;
3b0e906f
CB
194 char cmd_output[MAXPATHLEN];
195 struct rbd_args args = {0};
3ceb2820 196
43bd0ebf
CB
197 src = lxc_storage_get_path(orig->src, orig->type);
198 if (file_exists(src)) {
3b0e906f
CB
199 args.rbd_name = src;
200 ret = run_command(cmd_output, sizeof(cmd_output),
201 rbd_unmap_wrapper, (void *)&args);
202 if (ret < 0) {
203 ERROR("Failed to map rbd storage volume \"%s\": %s",
204 src, cmd_output);
3ceb2820 205 return -1;
3ceb2820 206 }
3ceb2820
CB
207 }
208
3b0e906f
CB
209 rbdfullname = alloca(strlen(src) - 8);
210 strcpy(rbdfullname, &src[9]);
211 args.rbd_name = rbdfullname;
212 ret = run_command(cmd_output, sizeof(cmd_output),
213 rbd_delete_wrapper, (void *)&args);
214 if (ret < 0) {
215 ERROR("Failed to delete rbd storage volume \"%s\": %s",
216 rbdfullname, cmd_output);
3ceb2820 217 return -1;
3ceb2820 218 }
3b0e906f
CB
219
220 return 0;
3ceb2820
CB
221}
222
3d2ae1e2 223bool rbd_detect(const char *path)
3ceb2820 224{
f7ac4459 225 if (!strncmp(path, "rbd:", 4))
3d2ae1e2 226 return true;
f7ac4459
CB
227
228 if (!strncmp(path, "/dev/rbd/", 9))
3d2ae1e2 229 return true;
f7ac4459 230
3d2ae1e2 231 return false;
3ceb2820
CB
232}
233
10bc1861 234int rbd_mount(struct lxc_storage *bdev)
3ceb2820 235{
43bd0ebf 236 char *src;
3b0e906f 237
3ceb2820
CB
238 if (strcmp(bdev->type, "rbd"))
239 return -22;
43bd0ebf 240
3ceb2820
CB
241 if (!bdev->src || !bdev->dest)
242 return -22;
243
43bd0ebf
CB
244 src = lxc_storage_get_path(bdev->src, bdev->type);
245 if (!file_exists(src)) {
7b22b3e9
CB
246 /* If blkdev does not exist it should be mapped, because it is
247 * not persistent on reboot.
248 */
3ceb2820
CB
249 ERROR("Block device %s is not mapped.", bdev->src);
250 return -1;
251 }
252
3b0e906f 253 return mount_unknown_fs(src, bdev->dest, bdev->mntopts);
3ceb2820
CB
254}
255
10bc1861 256int rbd_umount(struct lxc_storage *bdev)
3ceb2820
CB
257{
258 if (strcmp(bdev->type, "rbd"))
259 return -22;
43bd0ebf 260
3ceb2820
CB
261 if (!bdev->src || !bdev->dest)
262 return -22;
43bd0ebf 263
3ceb2820
CB
264 return umount(bdev->dest);
265}