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