Revision feeee5ac

b/block.c
1666 1666
/**************************************************************/
1667 1667
/* handling of snapshots */
1668 1668

  
1669
int bdrv_can_snapshot(BlockDriverState *bs)
1670
{
1671
    BlockDriver *drv = bs->drv;
1672
    if (!drv || bdrv_is_removable(bs) || bdrv_is_read_only(bs)) {
1673
        return 0;
1674
    }
1675

  
1676
    if (!drv->bdrv_snapshot_create) {
1677
        if (bs->file != NULL) {
1678
            return bdrv_can_snapshot(bs->file);
1679
        }
1680
        return 0;
1681
    }
1682

  
1683
    return 1;
1684
}
1685

  
1669 1686
int bdrv_snapshot_create(BlockDriverState *bs,
1670 1687
                         QEMUSnapshotInfo *sn_info)
1671 1688
{
b/block.h
175 175
const char *bdrv_get_encrypted_filename(BlockDriverState *bs);
176 176
void bdrv_get_backing_filename(BlockDriverState *bs,
177 177
                               char *filename, int filename_size);
178
int bdrv_can_snapshot(BlockDriverState *bs);
178 179
int bdrv_snapshot_create(BlockDriverState *bs,
179 180
                         QEMUSnapshotInfo *sn_info);
180 181
int bdrv_snapshot_goto(BlockDriverState *bs,
b/savevm.c
1575 1575
    return ret;
1576 1576
}
1577 1577

  
1578
/* device can contain snapshots */
1579
static int bdrv_can_snapshot(BlockDriverState *bs)
1580
{
1581
    return (bs &&
1582
            !bdrv_is_removable(bs) &&
1583
            !bdrv_is_read_only(bs));
1584
}
1585

  
1586
/* device must be snapshots in order to have a reliable snapshot */
1587
static int bdrv_has_snapshot(BlockDriverState *bs)
1588
{
1589
    return (bs &&
1590
            !bdrv_is_removable(bs) &&
1591
            !bdrv_is_read_only(bs));
1592
}
1593

  
1594 1578
static BlockDriverState *get_bs_snapshots(void)
1595 1579
{
1596 1580
    BlockDriverState *bs;
......
1600 1584
        return bs_snapshots;
1601 1585
    QTAILQ_FOREACH(dinfo, &drives, next) {
1602 1586
        bs = dinfo->bdrv;
1603
        if (bdrv_can_snapshot(bs))
1587
        if (bdrv_can_snapshot(bs)) {
1604 1588
            goto ok;
1589
        }
1605 1590
    }
1606 1591
    return NULL;
1607 1592
 ok:
......
1675 1660
#endif
1676 1661
    const char *name = qdict_get_try_str(qdict, "name");
1677 1662

  
1663
    /* Verify if there is a device that doesn't support snapshots and is writable */
1664
    QTAILQ_FOREACH(dinfo, &drives, next) {
1665
        bs = dinfo->bdrv;
1666

  
1667
        if (bdrv_is_removable(bs) || bdrv_is_read_only(bs)) {
1668
            continue;
1669
        }
1670

  
1671
        if (!bdrv_can_snapshot(bs)) {
1672
            monitor_printf(mon, "Device '%s' is writable but does not support snapshots.\n",
1673
                               bdrv_get_device_name(bs));
1674
            return;
1675
        }
1676
    }
1677

  
1678 1678
    bs = get_bs_snapshots();
1679 1679
    if (!bs) {
1680 1680
        monitor_printf(mon, "No block device can accept snapshots\n");
1681 1681
        return;
1682 1682
    }
1683

  
1684 1683
    /* ??? Should this occur after vm_stop?  */
1685 1684
    qemu_aio_flush();
1686 1685

  
......
1733 1732

  
1734 1733
    QTAILQ_FOREACH(dinfo, &drives, next) {
1735 1734
        bs1 = dinfo->bdrv;
1736
        if (bdrv_has_snapshot(bs1)) {
1735
        if (bdrv_can_snapshot(bs1)) {
1737 1736
            /* Write VM state size only to the image that contains the state */
1738 1737
            sn->vm_state_size = (bs == bs1 ? vm_state_size : 0);
1739 1738
            ret = bdrv_snapshot_create(bs1, sn);
......
1757 1756
    QEMUFile *f;
1758 1757
    int ret;
1759 1758

  
1759
    /* Verify if there is a device that doesn't support snapshots and is writable */
1760
    QTAILQ_FOREACH(dinfo, &drives, next) {
1761
        bs = dinfo->bdrv;
1762

  
1763
        if (bdrv_is_removable(bs) || bdrv_is_read_only(bs)) {
1764
            continue;
1765
        }
1766

  
1767
        if (!bdrv_can_snapshot(bs)) {
1768
            error_report("Device '%s' is writable but does not support snapshots.",
1769
                               bdrv_get_device_name(bs));
1770
            return -ENOTSUP;
1771
        }
1772
    }
1773

  
1760 1774
    bs = get_bs_snapshots();
1761 1775
    if (!bs) {
1762 1776
        error_report("No block device supports snapshots");
......
1768 1782

  
1769 1783
    QTAILQ_FOREACH(dinfo, &drives, next) {
1770 1784
        bs1 = dinfo->bdrv;
1771
        if (bdrv_has_snapshot(bs1)) {
1785
        if (bdrv_can_snapshot(bs1)) {
1772 1786
            ret = bdrv_snapshot_goto(bs1, name);
1773 1787
            if (ret < 0) {
1774 1788
                switch(ret) {
......
1830 1844

  
1831 1845
    QTAILQ_FOREACH(dinfo, &drives, next) {
1832 1846
        bs1 = dinfo->bdrv;
1833
        if (bdrv_has_snapshot(bs1)) {
1847
        if (bdrv_can_snapshot(bs1)) {
1834 1848
            ret = bdrv_snapshot_delete(bs1, name);
1835 1849
            if (ret < 0) {
1836 1850
                if (ret == -ENOTSUP)
......
1861 1875
    monitor_printf(mon, "Snapshot devices:");
1862 1876
    QTAILQ_FOREACH(dinfo, &drives, next) {
1863 1877
        bs1 = dinfo->bdrv;
1864
        if (bdrv_has_snapshot(bs1)) {
1878
        if (bdrv_can_snapshot(bs1)) {
1865 1879
            if (bs == bs1)
1866 1880
                monitor_printf(mon, " %s", bdrv_get_device_name(bs1));
1867 1881
        }

Also available in: Unified diff