Revision fab5cf59 block/rbd.c
b/block/rbd.c | ||
---|---|---|
23 | 23 |
/* |
24 | 24 |
* When specifying the image filename use: |
25 | 25 |
* |
26 |
* rbd:poolname/devicename |
|
26 |
* rbd:poolname/devicename[@snapshotname][:option1=value1[:option2=value2...]]
|
|
27 | 27 |
* |
28 | 28 |
* poolname must be the name of an existing rados pool |
29 | 29 |
* |
30 | 30 |
* devicename is the basename for all objects used to |
31 | 31 |
* emulate the raw device. |
32 | 32 |
* |
33 |
* Each option given is used to configure rados, and may be |
|
34 |
* any Ceph option, or "conf". The "conf" option specifies |
|
35 |
* a Ceph configuration file to read. |
|
36 |
* |
|
33 | 37 |
* Metadata information (image size, ...) is stored in an |
34 | 38 |
* object with the name "devicename.rbd". |
35 | 39 |
* |
... | ... | |
123 | 127 |
static int qemu_rbd_parsename(const char *filename, |
124 | 128 |
char *pool, int pool_len, |
125 | 129 |
char *snap, int snap_len, |
126 |
char *name, int name_len) |
|
130 |
char *name, int name_len, |
|
131 |
char *conf, int conf_len) |
|
127 | 132 |
{ |
128 | 133 |
const char *start; |
129 | 134 |
char *p, *buf; |
... | ... | |
135 | 140 |
|
136 | 141 |
buf = qemu_strdup(start); |
137 | 142 |
p = buf; |
143 |
*snap = '\0'; |
|
144 |
*conf = '\0'; |
|
138 | 145 |
|
139 | 146 |
ret = qemu_rbd_next_tok(pool, pool_len, p, '/', "pool name", &p); |
140 | 147 |
if (ret < 0 || !p) { |
141 | 148 |
ret = -EINVAL; |
142 | 149 |
goto done; |
143 | 150 |
} |
144 |
ret = qemu_rbd_next_tok(name, name_len, p, '@', "object name", &p); |
|
145 |
if (ret < 0) { |
|
146 |
goto done; |
|
151 |
|
|
152 |
if (strchr(p, '@')) { |
|
153 |
ret = qemu_rbd_next_tok(name, name_len, p, '@', "object name", &p); |
|
154 |
if (ret < 0) { |
|
155 |
goto done; |
|
156 |
} |
|
157 |
ret = qemu_rbd_next_tok(snap, snap_len, p, ':', "snap name", &p); |
|
158 |
} else { |
|
159 |
ret = qemu_rbd_next_tok(name, name_len, p, ':', "object name", &p); |
|
147 | 160 |
} |
148 |
if (!p) { |
|
149 |
*snap = '\0'; |
|
161 |
if (ret < 0 || !p) { |
|
150 | 162 |
goto done; |
151 | 163 |
} |
152 | 164 |
|
153 |
ret = qemu_rbd_next_tok(snap, snap_len, p, '\0', "snap name", &p);
|
|
165 |
ret = qemu_rbd_next_tok(conf, conf_len, p, '\0', "configuration", &p);
|
|
154 | 166 |
|
155 | 167 |
done: |
156 | 168 |
qemu_free(buf); |
157 | 169 |
return ret; |
158 | 170 |
} |
159 | 171 |
|
172 |
static int qemu_rbd_set_conf(rados_t cluster, const char *conf) |
|
173 |
{ |
|
174 |
char *p, *buf; |
|
175 |
char name[RBD_MAX_CONF_NAME_SIZE]; |
|
176 |
char value[RBD_MAX_CONF_VAL_SIZE]; |
|
177 |
int ret = 0; |
|
178 |
|
|
179 |
buf = qemu_strdup(conf); |
|
180 |
p = buf; |
|
181 |
|
|
182 |
while (p) { |
|
183 |
ret = qemu_rbd_next_tok(name, sizeof(name), p, |
|
184 |
'=', "conf option name", &p); |
|
185 |
if (ret < 0) { |
|
186 |
break; |
|
187 |
} |
|
188 |
|
|
189 |
if (!p) { |
|
190 |
error_report("conf option %s has no value", name); |
|
191 |
ret = -EINVAL; |
|
192 |
break; |
|
193 |
} |
|
194 |
|
|
195 |
ret = qemu_rbd_next_tok(value, sizeof(value), p, |
|
196 |
':', "conf option value", &p); |
|
197 |
if (ret < 0) { |
|
198 |
break; |
|
199 |
} |
|
200 |
|
|
201 |
if (strcmp(name, "conf")) { |
|
202 |
ret = rados_conf_set(cluster, name, value); |
|
203 |
if (ret < 0) { |
|
204 |
error_report("invalid conf option %s", name); |
|
205 |
ret = -EINVAL; |
|
206 |
break; |
|
207 |
} |
|
208 |
} else { |
|
209 |
ret = rados_conf_read_file(cluster, value); |
|
210 |
if (ret < 0) { |
|
211 |
error_report("error reading conf file %s", value); |
|
212 |
break; |
|
213 |
} |
|
214 |
} |
|
215 |
} |
|
216 |
|
|
217 |
qemu_free(buf); |
|
218 |
return ret; |
|
219 |
} |
|
220 |
|
|
160 | 221 |
static int qemu_rbd_create(const char *filename, QEMUOptionParameter *options) |
161 | 222 |
{ |
162 | 223 |
int64_t bytes = 0; |
... | ... | |
165 | 226 |
char pool[RBD_MAX_POOL_NAME_SIZE]; |
166 | 227 |
char name[RBD_MAX_IMAGE_NAME_SIZE]; |
167 | 228 |
char snap_buf[RBD_MAX_SNAP_NAME_SIZE]; |
229 |
char conf[RBD_MAX_CONF_SIZE]; |
|
168 | 230 |
char *snap = NULL; |
169 | 231 |
rados_t cluster; |
170 | 232 |
rados_ioctx_t io_ctx; |
... | ... | |
172 | 234 |
|
173 | 235 |
if (qemu_rbd_parsename(filename, pool, sizeof(pool), |
174 | 236 |
snap_buf, sizeof(snap_buf), |
175 |
name, sizeof(name)) < 0) { |
|
237 |
name, sizeof(name), |
|
238 |
conf, sizeof(conf)) < 0) { |
|
176 | 239 |
return -EINVAL; |
177 | 240 |
} |
178 | 241 |
if (snap_buf[0] != '\0') { |
... | ... | |
205 | 268 |
return -EIO; |
206 | 269 |
} |
207 | 270 |
|
208 |
if (rados_conf_read_file(cluster, NULL) < 0) { |
|
209 |
error_report("error reading config file"); |
|
271 |
if (strstr(conf, "conf=") == NULL) { |
|
272 |
if (rados_conf_read_file(cluster, NULL) < 0) { |
|
273 |
error_report("error reading config file"); |
|
274 |
rados_shutdown(cluster); |
|
275 |
return -EIO; |
|
276 |
} |
|
277 |
} |
|
278 |
|
|
279 |
if (conf[0] != '\0' && |
|
280 |
qemu_rbd_set_conf(cluster, conf) < 0) { |
|
281 |
error_report("error setting config options"); |
|
210 | 282 |
rados_shutdown(cluster); |
211 | 283 |
return -EIO; |
212 | 284 |
} |
... | ... | |
316 | 388 |
BDRVRBDState *s = bs->opaque; |
317 | 389 |
char pool[RBD_MAX_POOL_NAME_SIZE]; |
318 | 390 |
char snap_buf[RBD_MAX_SNAP_NAME_SIZE]; |
391 |
char conf[RBD_MAX_CONF_SIZE]; |
|
319 | 392 |
int r; |
320 | 393 |
|
321 | 394 |
if (qemu_rbd_parsename(filename, pool, sizeof(pool), |
322 | 395 |
snap_buf, sizeof(snap_buf), |
323 |
s->name, sizeof(s->name)) < 0) { |
|
396 |
s->name, sizeof(s->name), |
|
397 |
conf, sizeof(conf)) < 0) { |
|
324 | 398 |
return -EINVAL; |
325 | 399 |
} |
326 | 400 |
s->snap = NULL; |
... | ... | |
334 | 408 |
return r; |
335 | 409 |
} |
336 | 410 |
|
337 |
r = rados_conf_read_file(s->cluster, NULL); |
|
338 |
if (r < 0) { |
|
339 |
error_report("error reading config file"); |
|
340 |
rados_shutdown(s->cluster); |
|
341 |
return r; |
|
411 |
if (strstr(conf, "conf=") == NULL) { |
|
412 |
r = rados_conf_read_file(s->cluster, NULL); |
|
413 |
if (r < 0) { |
|
414 |
error_report("error reading config file"); |
|
415 |
rados_shutdown(s->cluster); |
|
416 |
return r; |
|
417 |
} |
|
418 |
} |
|
419 |
|
|
420 |
if (conf[0] != '\0') { |
|
421 |
r = qemu_rbd_set_conf(s->cluster, conf); |
|
422 |
if (r < 0) { |
|
423 |
error_report("error setting config options"); |
|
424 |
rados_shutdown(s->cluster); |
|
425 |
return r; |
|
426 |
} |
|
342 | 427 |
} |
343 | 428 |
|
344 | 429 |
r = rados_connect(s->cluster); |
Also available in: Unified diff