Skip to contentSkip to conversation

Block patches

GIT PULL New Kevin Wolf 1 participant 12 messages Aug 30, 2010 – Sep 6, 2010 Block layer

lore
Share & tools
lore

Kevin Wolf

author
#0 lore raw

The following changes since commit 02a89b219039621c940863aa5a9da4fec81a1546:

isapc: fix segfault. (2010-08-28 08:50:40 +0000)

are available in the git repository at:
git://repo.or.cz/qemu/kevin.git for-anthony

Andrew de Quincey (1):
posix-aio-compat: Fix async_conmtext for ioctl

Izumi Tsutsui (1):
sheepdog: remove unnecessary includes

Kevin Wolf (4):
virtio: Factor virtqueue_map_sg out
virtio-blk: Fix migration of queued requests
block: Fix image re-open in bdrv_commit qemu-img rebase: Open new backing file read-only

Laurent Vivier (1):
nbd: Introduce NBD named exports.

Loïc Minier (1):
vvfat: fat_chksum(): fix access above array bounds

Miguel Di Ciurcio Filho (2):
monitor: make 'info snapshots' show only fully available snapshots
savevm: Generate a name when run without one

 block.c            |   13 ++++--
 block/nbd.c        |   68 +++++++++++++++++++++--------
 block/sheepdog.c   |   10 ----
 block/vvfat.c      |    2 +-
 hw/virtio-blk.c    |    5 ++
 hw/virtio.c        |   38 +++++++++++------
 hw/virtio.h        |    3 +
 nbd.c              |  118 ++++++++++++++++++++++++++++++++++++++++++++++-----
 nbd.h              |    5 ++-
 posix-aio-compat.c |    1 +
 qemu-doc.texi      |    7 +++
 qemu-img.c         |    2 +-
 qemu-nbd.c         |    4 +-
 savevm.c           |   88 ++++++++++++++++++++++++++++-----------
 14 files changed, 276 insertions(+), 88 deletions(-)
author
#1 lore raw

PATCH 1/10 virtio: Factor virtqueue_map_sg out

Separate the mapping of requests to host memory from the descriptor iteration. The next patch will make use of it in a different context.

---
 hw/virtio.c |   38 ++++++++++++++++++++++++--------------
 hw/virtio.h |    3 +++
 2 files changed, 27 insertions(+), 14 deletions(-)
hw/virtio.c +24 -14
index 4475bb3..85312b3 100644
@@ -360,11 +360,26 @@ int virtqueue_avail_bytes(VirtQueue *vq, int in_bytes, int out_bytes)
     return 0;
 }
 
+void virtqueue_map_sg(struct iovec *sg, target_phys_addr_t *addr,
+    size_t num_sg, int is_write)
+{
+    unsigned int i;
+    target_phys_addr_t len;
+
+    for (i = 0; i < num_sg; i++) {
+        len = sg[i].iov_len;
+        sg[i].iov_base = cpu_physical_memory_map(addr[i], &len, is_write);
+        if (sg[i].iov_base == NULL || len != sg[i].iov_len) {
+            fprintf(stderr, "virtio: trying to map MMIO memory\n");
+            exit(1);
+        }
+    }
+}
+
 int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem)
 {
     unsigned int i, head, max;
     target_phys_addr_t desc_pa = vq->vring.desc;
-    target_phys_addr_t len;
 
     if (!virtqueue_num_heads(vq, vq->last_avail_idx))
         return 0;
@@ -388,28 +403,19 @@ int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem)
         i = 0;
     }
 
+    /* Collect all the descriptors */
     do {
         struct iovec *sg;
-        int is_write = 0;
 
         if (vring_desc_flags(desc_pa, i) & VRING_DESC_F_WRITE) {
             elem->in_addr[elem->in_num] = vring_desc_addr(desc_pa, i);
             sg = &elem->in_sg[elem->in_num++];
-            is_write = 1;
-        } else
+        } else {
+            elem->out_addr[elem->out_num] = vring_desc_addr(desc_pa, i);
             sg = &elem->out_sg[elem->out_num++];
+        }
 
-        /* Grab the first descriptor, and check it's OK. */
         sg->iov_len = vring_desc_len(desc_pa, i);
