diff --git a/block.c b/block.c
index cd70730..7eddc15 100644
--- a/block.c
+++ b/block.c
@@ -1720,15 +1720,52 @@ void bdrv_debug_event(BlockDriverState *bs, BlkDebugEvent event)
 /**************************************************************/
 /* handling of snapshots */
 
-int bdrv_snapshot_create(BlockDriverState *bs,
-                         QEMUSnapshotInfo *sn_info)
+int bdrv_can_snapshot(BlockDriverState *bs)
 {
     BlockDriver *drv = bs->drv;
-    if (!drv)
+    if (!drv) {
+        return -ENOMEDIUM;
+    }
+
+    if (!drv->bdrv_snapshot_create || bdrv_is_removable(bs) ||
+        bdrv_is_read_only(bs)) {
+        return -ENOTSUP;
+    }
+
+    return 1;
+}
+
+int bdrv_has_snapshot(BlockDriverState *bs)
+{
+    int ret;
+    QEMUSnapshotInfo *sn_tab;
+    BlockDriver *drv = bs->drv;
+    if (!drv) {
         return -ENOMEDIUM;
-    if (!drv->bdrv_snapshot_create)
+    }
+
+    if (!drv->bdrv_snapshot_list) {
         return -ENOTSUP;
-    return drv->bdrv_snapshot_create(bs, sn_info);
+    }
+
+    ret = drv->bdrv_snapshot_list(bs, &sn_tab);
+
+    if (sn_tab) {
+        qemu_free(sn_tab);
+    }
+
+    return ret;
+}
+
+int bdrv_snapshot_create(BlockDriverState *bs,
+                         QEMUSnapshotInfo *sn_info)
+{
+    BlockDriver *drv = bs->drv;
+    if (bdrv_can_snapshot(bs) > 0) {
+        return drv->bdrv_snapshot_create(bs, sn_info);
+    }
+
+    return -1;
 }
 
 int bdrv_snapshot_goto(BlockDriverState *bs,
diff --git a/block.h b/block.h
index 24efeb6..c536f1c 100644
--- a/block.h
+++ b/block.h
@@ -173,6 +173,8 @@ int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi);
 const char *bdrv_get_encrypted_filename(BlockDriverState *bs);
 void bdrv_get_backing_filename(BlockDriverState *bs,
                                char *filename, int filename_size);
+int bdrv_can_snapshot(BlockDriverState *bs);
+int bdrv_has_snapshot(BlockDriverState *bs);
 int bdrv_snapshot_create(BlockDriverState *bs,
                          QEMUSnapshotInfo *sn_info);
 int bdrv_snapshot_goto(BlockDriverState *bs,
diff --git a/savevm.c b/savevm.c
index dc20390..9bc232f 100644
--- a/savevm.c
+++ b/savevm.c
@@ -1574,22 +1574,6 @@ out:
     return ret;
 }
 
-/* device can contain snapshots */
-static int bdrv_can_snapshot(BlockDriverState *bs)
-{
-    return (bs &&
-            !bdrv_is_removable(bs) &&
-            !bdrv_is_read_only(bs));
-}
-
-/* device must be snapshots in order to have a reliable snapshot */
-static int bdrv_has_snapshot(BlockDriverState *bs)
-{
-    return (bs &&
-            !bdrv_is_removable(bs) &&
-            !bdrv_is_read_only(bs));
-}
-
 static BlockDriverState *get_bs_snapshots(void)
 {
     BlockDriverState *bs;
@@ -1599,7 +1583,7 @@ static BlockDriverState *get_bs_snapshots(void)
         return bs_snapshots;
     QTAILQ_FOREACH(dinfo, &drives, next) {
         bs = dinfo->bdrv;
-        if (bdrv_can_snapshot(bs))
+        if (bdrv_can_snapshot(bs) > 0)
             goto ok;
     }
     return NULL;
@@ -1642,7 +1626,7 @@ static int del_existing_snapshots(Monitor *mon, const char *name)
 
     QTAILQ_FOREACH(dinfo, &drives, next) {
         bs = dinfo->bdrv;
-        if (bdrv_can_snapshot(bs) &&
+        if ((bdrv_can_snapshot(bs) > 0) &&
             bdrv_snapshot_find(bs, snapshot, name) >= 0)
         {
             ret = bdrv_snapshot_delete(bs, name);
@@ -1674,12 +1658,30 @@ void do_savevm(Monitor *mon, const QDict *qdict)
 #endif
     const char *name = qdict_get_try_str(qdict, "name");
 
+    /* Verify if there is have a device that doesn't support snapshots and is writable*/
+    ret = 0;
+    QTAILQ_FOREACH(dinfo, &drives, next) {
+        bs = dinfo->bdrv;
+
+        if (bdrv_is_removable(bs) || bdrv_is_read_only(bs)) {
+            continue;
+        }
+
+        if ((ret = bdrv_can_snapshot(bs)) < 0) {
+            monitor_printf(mon, "Device '%s' is writable but does not support snapshots.\n",
+                               bdrv_get_device_name(bs));
+        }
+    }
+
+    if (ret < 0) {
+        goto the_end;
+    }
+
     bs = get_bs_snapshots();
     if (!bs) {
         monitor_printf(mon, "No block device can accept snapshots\n");
         return;
     }
-
     /* ??? Should this occur after vm_stop?  */
     qemu_aio_flush();
 
@@ -1732,7 +1734,7 @@ void do_savevm(Monitor *mon, const QDict *qdict)
 
     QTAILQ_FOREACH(dinfo, &drives, next) {
         bs1 = dinfo->bdrv;
-        if (bdrv_has_snapshot(bs1)) {
+        if (bdrv_can_snapshot(bs1) > 0) {
             /* Write VM state size only to the image that contains the state */
             sn->vm_state_size = (bs == bs1 ? vm_state_size : 0);
             ret = bdrv_snapshot_create(bs1, sn);
@@ -1767,7 +1769,7 @@ int load_vmstate(const char *name)
 
     QTAILQ_FOREACH(dinfo, &drives, next) {
         bs1 = dinfo->bdrv;
-        if (bdrv_has_snapshot(bs1)) {
+        if (bdrv_has_snapshot(bs1) > 0) {
             ret = bdrv_snapshot_goto(bs1, name);
             if (ret < 0) {
                 switch(ret) {
@@ -1829,7 +1831,7 @@ void do_delvm(Monitor *mon, const QDict *qdict)
 
     QTAILQ_FOREACH(dinfo, &drives, next) {
         bs1 = dinfo->bdrv;
-        if (bdrv_has_snapshot(bs1)) {
+        if (bdrv_has_snapshot(bs1) > 0) {
             ret = bdrv_snapshot_delete(bs1, name);
             if (ret < 0) {
                 if (ret == -ENOTSUP)
@@ -1860,7 +1862,7 @@ void do_info_snapshots(Monitor *mon)
     monitor_printf(mon, "Snapshot devices:");
     QTAILQ_FOREACH(dinfo, &drives, next) {
         bs1 = dinfo->bdrv;
-        if (bdrv_has_snapshot(bs1)) {
+        if (bdrv_can_snapshot(bs1) > 0) {
             if (bs == bs1)
                 monitor_printf(mon, " %s", bdrv_get_device_name(bs1));
         }
