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