-        len = sg->iov_len;
-
-        sg->iov_base = cpu_physical_memory_map(vring_desc_addr(desc_pa, i),
-                                               &len, is_write);
-
-        if (sg->iov_base == NULL || len != sg->iov_len) {
-            fprintf(stderr, "virtio: trying to map MMIO memory\n");
-            exit(1);
-        }
 
         /* If we've got too many, that implies a descriptor loop. */
         if ((elem->in_num + elem->out_num) > max) {
@@ -418,6 +424,10 @@ int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem)
         }
     } while ((i = virtqueue_next_desc(desc_pa, i, max)) != max);
 
+    /* Now map what we have collected */
+    virtqueue_map_sg(elem->in_sg, elem->in_addr, elem->in_num, 1);
+    virtqueue_map_sg(elem->out_sg, elem->out_addr, elem->out_num, 0);
+
     elem->index = head;
 
     vq->inuse++;
hw/virtio.h +3 -0
index 5836ab6..1deeb2c 100644
@@ -81,6 +81,7 @@ typedef struct VirtQueueElement
     unsigned int out_num;
     unsigned int in_num;
     target_phys_addr_t in_addr[VIRTQUEUE_MAX_SIZE];
+    target_phys_addr_t out_addr[VIRTQUEUE_MAX_SIZE];
     struct iovec in_sg[VIRTQUEUE_MAX_SIZE];
     struct iovec out_sg[VIRTQUEUE_MAX_SIZE];
 } VirtQueueElement;
@@ -142,6 +143,8 @@ void virtqueue_flush(VirtQueue *vq, unsigned int count);
 void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem,
                     unsigned int len, unsigned int idx);
 
+void virtqueue_map_sg(struct iovec *sg, target_phys_addr_t *addr,
+    size_t num_sg, int is_write);
 int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem);
 int virtqueue_avail_bytes(VirtQueue *vq, int in_bytes, int out_bytes);
 
Signature · 1 line
1.7.2.2
author
#2 lore raw

PATCH 2/10 virtio-blk: Fix migration of queued requests

In reply to Kevin Wolf

in_sg[].iovec and out_sg[].ioved are pointer to (source) host memory and therefore invalid after migration. When loading the device state we must create a new mapping on the destination host.

---
 hw/virtio-blk.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)
hw/virtio-blk.c +5 -0
index c3a7343..395eb9a 100644
@@ -481,6 +481,11 @@ static int virtio_blk_load(QEMUFile *f, void *opaque, int version_id)
         qemu_get_buffer(f, (unsigned char*)&req->elem, sizeof(req->elem));
         req->next = s->rq;
         s->rq = req;
+
+        virtqueue_map_sg(req->elem.in_sg, req->elem.in_addr,
+            req->elem.in_num, 1);
+        virtqueue_map_sg(req->elem.out_sg, req->elem.out_addr,
+            req->elem.out_num, 0);
     }
 
     return 0;
Signature · 1 line
1.7.2.2
author
#3 lore raw

PATCH 3/10 block: Fix image re-open in bdrv_commit

In reply to Kevin Wolf

Arguably we should re-open the backing file with the backing file format and not with the format of the snapshot image.

---
 block.c |   13 +++++++++----
 1 files changed, 9 insertions(+), 4 deletions(-)
