Revision 8c116b0e qemu-nbd.c
b/qemu-nbd.c | ||
---|---|---|
20 | 20 |
#include "block/block.h" |
21 | 21 |
#include "block/nbd.h" |
22 | 22 |
#include "qemu/main-loop.h" |
23 |
#include "block/snapshot.h" |
|
23 | 24 |
|
24 | 25 |
#include <stdarg.h> |
25 | 26 |
#include <stdio.h> |
... | ... | |
79 | 80 |
"\n" |
80 | 81 |
"Block device options:\n" |
81 | 82 |
" -r, --read-only export read-only\n" |
82 |
" -s, --snapshot use snapshot file\n" |
|
83 |
" -s, --snapshot use FILE as an external snapshot, create a temporary\n" |
|
84 |
" file with backing_file=FILE, redirect the write to\n" |
|
85 |
" the temporary one\n" |
|
86 |
" -l, --load-snapshot=SNAPSHOT_PARAM\n" |
|
87 |
" load an internal snapshot inside FILE and export it\n" |
|
88 |
" as an read-only device, SNAPSHOT_PARAM format is\n" |
|
89 |
" 'snapshot.id=[ID],snapshot.name=[NAME]', or\n" |
|
90 |
" '[ID_OR_NAME]'\n" |
|
83 | 91 |
" -n, --nocache disable host cache\n" |
84 | 92 |
" --cache=MODE set cache mode (none, writeback, ...)\n" |
85 | 93 |
#ifdef CONFIG_LINUX_AIO |
... | ... | |
315 | 323 |
char *device = NULL; |
316 | 324 |
int port = NBD_DEFAULT_PORT; |
317 | 325 |
off_t fd_size; |
318 |
const char *sopt = "hVb:o:p:rsnP:c:dvk:e:f:t"; |
|
326 |
QemuOpts *sn_opts = NULL; |
|
327 |
const char *sn_id_or_name = NULL; |
|
328 |
const char *sopt = "hVb:o:p:rsnP:c:dvk:e:f:tl:"; |
|
319 | 329 |
struct option lopt[] = { |
320 | 330 |
{ "help", 0, NULL, 'h' }, |
321 | 331 |
{ "version", 0, NULL, 'V' }, |
... | ... | |
328 | 338 |
{ "connect", 1, NULL, 'c' }, |
329 | 339 |
{ "disconnect", 0, NULL, 'd' }, |
330 | 340 |
{ "snapshot", 0, NULL, 's' }, |
341 |
{ "load-snapshot", 1, NULL, 'l' }, |
|
331 | 342 |
{ "nocache", 0, NULL, 'n' }, |
332 | 343 |
{ "cache", 1, NULL, QEMU_NBD_OPT_CACHE }, |
333 | 344 |
#ifdef CONFIG_LINUX_AIO |
... | ... | |
428 | 439 |
errx(EXIT_FAILURE, "Offset must be positive `%s'", optarg); |
429 | 440 |
} |
430 | 441 |
break; |
442 |
case 'l': |
|
443 |
if (strstart(optarg, SNAPSHOT_OPT_BASE, NULL)) { |
|
444 |
sn_opts = qemu_opts_parse(&internal_snapshot_opts, optarg, 0); |
|
445 |
if (!sn_opts) { |
|
446 |
errx(EXIT_FAILURE, "Failed in parsing snapshot param `%s'", |
|
447 |
optarg); |
|
448 |
} |
|
449 |
} else { |
|
450 |
sn_id_or_name = optarg; |
|
451 |
} |
|
452 |
/* fall through */ |
|
431 | 453 |
case 'r': |
432 | 454 |
nbdflags |= NBD_FLAG_READ_ONLY; |
433 | 455 |
flags &= ~BDRV_O_RDWR; |
... | ... | |
581 | 603 |
error_get_pretty(local_err)); |
582 | 604 |
} |
583 | 605 |
|
606 |
if (sn_opts) { |
|
607 |
ret = bdrv_snapshot_load_tmp(bs, |
|
608 |
qemu_opt_get(sn_opts, SNAPSHOT_OPT_ID), |
|
609 |
qemu_opt_get(sn_opts, SNAPSHOT_OPT_NAME), |
|
610 |
&local_err); |
|
611 |
} else if (sn_id_or_name) { |
|
612 |
ret = bdrv_snapshot_load_tmp_by_id_or_name(bs, sn_id_or_name, |
|
613 |
&local_err); |
|
614 |
} |
|
615 |
if (ret < 0) { |
|
616 |
errno = -ret; |
|
617 |
err(EXIT_FAILURE, |
|
618 |
"Failed to load snapshot: %s", |
|
619 |
error_get_pretty(local_err)); |
|
620 |
} |
|
621 |
|
|
584 | 622 |
fd_size = bdrv_getlength(bs); |
585 | 623 |
|
586 | 624 |
if (partition != -1) { |
... | ... | |
641 | 679 |
unlink(sockpath); |
642 | 680 |
} |
643 | 681 |
|
682 |
if (sn_opts) { |
|
683 |
qemu_opts_del(sn_opts); |
|
684 |
} |
|
685 |
|
|
644 | 686 |
if (device) { |
645 | 687 |
void *ret; |
646 | 688 |
pthread_join(client_thread, &ret); |
Also available in: Unified diff