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