more dummy regs & clean-up for twl4030
[qemu] / savevm.c
index 1ee5a6f..ce12628 100644 (file)
--- a/savevm.c
+++ b/savevm.c
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
-#include "qemu-common.h"
-#include "hw/hw.h"
-#include "net.h"
-#include "console.h"
-#include "sysemu.h"
-#include "qemu-timer.h"
-#include "qemu-char.h"
-#include "block.h"
-#include "audio/audio.h"
-#include "migration.h"
-#include "qemu_socket.h"
-
 #include <unistd.h>
 #include <fcntl.h>
 #include <signal.h>
@@ -41,6 +29,9 @@
 #include <sys/time.h>
 #include <zlib.h>
 
+/* Needed early for HOST_BSD etc. */
+#include "config-host.h"
+
 #ifndef _WIN32
 #include <sys/times.h>
 #include <sys/wait.h>
@@ -61,9 +52,9 @@
 #include <dirent.h>
 #include <netdb.h>
 #include <sys/select.h>
-#ifdef _BSD
+#ifdef HOST_BSD
 #include <sys/stat.h>
-#ifdef __FreeBSD__
+#if defined(__FreeBSD__) || defined(__DragonFly__)
 #include <libutil.h>
 #else
 #include <util.h>
@@ -80,6 +71,7 @@
 #endif
 
 #ifdef _WIN32
+#include <windows.h>
 #include <malloc.h>
 #include <sys/timeb.h>
 #include <mmsystem.h>
 #define memalign(align, size) malloc(size)
 #endif
 
+#include "qemu-common.h"
+#include "hw/hw.h"
+#include "net.h"
+#include "monitor.h"
+#include "sysemu.h"
+#include "qemu-timer.h"
+#include "qemu-char.h"
+#include "block.h"
+#include "audio/audio.h"
+#include "migration.h"
+#include "qemu_socket.h"
+
 /* point to the block driver where the snapshots are managed */
 static BlockDriverState *bs_snapshots;
 
@@ -118,7 +122,9 @@ void qemu_announce_self(void)
     VLANClientState *vc;
     uint8_t buf[256];
 
