]> git.proxmox.com Git - mirror_lxc.git/blame - src/lxc/storage/rbd.c
tree-wide: fix includes to fix bionic builds
[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
d38dd64a
CB
24#ifndef _GNU_SOURCE
25#define _GNU_SOURCE 1
26#endif
3ceb2820 27#define __STDC_FORMAT_MACROS /* Required for PRIu64 to work. */
7b22b3e9 28#include <inttypes.h> /* Required for PRIu64 to work. */
3ceb2820
CB
29#include <stdint.h>
30#include <stdio.h>
31#include <stdlib.h>
32#include <string.h>
33
d38dd64a 34#include "config.h"
3ceb2820 35#include "log.h"
28d832c4 36#include "storage.h"
f2d5a09d 37#include "storage_utils.h"
3ceb2820
CB
38#include "utils.h"
39
43f984ea
DJ
40#ifndef HAVE_STRLCPY
41#include "include/strlcpy.h"
42#endif
43
10bc1861 44lxc_log_define(rbd, lxc);
3ceb2820 45
3b0e906f
CB
46struct rbd_args {
47 const char *osd_pool_name;
48 const char *rbd_name;
49 const char *size;
50};
51
52int 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
62int 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
72int 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
81int 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
10bc1861
CB
90int 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)
3ceb2820
CB
94{
95 ERROR("rbd clonepaths not implemented");
96 return -1;
97}
98
10bc1861 99int rbd_create(struct lxc_storage *bdev, const char *dest, const char *n,
7b22b3e9 100 struct bdev_specs *specs)
3ceb2820 101{
3b0e906f 102 const char *rbdpool, *fstype;
3ceb2820
CB
103 uint64_t size;
104 int ret, len;
105 char sz[24];
a5b18cb1
CB
106 const char *cmd_args[2];
107 char cmd_output[MAXPATHLEN];
3b0e906f
CB
108 const char *rbdname = n;
109 struct rbd_args args = {0};
3ceb2820
CB
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 */
43bd0ebf 122 len = strlen(rbdpool) + strlen(rbdname) + 4 + 11;
3ceb2820 123 bdev->src = malloc(len);
3b0e906f
CB
124 if (!bdev->src) {
125 ERROR("Failed to allocate memory");
3ceb2820 126 return -1;
3b0e906f 127 }
3ceb2820 128
43bd0ebf 129 ret = snprintf(bdev->src, len, "rbd:/dev/rbd/%s/%s", rbdpool, rbdname);
3b0e906f
CB
130 if (ret < 0 || ret >= len) {
131 ERROR("Failed to create string");
3ceb2820 132 return -1;
3b0e906f 133 }
3ceb2820 134
7b22b3e9 135 /* fssize is in bytes */
3ceb2820
CB
136 size = specs->fssize;
137 if (!size)
138 size = DEFAULT_FS_SIZE;
139
7b22b3e9
CB
140 /* in megabytes for rbd tool */
141 ret = snprintf(sz, 24, "%" PRIu64, size / 1024 / 1024);
3b0e906f
CB
142 if (ret < 0 || ret >= 24) {
143 ERROR("Failed to create string");
3ceb2820 144 return -1;
3ceb2820 145 }
3ceb2820 146
3b0e906f
CB
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);
3ceb2820 155 return -1;
3ceb2820 156 }
3b0e906f
CB
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);
3ceb2820 163 return -1;
3b0e906f 164 }
3ceb2820
CB
165
166 fstype = specs->fstype;
167 if (!fstype)
168 fstype = DEFAULT_FSTYPE;
169
a5b18cb1 170 cmd_args[0] = fstype;
3b0e906f 171 cmd_args[1] = lxc_storage_get_path(bdev->src, bdev->type);
a5b18cb1
CB
172 ret = run_command(cmd_output, sizeof(cmd_output), do_mkfs_exec_wrapper,
173 (void *)cmd_args);
3b0e906f
CB
174 if (ret < 0) {
175 ERROR("Failed to map rbd storage volume \"%s\": %s", rbdname,
176 cmd_output);
3ceb2820 177 return -1;
3b0e906f 178 }
a5b18cb1 179
3b0e906f
CB
180 bdev->dest = strdup(dest);
181 if (!bdev->dest) {
182 ERROR("Failed to duplicate string \"%s\"", dest);
3ceb2820 183 return -1;
3b0e906f 184 }
3ceb2820 185
3b0e906f
CB
186 ret = mkdir_p(bdev->dest, 0755);
187 if (ret < 0 && errno != EEXIST) {
188 ERROR("Failed to create directory \"%s\"", bdev->dest);
3ceb2820
CB
189 return -1;
190 }
191
3b0e906f 192 TRACE("Created rbd storage volume \"%s\"", bdev->dest);
3ceb2820
CB
193 return 0;
194}
195
10bc1861 196int rbd_destroy(struct lxc_storage *orig)
3ceb2820 197{
3b0e906f 198 int ret;
41dc7155 199 const char *src;
3ceb2820 200 char *rbdfullname;
3b0e906f
CB
201 char cmd_output[MAXPATHLEN];
202 struct rbd_args args = {0};
43f984ea 203 size_t len;
3ceb2820 204
43bd0ebf
CB
205 src = lxc_storage_get_path(orig->src, orig->type);
206 if (file_exists(src)) {
3b0e906f
CB
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);
3ceb2820 213 return -1;
3ceb2820 214 }
3ceb2820
CB
215 }
216
43f984ea
DJ
217 len = strlen(src);
218 rbdfullname = alloca(len - 8);
219 (void)strlcpy(rbdfullname, &src[9], len - 8);
3b0e906f 220 args.rbd_name = rbdfullname;
43f984ea 221
3b0e906f
CB
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);
3ceb2820 227 return -1;
3ceb2820 228 }
3b0e906f
CB
229
230 return 0;
3ceb2820
CB
231}
232
3d2ae1e2 233bool rbd_detect(const char *path)
3ceb2820 234{
f7ac4459 235 if (!strncmp(path, "rbd:", 4))
3d2ae1e2 236 return true;
f7ac4459
CB
237
238 if (!strncmp(path, "/dev/rbd/", 9))
3d2ae1e2 239 return true;
f7ac4459 240
3d2ae1e2 241 return false;
3ceb2820
CB
242}
243
10bc1861 244int rbd_mount(struct lxc_storage *bdev)
3ceb2820 245{
41dc7155 246 const char *src;
3b0e906f 247
3ceb2820
CB
248 if (strcmp(bdev->type, "rbd"))
249 return -22;
43bd0ebf 250
3ceb2820
CB
251 if (!bdev->src || !bdev->dest)
252 return -22;
253
43bd0ebf
CB
254 src = lxc_storage_get_path(bdev->src, bdev->type);
255 if (!file_exists(src)) {
7b22b3e9
CB
256 /* If blkdev does not exist it should be mapped, because it is
257 * not persistent on reboot.
258 */
3ceb2820
CB
259 ERROR("Block device %s is not mapped.", bdev->src);
260 return -1;
261 }
262
3b0e906f 263 return mount_unknown_fs(src, bdev->dest, bdev->mntopts);
3ceb2820
CB
264}
265
10bc1861 266int rbd_umount(struct lxc_storage *bdev)
3ceb2820
CB
267{
268 if (strcmp(bdev->type, "rbd"))
269 return -22;
43bd0ebf 270
3ceb2820
CB
271 if (!bdev->src || !bdev->dest)
272 return -22;
43bd0ebf 273
3ceb2820
CB
274 return umount(bdev->dest);
275}