block.c +9 -4
index da70f29..a5514e3 100644
@@ -745,6 +745,7 @@ int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res)
 int bdrv_commit(BlockDriverState *bs)
 {
     BlockDriver *drv = bs->drv;
+    BlockDriver *backing_drv;
     int64_t sector, total_sectors;
     int n, ro, open_flags;
     int ret = 0, rw_ret = 0;
@@ -762,7 +763,8 @@ int bdrv_commit(BlockDriverState *bs)
     if (bs->backing_hd->keep_read_only) {
         return -EACCES;
     }
-    
+
+    backing_drv = bs->backing_hd->drv;
     ro = bs->backing_hd->read_only;
     strncpy(filename, bs->backing_hd->filename, sizeof(filename));
     open_flags =  bs->backing_hd->open_flags;
@@ -772,12 +774,14 @@ int bdrv_commit(BlockDriverState *bs)
         bdrv_delete(bs->backing_hd);
         bs->backing_hd = NULL;
         bs_rw = bdrv_new("");
-        rw_ret = bdrv_open(bs_rw, filename, open_flags | BDRV_O_RDWR, drv);
+        rw_ret = bdrv_open(bs_rw, filename, open_flags | BDRV_O_RDWR,
+            backing_drv);
         if (rw_ret < 0) {
             bdrv_delete(bs_rw);
             /* try to re-open read-only */
             bs_ro = bdrv_new("");
-            ret = bdrv_open(bs_ro, filename, open_flags & ~BDRV_O_RDWR, drv);
+            ret = bdrv_open(bs_ro, filename, open_flags & ~BDRV_O_RDWR,
+                backing_drv);
             if (ret < 0) {
                 bdrv_delete(bs_ro);
                 /* drive not functional anymore */
@@ -828,7 +832,8 @@ ro_cleanup:
         bdrv_delete(bs->backing_hd);
         bs->backing_hd = NULL;
         bs_ro = bdrv_new("");
-        ret = bdrv_open(bs_ro, filename, open_flags & ~BDRV_O_RDWR, drv);
+        ret = bdrv_open(bs_ro, filename, open_flags & ~BDRV_O_RDWR,
+            backing_drv);
         if (ret < 0) {
             bdrv_delete(bs_ro);
             /* drive not functional anymore */
Signature · 1 line
1.7.2.2
author
#4 lore raw

PATCH 4/10 sheepdog: remove unnecessary includes

In reply to Kevin Wolf

From: Izumi Tsutsui <[email protected]>

"qemu_socket.h" includes all necessary files and including <netinet/tcp.h> without <netinet/in.h> could cause errors on some systems.

---
 block/sheepdog.c |   10 ----------
 1 files changed, 0 insertions(+), 10 deletions(-)
block/sheepdog.c +0 -10
index 81aa564..e62820a 100644
@@ -8,16 +8,6 @@
  * You should have received a copy of the GNU General Public License
  * along with this program. If not, see <http://www.gnu.org/licenses/>.
  */
-#ifdef _WIN32
-#include <windows.h>
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#else
-#include <netdb.h>
-#include <netinet/tcp.h>
-
-#define closesocket(s) close(s)
-#endif
 
 #include "qemu-common.h"
 #include "qemu-error.h"
Signature · 1 line
1.7.2.2
author
#5 lore raw

PATCH 5/10 qemu-img rebase: Open new backing file read-only

In reply to Kevin Wolf

We never write to a backing file, so opening rw is useless. It just means that you can't rebase on top of a file for which you don't have write permissions.

---
 qemu-img.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
qemu-img.c +1 -1
index e300f91..d2a978b 100644
@@ -1286,7 +1286,7 @@ static int img_rebase(int argc, char **argv)
         }
 
         bs_new_backing = bdrv_new("new_backing");
-        ret = bdrv_open(bs_new_backing, out_baseimg, BDRV_O_FLAGS | BDRV_O_RDWR,
+        ret = bdrv_open(bs_new_backing, out_baseimg, BDRV_O_FLAGS,
                         new_backing_drv);
         if (ret) {
             error("Could not open new backing file '%s'", out_baseimg);
Signature · 1 line
1.7.2.2
author
#6 lore raw

PATCH 6/10 vvfat: fat_chksum(): fix access above array bounds

In reply to Kevin Wolf

From: Loïc Minier <[email protected]>

---
 block/vvfat.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
block/vvfat.c +1 -1
index 6d61c2e..365332a 100644
@@ -512,7 +512,7 @@ static inline uint8_t fat_chksum(const direntry_t* entry)
     for(i=0;i<11;i++) {
         unsigned char c;
 
-        c = (i <= 8) ? entry->name[i] : entry->extension[i-8];
+        c = (i < 8) ? entry->name[i] : entry->extension[i-8];
         chksum=(((chksum&0xfe)>>1)|((chksum&0x01)?0x80:0)) + c;
     }
 
Signature · 1 line
1.7.2.2
author
#7 lore raw

PATCH 7/10 nbd: Introduce NBD named exports.

In reply to Kevin Wolf

From: Laurent Vivier <[email protected]>

This patch allows to connect Qemu using NBD protocol to an nbd-server using named exports.

For instance, if on the host "isoserver", in /etc/nbd-server/config, you have:

[generic]
[debian-500-ppc-netinst]
exportname = /ISO/debian-500-powerpc-netinst.iso
[Fedora-10-ppc-netinst]
exportname = /ISO/Fedora-10-ppc-netinst.iso

You can connect to it, using:

qemu -cdrom nbd:isoserver:exportname=debian-500-ppc-netinst qemu -cdrom nbd:isoserver:exportname=Fedora-10-ppc-netinst

NOTE: you need at least nbd-server 2.9.18

---
 block/nbd.c   |   68 +++++++++++++++++++++++---------
 nbd.c         |  118 +++++++++++++++++++++++++++++++++++++++++++++++++++------
 nbd.h         |    5 ++-
 qemu-doc.texi |    7 +++
 qemu-nbd.c    |    4 +-
 5 files changed, 169 insertions(+), 33 deletions(-)
block/nbd.c +49 -19
index a1ec123..5e9d6cb 100644
@@ -33,6 +33,8 @@
 #include <sys/types.h>
 #include <unistd.h>
 
+#define EN_OPTSTR ":exportname="
+
 typedef struct BDRVNBDState {
     int sock;
     off_t size;
@@ -42,55 +44,83 @@ typedef struct BDRVNBDState {
 static int nbd_open(BlockDriverState *bs, const char* filename, int flags)
 {
     BDRVNBDState *s = bs->opaque;
+    uint32_t nbdflags;
+
+    char *file;
+    char *name;
     const char *host;
     const char *unixpath;
     int sock;
     off_t size;
     size_t blocksize;
     int ret;
+    int err = -EINVAL;
+
+    file = qemu_strdup(filename);
 
-    if (!strstart(filename, "nbd:", &host))
-        return -EINVAL;
+    name = strstr(file, EN_OPTSTR);
+    if (name) {
+        if (name[strlen(EN_OPTSTR)] == 0) {
+            goto out;
+        }
+        name[0] = 0;
+        name += strlen(EN_OPTSTR);
+    }
+
+    if (!strstart(file, "nbd:", &host)) {
+        goto out;
+    }
 
     if (strstart(host, "unix:", &unixpath)) {
 
-        if (unixpath[0] != '/')
-            return -EINVAL;
+        if (unixpath[0] != '/') {
+            goto out;
+        }
 
         sock = unix_socket_outgoing(unixpath);
 
     } else {
-        uint16_t port;
+        uint16_t port = NBD_DEFAULT_PORT;
         char *p, *r;
         char hostname[128];
 
         pstrcpy(hostname, 128, host);
 
         p = strchr(hostname, ':');
-        if (p == NULL)
-            return -EINVAL;
+        if (p != NULL) {
+            *p = '\0';
+            p++;
+
+            port = strtol(p, &r, 0);
+            if (r == p) {
+                goto out;
+            }
+        } else if (name == NULL) {
+            goto out;
+        }
 
-        *p = '\0';
-        p++;
-
-        port = strtol(p, &r, 0);
-        if (r == p)
-            return -EINVAL;
         sock = tcp_socket_outgoing(hostname, port);
     }
 
-    if (sock == -1)
-        return -errno;
+    if (sock == -1) {
+        err = -errno;
+        goto out;
+    }
 
-    ret = nbd_receive_negotiate(sock, &size, &blocksize);
-    if (ret == -1)
-        return -errno;
+    ret = nbd_receive_negotiate(sock, name, &nbdflags, &size, &blocksize);
+    if (ret == -1) {
+        err = -errno;
+        goto out;
+    }
 
     s->sock = sock;
     s->size = size;
     s->blocksize = blocksize;
+    err = 0;
 
-    return 0;
+out:
+    qemu_free(file);
+    return err;
 }
 
 static int nbd_read(BlockDriverState *bs, int64_t sector_num,
nbd.c +106 -12

152 lines not on this page · raw message

nbd.h +4 -1
index 5a1fbdf..8ff65a1 100644
@@ -42,6 +42,8 @@ enum {
     NBD_CMD_DISC = 2
 };
 
+#define NBD_DEFAULT_PORT	10809
+
 size_t nbd_wr_sync(int fd, void *buffer, size_t size, bool do_read);
 int tcp_socket_outgoing(const char *address, uint16_t port);
 int tcp_socket_incoming(const char *address, uint16_t port);
@@ -49,7 +51,8 @@ int unix_socket_outgoing(const char *path);
 int unix_socket_incoming(const char *path);
 
 int nbd_negotiate(int csock, off_t size);
-int nbd_receive_negotiate(int csock, off_t *size, size_t *blocksize);
+int nbd_receive_negotiate(int csock, const char *name, uint32_t *flags,
+                          off_t *size, size_t *blocksize);
 int nbd_init(int fd, int csock, off_t size, size_t blocksize);
 int nbd_send_request(int csock, struct nbd_request *request);
 int nbd_receive_reply(int csock, struct nbd_reply *reply);
qemu-doc.texi +7 -0
index 55a966f..d7d760f 100644
@@ -620,6 +620,13 @@ qemu linux1.img -hdb nbd:unix:/tmp/my_socket
 qemu linux2.img -hdb nbd:unix:/tmp/my_socket
 @end example
 
+If the nbd-server uses named exports (since NBD 2.9.18), you must use the
+"exportname" option:
+@example
+qemu -cdrom nbd:localhost:exportname=debian-500-ppc-netinst
+qemu -cdrom nbd:localhost:exportname=openSUSE-11.1-ppc-netinst
+@end example
+
 @node pcsys_network
 @section Network emulation
 
qemu-nbd.c +3 -1
index 4e607cf..41e5c5d 100644
@@ -230,6 +230,7 @@ int main(int argc, char **argv)
     int nb_fds = 0;
     int max_fd;
     int persistent = 0;
+    uint32_t nbdflags;
 
     while ((ch = getopt_long(argc, argv, sopt, lopt, &opt_ind)) != -1) {
         switch (ch) {
@@ -398,7 +399,8 @@ int main(int argc, char **argv)
                 goto out;
             }
 
-            ret = nbd_receive_negotiate(sock, &size, &blocksize);
+            ret = nbd_receive_negotiate(sock, NULL, &nbdflags,
+					&size, &blocksize);
             if (ret == -1) {
                 ret = 1;
                 goto out;
Signature · 1 line
1.7.2.2
author
#8 lore raw

PATCH 8/10 posix-aio-compat: Fix async_conmtext for ioctl

In reply to Kevin Wolf

From: Andrew de Quincey <[email protected]>

Set the async_context_id field when queuing an async ioctl call

---
 posix-aio-compat.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
posix-aio-compat.c +1 -0
index a67ffe3..efc5968 100644
@@ -599,6 +599,7 @@ BlockDriverAIOCB *paio_ioctl(BlockDriverState *bs, int fd,
     acb->aio_type = QEMU_AIO_IOCTL;
     acb->aio_fildes = fd;
     acb->ev_signo = SIGUSR2;
+    acb->async_context_id = get_async_context_id();
     acb->aio_offset = 0;
     acb->aio_ioctl_buf = buf;
     acb->aio_ioctl_cmd = req;
Signature · 1 line
1.7.2.2
author
#9 lore raw

PATCH 9/10 monitor: make 'info snapshots' show only fully available snapshots

In reply to Kevin Wolf

From: Miguel Di Ciurcio Filho <[email protected]>

The output generated by 'info snapshots' shows only snapshots that exist on the block device that saves the VM state. This output can cause an user to erroneously try to load an snapshot that is not available on all block devices.

$ qemu-img snapshot -l xxtest.qcow2
Snapshot list:
ID        TAG                 VM SIZE                DATE       VM CLOCK
1                                1.5M 2010-07-26 16:51:52   00:00:08.599
2                                1.5M 2010-07-26 16:51:53   00:00:09.719
3                                1.5M 2010-07-26 17:26:49   00:00:13.245
4                                1.5M 2010-07-26 19:01:00   00:00:46.763
$ qemu-img snapshot -l xxtest2.qcow2
Snapshot list:
ID        TAG                 VM SIZE                DATE       VM CLOCK
3                                   0 2010-07-26 17:26:49   00:00:13.245
4                                   0 2010-07-26 19:01:00   00:00:46.763

Current output:

$ qemu -hda xxtest.qcow2 -hdb xxtest2.qcow2 -monitor stdio -vnc :0
QEMU 0.12.4 monitor - type 'help' for more information
(qemu) info snapshots
Snapshot devices: ide0-hd0
Snapshot list (from ide0-hd0):
ID        TAG                 VM SIZE                DATE       VM CLOCK
1                                1.5M 2010-07-26 16:51:52   00:00:08.599
2                                1.5M 2010-07-26 16:51:53   00:00:09.719
3                                1.5M 2010-07-26 17:26:49   00:00:13.245
4                                1.5M 2010-07-26 19:01:00   00:00:46.763

Snapshots 1 and 2 do not exist on xxtest2.qcow, but they are displayed anyway.

This patch sumarizes the output to only show fully available snapshots.

New output:
(qemu) info snapshots
ID TAG VM SIZE DATE VM CLOCK

3                                1.5M 2010-07-26 17:26:49   00:00:13.245
4                                1.5M 2010-07-26 19:01:00   00:00:46.763
---
 savevm.c |   59 +++++++++++++++++++++++++++++++++++++++++++----------------
 1 files changed, 43 insertions(+), 16 deletions(-)
savevm.c +43 -16
index 99e4949..d286592 100644
@@ -2039,8 +2039,10 @@ void do_delvm(Monitor *mon, const QDict *qdict)
 void do_info_snapshots(Monitor *mon)
 {
     BlockDriverState *bs, *bs1;
-    QEMUSnapshotInfo *sn_tab, *sn;
-    int nb_sns, i;
+    QEMUSnapshotInfo *sn_tab, *sn, s, *sn_info = &s;
+    int nb_sns, i, ret, available;
+    int total;
+    int *available_snapshots;
     char buf[256];
 
     bs = bdrv_snapshots();
@@ -2048,27 +2050,52 @@ void do_info_snapshots(Monitor *mon)
         monitor_printf(mon, "No available block device supports snapshots\n");
         return;
     }
-    monitor_printf(mon, "Snapshot devices:");
-    bs1 = NULL;
-    while ((bs1 = bdrv_next(bs1))) {
-        if (bdrv_can_snapshot(bs1)) {
-            if (bs == bs1)
-                monitor_printf(mon, " %s", bdrv_get_device_name(bs1));
-        }
-    }
-    monitor_printf(mon, "\n");
 
     nb_sns = bdrv_snapshot_list(bs, &sn_tab);
     if (nb_sns < 0) {
         monitor_printf(mon, "bdrv_snapshot_list: error %d\n", nb_sns);
         return;
     }
-    monitor_printf(mon, "Snapshot list (from %s):\n",
-                   bdrv_get_device_name(bs));
-    monitor_printf(mon, "%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
-    for(i = 0; i < nb_sns; i++) {
+
+    if (nb_sns == 0) {
+        monitor_printf(mon, "There is no snapshot available.\n");
+        return;
+    }
+
+    available_snapshots = qemu_mallocz(sizeof(int) * nb_sns);
+    total = 0;
+    for (i = 0; i < nb_sns; i++) {
         sn = &sn_tab[i];
-        monitor_printf(mon, "%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
+        available = 1;
+        bs1 = NULL;
+
+        while ((bs1 = bdrv_next(bs1))) {
+            if (bdrv_can_snapshot(bs1) && bs1 != bs) {
+                ret = bdrv_snapshot_find(bs1, sn_info, sn->id_str);
+                if (ret < 0) {
+                    available = 0;
+                    break;
+                }
+            }
+        }
+
+        if (available) {
+            available_snapshots[total] = i;
+            total++;
+        }
     }
+
+    if (total > 0) {
+        monitor_printf(mon, "%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
+        for (i = 0; i < total; i++) {
+            sn = &sn_tab[available_snapshots[i]];
+            monitor_printf(mon, "%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
+        }
+    } else {
+        monitor_printf(mon, "There is no suitable snapshot available\n");
+    }
+
     qemu_free(sn_tab);
+    qemu_free(available_snapshots);
+
 }
Signature · 1 line
1.7.2.2
author
#10 lore raw

PATCH 10/10 savevm: Generate a name when run without one

In reply to Kevin Wolf

From: Miguel Di Ciurcio Filho <[email protected]>

When savevm is run without a name, the name stays blank and the snapshot is saved anyway.

The new behavior is when savevm is run without parameters a name will be created automaticaly, so the snapshot is accessible to the user without needing the id when loadvm is run.

(qemu) savevm
(qemu) info snapshots
ID TAG VM SIZE DATE VM CLOCK
1 vm-20100728134640 978K 2010-07-28 13:46:40 00:00:08.603

We use a name with the format 'vm-YYYYMMDDHHMMSS'.

This is a first step to hide the internal id, because I don't see a reason to expose this kind of internals to the user.

---
 savevm.c |   29 ++++++++++++++++++++---------
 1 files changed, 20 insertions(+), 9 deletions(-)
savevm.c +20 -9
index d286592..4d9f822 100644
@@ -1837,8 +1837,10 @@ void do_savevm(Monitor *mon, const QDict *qdict)
     uint32_t vm_state_size;
 #ifdef _WIN32
     struct _timeb tb;
+    struct tm *ptm;
 #else
     struct timeval tv;
+    struct tm tm;
 #endif
     const char *name = qdict_get_try_str(qdict, "name");
 
@@ -1869,15 +1871,6 @@ void do_savevm(Monitor *mon, const QDict *qdict)
     vm_stop(0);
 
     memset(sn, 0, sizeof(*sn));
-    if (name) {
-        ret = bdrv_snapshot_find(bs, old_sn, name);
-        if (ret >= 0) {
-            pstrcpy(sn->name, sizeof(sn->name), old_sn->name);
-            pstrcpy(sn->id_str, sizeof(sn->id_str), old_sn->id_str);
-        } else {
-            pstrcpy(sn->name, sizeof(sn->name), name);
-        }
-    }
 
     /* fill auxiliary fields */
 #ifdef _WIN32
@@ -1891,6 +1884,24 @@ void do_savevm(Monitor *mon, const QDict *qdict)
 #endif
     sn->vm_clock_nsec = qemu_get_clock(vm_clock);
 
+    if (name) {
+        ret = bdrv_snapshot_find(bs, old_sn, name);
+        if (ret >= 0) {
+            pstrcpy(sn->name, sizeof(sn->name), old_sn->name);
+            pstrcpy(sn->id_str, sizeof(sn->id_str), old_sn->id_str);
+        } else {
+            pstrcpy(sn->name, sizeof(sn->name), name);
+        }
+    } else {
+#ifdef _WIN32
+        ptm = localtime(&tb.time);
+        strftime(sn->name, sizeof(sn->name), "vm-%Y%m%d%H%M%S", ptm);
+#else
+        localtime_r(&tv.tv_sec, &tm);
+        strftime(sn->name, sizeof(sn->name), "vm-%Y%m%d%H%M%S", &tm);
+#endif
+    }
+
     /* Delete old snapshots of the same name */
     if (name && del_existing_snapshots(mon, name) < 0) {
         goto the_end;
Signature · 1 line
1.7.2.2
author
#11 lore raw
In reply to Kevin Wolf

Am 30.08.2010 18:32, schrieb Kevin Wolf:

Quoted 22 lines

The following changes since commit 02a89b219039621c940863aa5a9da4fec81a1546:

isapc: fix segfault. (2010-08-28 08:50:40 +0000)

are available in the git repository at:
git://repo.or.cz/qemu/kevin.git for-anthony

Andrew de Quincey (1):
posix-aio-compat: Fix async_conmtext for ioctl

Izumi Tsutsui (1):
sheepdog: remove unnecessary includes

Kevin Wolf (4):
virtio: Factor virtqueue_map_sg out
virtio-blk: Fix migration of queued requests
block: Fix image re-open in bdrv_commit qemu-img rebase: Open new backing file read-only

Laurent Vivier (1):
nbd: Introduce NBD named exports.

Quoted 6 lines

Loïc Minier (1):
vvfat: fat_chksum(): fix access above array bounds

Miguel Di Ciurcio Filho (2):
monitor: make 'info snapshots' show only fully available snapshots
savevm: Generate a name when run without one

Anthony, I think you already pulled the patches for stable-0.13 that I sent on the same day, but these patches for master still seem to be missing.

Kevin