-    for (i = 0; i < nb_nics; i++) {
+    for (i = 0; i < MAX_NICS; i++) {
+        if (!nd_table[i].used)
+            continue;
         len = announce_self_create(buf, nd_table[i].macaddr);
         vlan = nd_table[i].vlan;
         for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
@@ -214,10 +220,6 @@ QEMUFile *qemu_popen(FILE *popen_file, const char *mode)
     }
 
     s = qemu_mallocz(sizeof(QEMUFilePopen));
-    if (!s) {
-        fprintf(stderr, "qemu_popen: malloc failed\n");
-        return NULL;
-    }
 
     s->popen_file = popen_file;
 
@@ -246,9 +248,6 @@ QEMUFile *qemu_fopen_socket(int fd)
 {
     QEMUFileSocket *s = qemu_mallocz(sizeof(QEMUFileSocket));
 
-    if (s == NULL)
-        return NULL;
-
     s->fd = fd;
     s->file = qemu_fopen_ops(s, NULL, socket_get_buffer, socket_close, NULL);
     return s->file;
@@ -288,8 +287,6 @@ QEMUFile *qemu_fopen(const char *filename, const char *mode)
     QEMUFileStdio *s;
 
     s = qemu_mallocz(sizeof(QEMUFileStdio));
-    if (!s)
-        return NULL;
 
     s->outfile = fopen(filename, mode);
     if (!s->outfile)
@@ -339,8 +336,6 @@ static QEMUFile *qemu_fopen_bdrv(BlockDriverState *bs, int64_t offset, int is_wr
     QEMUFileBdrv *s;
 
     s = qemu_mallocz(sizeof(QEMUFileBdrv));
-    if (!s)
-        return NULL;
 
     s->bs = bs;
     s->base_offset = offset;
@@ -359,8 +354,6 @@ QEMUFile *qemu_fopen_ops(void *opaque, QEMUFilePutBufferFunc *put_buffer,
     QEMUFile *f;
 
     f = qemu_mallocz(sizeof(QEMUFile));
-    if (!f)
-        return NULL;
 
     f->opaque = opaque;
     f->put_buffer = put_buffer;
@@ -615,8 +608,6 @@ int register_savevm_live(const char *idstr,
     static int global_section_id;
 
     se = qemu_malloc(sizeof(SaveStateEntry));
-    if (!se)
-        return -1;
     pstrcpy(se->idstr, sizeof(se->idstr), idstr);
     se->instance_id = (instance_id == -1) ? 0 : instance_id;
     se->version_id = version_id;
@@ -908,10 +899,6 @@ int qemu_loadvm_state(QEMUFile *f)
 
             /* Add entry */
             le = qemu_mallocz(sizeof(*le));
-            if (le == NULL) {
-                ret = -ENOMEM;
-                goto out;
-            }
 
             le->se = se;
             le->section_id = section_id;
@@ -1012,7 +999,7 @@ static int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info,
     return ret;
 }
 
-void do_savevm(const char *name)
+void do_savevm(Monitor *mon, const char *name)
 {
     BlockDriverState *bs, *bs1;
     QEMUSnapshotInfo sn1, *sn = &sn1, old_sn1, *old_sn = &old_sn1;
@@ -1020,6 +1007,7 @@ void do_savevm(const char *name)
     BlockDriverInfo bdi1, *bdi = &bdi1;
     QEMUFile *f;
     int saved_vm_running;
+    uint32_t vm_state_size;
 #ifdef _WIN32
     struct _timeb tb;
 #else
@@ -1028,7 +1016,7 @@ void do_savevm(const char *name)
 
     bs = get_bs_snapshots();
     if (!bs) {
-        term_printf("No block device can accept snapshots\n");
+        monitor_printf(mon, "No block device can accept snapshots\n");
         return;
     }
 
@@ -1067,22 +1055,22 @@ void do_savevm(const char *name)
     sn->vm_clock_nsec = qemu_get_clock(vm_clock);
 
     if (bdrv_get_info(bs, bdi) < 0 || bdi->vm_state_offset <= 0) {
-        term_printf("Device %s does not support VM state snapshots\n",
-                    bdrv_get_device_name(bs));
+        monitor_printf(mon, "Device %s does not support VM state snapshots\n",
+                       bdrv_get_device_name(bs));
         goto the_end;
     }
 
     /* save the VM state */
     f = qemu_fopen_bdrv(bs, bdi->vm_state_offset, 1);
     if (!f) {
-        term_printf("Could not open VM state file\n");
+        monitor_printf(mon, "Could not open VM state file\n");
         goto the_end;
     }
     ret = qemu_savevm_state(f);
-    sn->vm_state_size = qemu_ftell(f);
+    vm_state_size = qemu_ftell(f);
     qemu_fclose(f);
     if (ret < 0) {
-        term_printf("Error %d while writing VM\n", ret);
+        monitor_printf(mon, "Error %d while writing VM\n", ret);
         goto the_end;
     }
 
@@ -1094,14 +1082,17 @@ void do_savevm(const char *name)
             if (must_delete) {
                 ret = bdrv_snapshot_delete(bs1, old_sn->id_str);
                 if (ret < 0) {
-                    term_printf("Error while deleting snapshot on '%s'\n",
-                                bdrv_get_device_name(bs1));
+                    monitor_printf(mon,
+                                   "Error while deleting snapshot on '%s'\n",
+                                   bdrv_get_device_name(bs1));
                 }
             }
+            /* 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);
             if (ret < 0) {
-                term_printf("Error while creating snapshot on '%s'\n",
-                            bdrv_get_device_name(bs1));
+                monitor_printf(mon, "Error while creating snapshot on '%s'\n",
+                               bdrv_get_device_name(bs1));
             }
         }
     }
@@ -1111,17 +1102,18 @@ void do_savevm(const char *name)
         vm_start();
 }
 
-void do_loadvm(const char *name)
+void do_loadvm(Monitor *mon, const char *name)
 {
     BlockDriverState *bs, *bs1;
     BlockDriverInfo bdi1, *bdi = &bdi1;
+    QEMUSnapshotInfo sn;
     QEMUFile *f;
     int i, ret;
     int saved_vm_running;
 
     bs = get_bs_snapshots();
     if (!bs) {
-        term_printf("No block device supports snapshots\n");
+        monitor_printf(mon, "No block device supports snapshots\n");
         return;
     }
 
@@ -1137,19 +1129,21 @@ void do_loadvm(const char *name)
             ret = bdrv_snapshot_goto(bs1, name);
             if (ret < 0) {
                 if (bs != bs1)
-                    term_printf("Warning: ");
+                    monitor_printf(mon, "Warning: ");
                 switch(ret) {
                 case -ENOTSUP:
-                    term_printf("Snapshots not supported on device '%s'\n",
-                                bdrv_get_device_name(bs1));
+                    monitor_printf(mon,
+                                   "Snapshots not supported on device '%s'\n",
+                                   bdrv_get_device_name(bs1));
                     break;
                 case -ENOENT:
-                    term_printf("Could not find snapshot '%s' on device '%s'\n",
-                                name, bdrv_get_device_name(bs1));
+                    monitor_printf(mon, "Could not find snapshot '%s' on "
+                                   "device '%s'\n",
+                                   name, bdrv_get_device_name(bs1));
                     break;
                 default:
-                    term_printf("Error %d while activating snapshot on '%s'\n",
-                                ret, bdrv_get_device_name(bs1));
+                    monitor_printf(mon, "Error %d while activating snapshot on"
+                                   " '%s'\n", ret, bdrv_get_device_name(bs1));
                     break;
                 }
                 /* fatal on snapshot block device */
@@ -1160,35 +1154,40 @@ void do_loadvm(const char *name)
     }
 
     if (bdrv_get_info(bs, bdi) < 0 || bdi->vm_state_offset <= 0) {
-        term_printf("Device %s does not support VM state snapshots\n",
-                    bdrv_get_device_name(bs));
+        monitor_printf(mon, "Device %s does not support VM state snapshots\n",
+                       bdrv_get_device_name(bs));
         return;
     }
 
+    /* Don't even try to load empty VM states */
+    ret = bdrv_snapshot_find(bs, &sn, name);
+    if ((ret >= 0) && (sn.vm_state_size == 0))
+        goto the_end;
+
     /* restore the VM state */
     f = qemu_fopen_bdrv(bs, bdi->vm_state_offset, 0);
     if (!f) {
-        term_printf("Could not open VM state file\n");
+        monitor_printf(mon, "Could not open VM state file\n");
         goto the_end;
     }
     ret = qemu_loadvm_state(f);
     qemu_fclose(f);
     if (ret < 0) {
-        term_printf("Error %d while loading VM state\n", ret);
+        monitor_printf(mon, "Error %d while loading VM state\n", ret);
     }
  the_end:
     if (saved_vm_running)
         vm_start();
 }
 
-void do_delvm(const char *name)
+void do_delvm(Monitor *mon, const char *name)
 {
     BlockDriverState *bs, *bs1;
     int i, ret;
 
     bs = get_bs_snapshots();
     if (!bs) {
-        term_printf("No block device supports snapshots\n");
+        monitor_printf(mon, "No block device supports snapshots\n");
         return;
     }
 
@@ -1198,17 +1197,18 @@ void do_delvm(const char *name)
             ret = bdrv_snapshot_delete(bs1, name);
             if (ret < 0) {
                 if (ret == -ENOTSUP)
-                    term_printf("Snapshots not supported on device '%s'\n",
-                                bdrv_get_device_name(bs1));
+                    monitor_printf(mon,
+                                   "Snapshots not supported on device '%s'\n",
+                                   bdrv_get_device_name(bs1));
                 else
-                    term_printf("Error %d while deleting snapshot on '%s'\n",
-                                ret, bdrv_get_device_name(bs1));
+                    monitor_printf(mon, "Error %d while deleting snapshot on "
+                                   "'%s'\n", ret, bdrv_get_device_name(bs1));
             }
         }
     }
 }
 
-void do_info_snapshots(void)
+void do_info_snapshots(Monitor *mon)
 {
     BlockDriverState *bs, *bs1;
     QEMUSnapshotInfo *sn_tab, *sn;
@@ -1217,29 +1217,30 @@ void do_info_snapshots(void)
 
     bs = get_bs_snapshots();
     if (!bs) {
-        term_printf("No available block device supports snapshots\n");
+        monitor_printf(mon, "No available block device supports snapshots\n");
         return;
     }
-    term_printf("Snapshot devices:");
+    monitor_printf(mon, "Snapshot devices:");
     for(i = 0; i <= nb_drives; i++) {
         bs1 = drives_table[i].bdrv;
         if (bdrv_has_snapshot(bs1)) {
             if (bs == bs1)
-                term_printf(" %s", bdrv_get_device_name(bs1));
+                monitor_printf(mon, " %s", bdrv_get_device_name(bs1));
         }
     }
-    term_printf("\n");
+    monitor_printf(mon, "\n");
 
     nb_sns = bdrv_snapshot_list(bs, &sn_tab);
     if (nb_sns < 0) {
-        term_printf("bdrv_snapshot_list: error %d\n", nb_sns);
+        monitor_printf(mon, "bdrv_snapshot_list: error %d\n", nb_sns);
         return;
     }
-    term_printf("Snapshot list (from %s):\n", bdrv_get_device_name(bs));
-    term_printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
+    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++) {
         sn = &sn_tab[i];
-        term_printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
+        monitor_printf(mon, "%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
     }
     qemu_free(sn_tab);
 }