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