Diff for /qemu/savevm.c between versions 1.1.1.10 and 1.1.1.11

version 1.1.1.10, 2018/04/24 18:55:59 version 1.1.1.11, 2018/04/24 19:17:03
Line 81 Line 81
 #include "migration.h"  #include "migration.h"
 #include "qemu_socket.h"  #include "qemu_socket.h"
 #include "qemu-queue.h"  #include "qemu-queue.h"
   #include "qemu-timer.h"
 #include "cpus.h"  #include "cpus.h"
   
 #define SELF_ANNOUNCE_ROUNDS 5  #define SELF_ANNOUNCE_ROUNDS 5
Line 173  struct QEMUFile { Line 174  struct QEMUFile {
     int buf_size; /* 0 when writing */      int buf_size; /* 0 when writing */
     uint8_t buf[IO_BUF_SIZE];      uint8_t buf[IO_BUF_SIZE];
   
     int has_error;      int last_error;
 };  };
   
 typedef struct QEMUFileStdio  typedef struct QEMUFileStdio
Line 206  static int socket_get_buffer(void *opaqu Line 207  static int socket_get_buffer(void *opaqu
 static int socket_close(void *opaque)  static int socket_close(void *opaque)
 {  {
     QEMUFileSocket *s = opaque;      QEMUFileSocket *s = opaque;
     qemu_free(s);      g_free(s);
     return 0;      return 0;
 }  }
   
Line 234  static int stdio_pclose(void *opaque) Line 235  static int stdio_pclose(void *opaque)
     QEMUFileStdio *s = opaque;      QEMUFileStdio *s = opaque;
     int ret;      int ret;
     ret = pclose(s->stdio_file);      ret = pclose(s->stdio_file);
     qemu_free(s);      g_free(s);
     return ret;      return ret;
 }  }
   
Line 242  static int stdio_fclose(void *opaque) Line 243  static int stdio_fclose(void *opaque)
 {  {
     QEMUFileStdio *s = opaque;      QEMUFileStdio *s = opaque;
     fclose(s->stdio_file);      fclose(s->stdio_file);
     qemu_free(s);      g_free(s);
     return 0;      return 0;
 }  }
   
Line 255  QEMUFile *qemu_popen(FILE *stdio_file, c Line 256  QEMUFile *qemu_popen(FILE *stdio_file, c
         return NULL;          return NULL;
     }      }
   
     s = qemu_mallocz(sizeof(QEMUFileStdio));      s = g_malloc0(sizeof(QEMUFileStdio));
   
     s->stdio_file = stdio_file;      s->stdio_file = stdio_file;
   
Line 303  QEMUFile *qemu_fdopen(int fd, const char Line 304  QEMUFile *qemu_fdopen(int fd, const char
         return NULL;          return NULL;
     }      }
   
     s = qemu_mallocz(sizeof(QEMUFileStdio));      s = g_malloc0(sizeof(QEMUFileStdio));
     s->stdio_file = fdopen(fd, mode);      s->stdio_file = fdopen(fd, mode);
     if (!s->stdio_file)      if (!s->stdio_file)
         goto fail;          goto fail;
Line 318  QEMUFile *qemu_fdopen(int fd, const char Line 319  QEMUFile *qemu_fdopen(int fd, const char
     return s->file;      return s->file;
   
 fail:  fail:
     qemu_free(s);      g_free(s);
     return NULL;      return NULL;
 }  }
   
 QEMUFile *qemu_fopen_socket(int fd)  QEMUFile *qemu_fopen_socket(int fd)
 {  {
     QEMUFileSocket *s = qemu_mallocz(sizeof(QEMUFileSocket));      QEMUFileSocket *s = g_malloc0(sizeof(QEMUFileSocket));
   
     s->fd = fd;      s->fd = fd;
     s->file = qemu_fopen_ops(s, NULL, socket_get_buffer, socket_close,       s->file = qemu_fopen_ops(s, NULL, socket_get_buffer, socket_close, 
Line 358  QEMUFile *qemu_fopen(const char *filenam Line 359  QEMUFile *qemu_fopen(const char *filenam
         return NULL;          return NULL;
     }      }
   
     s = qemu_mallocz(sizeof(QEMUFileStdio));      s = g_malloc0(sizeof(QEMUFileStdio));
   
     s->stdio_file = fopen(filename, mode);      s->stdio_file = fopen(filename, mode);
     if (!s->stdio_file)      if (!s->stdio_file)
Line 373  QEMUFile *qemu_fopen(const char *filenam Line 374  QEMUFile *qemu_fopen(const char *filenam
     }      }
     return s->file;      return s->file;
 fail:  fail:
     qemu_free(s);      g_free(s);
     return NULL;      return NULL;
 }  }
   
Line 411  QEMUFile *qemu_fopen_ops(void *opaque, Q Line 412  QEMUFile *qemu_fopen_ops(void *opaque, Q
 {  {
     QEMUFile *f;      QEMUFile *f;
   
     f = qemu_mallocz(sizeof(QEMUFile));      f = g_malloc0(sizeof(QEMUFile));
   
     f->opaque = opaque;      f->opaque = opaque;
     f->put_buffer = put_buffer;      f->put_buffer = put_buffer;
Line 425  QEMUFile *qemu_fopen_ops(void *opaque, Q Line 426  QEMUFile *qemu_fopen_ops(void *opaque, Q
     return f;      return f;
 }  }
   
 int qemu_file_has_error(QEMUFile *f)  int qemu_file_get_error(QEMUFile *f)
 {  {
     return f->has_error;      return f->last_error;
 }  }
   
 void qemu_file_set_error(QEMUFile *f)  void qemu_file_set_error(QEMUFile *f, int ret)
 {  {
     f->has_error = 1;      f->last_error = ret;
 }  }
   
 void qemu_fflush(QEMUFile *f)  void qemu_fflush(QEMUFile *f)
Line 447  void qemu_fflush(QEMUFile *f) Line 448  void qemu_fflush(QEMUFile *f)
         if (len > 0)          if (len > 0)
             f->buf_offset += f->buf_index;              f->buf_offset += f->buf_index;
         else          else
             f->has_error = 1;              f->last_error = -EINVAL;
         f->buf_index = 0;          f->buf_index = 0;
     }      }
 }  }
Line 455  void qemu_fflush(QEMUFile *f) Line 456  void qemu_fflush(QEMUFile *f)
 static void qemu_fill_buffer(QEMUFile *f)  static void qemu_fill_buffer(QEMUFile *f)
 {  {
     int len;      int len;
       int pending;
   
     if (!f->get_buffer)      if (!f->get_buffer)
         return;          return;
Line 462  static void qemu_fill_buffer(QEMUFile *f Line 464  static void qemu_fill_buffer(QEMUFile *f
     if (f->is_write)      if (f->is_write)
         abort();          abort();
   
     len = f->get_buffer(f->opaque, f->buf, f->buf_offset, IO_BUF_SIZE);      pending = f->buf_size - f->buf_index;
       if (pending > 0) {
           memmove(f->buf, f->buf + f->buf_index, pending);
       }
       f->buf_index = 0;
       f->buf_size = pending;
   
       len = f->get_buffer(f->opaque, f->buf + pending, f->buf_offset,
                           IO_BUF_SIZE - pending);
     if (len > 0) {      if (len > 0) {
         f->buf_index = 0;          f->buf_size += len;
         f->buf_size = len;  
         f->buf_offset += len;          f->buf_offset += len;
       } else if (len == 0) {
           f->last_error = -EIO;
     } else if (len != -EAGAIN)      } else if (len != -EAGAIN)
         f->has_error = 1;          f->last_error = len;
 }  }
   
 int qemu_fclose(QEMUFile *f)  int qemu_fclose(QEMUFile *f)
Line 477  int qemu_fclose(QEMUFile *f) Line 488  int qemu_fclose(QEMUFile *f)
     qemu_fflush(f);      qemu_fflush(f);
     if (f->close)      if (f->close)
         ret = f->close(f->opaque);          ret = f->close(f->opaque);
     qemu_free(f);      g_free(f);
     return ret;      return ret;
 }  }
   
Line 490  void qemu_put_buffer(QEMUFile *f, const  Line 501  void qemu_put_buffer(QEMUFile *f, const 
 {  {
     int l;      int l;
   
     if (!f->has_error && f->is_write == 0 && f->buf_index > 0) {      if (!f->last_error && f->is_write == 0 && f->buf_index > 0) {
         fprintf(stderr,          fprintf(stderr,
                 "Attempted to write to buffer while read buffer is not empty\n");                  "Attempted to write to buffer while read buffer is not empty\n");
         abort();          abort();
     }      }
   
     while (!f->has_error && size > 0) {      while (!f->last_error && size > 0) {
         l = IO_BUF_SIZE - f->buf_index;          l = IO_BUF_SIZE - f->buf_index;
         if (l > size)          if (l > size)
             l = size;              l = size;
Line 512  void qemu_put_buffer(QEMUFile *f, const  Line 523  void qemu_put_buffer(QEMUFile *f, const 
   
 void qemu_put_byte(QEMUFile *f, int v)  void qemu_put_byte(QEMUFile *f, int v)
 {  {
     if (!f->has_error && f->is_write == 0 && f->buf_index > 0) {      if (!f->last_error && f->is_write == 0 && f->buf_index > 0) {
         fprintf(stderr,          fprintf(stderr,
                 "Attempted to write to buffer while read buffer is not empty\n");                  "Attempted to write to buffer while read buffer is not empty\n");
         abort();          abort();
Line 524  void qemu_put_byte(QEMUFile *f, int v) Line 535  void qemu_put_byte(QEMUFile *f, int v)
         qemu_fflush(f);          qemu_fflush(f);
 }  }
   
 int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size1)  static void qemu_file_skip(QEMUFile *f, int size)
   {
       if (f->buf_index + size <= f->buf_size) {
           f->buf_index += size;
       }
   }
   
   static int qemu_peek_buffer(QEMUFile *f, uint8_t *buf, int size, size_t offset)
 {  {
     int size, l;      int pending;
       int index;
   
     if (f->is_write)      if (f->is_write) {
         abort();          abort();
       }
   
     size = size1;      index = f->buf_index + offset;
     while (size > 0) {      pending = f->buf_size - index;
         l = f->buf_size - f->buf_index;      if (pending < size) {
         if (l == 0) {          qemu_fill_buffer(f);
             qemu_fill_buffer(f);          index = f->buf_index + offset;
             l = f->buf_size - f->buf_index;          pending = f->buf_size - index;
             if (l == 0)      }
                 break;  
       if (pending <= 0) {
           return 0;
       }
       if (size > pending) {
           size = pending;
       }
   
       memcpy(buf, f->buf + index, size);
       return size;
   }
   
   int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size)
   {
       int pending = size;
       int done = 0;
   
       while (pending > 0) {
           int res;
   
           res = qemu_peek_buffer(f, buf, pending, 0);
           if (res == 0) {
               return done;
         }          }
         if (l > size)          qemu_file_skip(f, res);
             l = size;          buf += res;
         memcpy(buf, f->buf + f->buf_index, l);          pending -= res;
         f->buf_index += l;          done += res;
         buf += l;  
         size -= l;  
     }      }
     return size1 - size;      return done;
 }  }
   
 static int qemu_peek_byte(QEMUFile *f)  static int qemu_peek_byte(QEMUFile *f, int offset)
 {  {
     if (f->is_write)      int index = f->buf_index + offset;
   
       if (f->is_write) {
         abort();          abort();
       }
   
     if (f->buf_index >= f->buf_size) {      if (index >= f->buf_size) {
         qemu_fill_buffer(f);          qemu_fill_buffer(f);
         if (f->buf_index >= f->buf_size)          index = f->buf_index + offset;
           if (index >= f->buf_size) {
             return 0;              return 0;
           }
     }      }
     return f->buf[f->buf_index];      return f->buf[index];
 }  }
   
 int qemu_get_byte(QEMUFile *f)  int qemu_get_byte(QEMUFile *f)
 {  {
     if (f->is_write)      int result;
         abort();  
   
     if (f->buf_index >= f->buf_size) {      result = qemu_peek_byte(f, 0);
         qemu_fill_buffer(f);      qemu_file_skip(f, 1);
         if (f->buf_index >= f->buf_size)      return result;
             return 0;  
     }  
     return f->buf[f->buf_index++];  
 }  }
   
 int64_t qemu_ftell(QEMUFile *f)  int64_t qemu_ftell(QEMUFile *f)
Line 674  uint64_t qemu_get_be64(QEMUFile *f) Line 715  uint64_t qemu_get_be64(QEMUFile *f)
     return v;      return v;
 }  }
   
   
   /* timer */
   
   void qemu_put_timer(QEMUFile *f, QEMUTimer *ts)
   {
       uint64_t expire_time;
   
       expire_time = qemu_timer_expire_time_ns(ts);
       qemu_put_be64(f, expire_time);
   }
   
   void qemu_get_timer(QEMUFile *f, QEMUTimer *ts)
   {
       uint64_t expire_time;
   
       expire_time = qemu_get_be64(f);
       if (expire_time != -1) {
           qemu_mod_timer_ns(ts, expire_time);
       } else {
           qemu_del_timer(ts);
       }
   }
   
   
 /* bool */  /* bool */
   
 static int get_bool(QEMUFile *f, void *pv, size_t size)  static int get_bool(QEMUFile *f, void *pv, size_t size)
Line 1114  int register_savevm_live(DeviceState *de Line 1179  int register_savevm_live(DeviceState *de
 {  {
     SaveStateEntry *se;      SaveStateEntry *se;
   
     se = qemu_mallocz(sizeof(SaveStateEntry));      se = g_malloc0(sizeof(SaveStateEntry));
     se->version_id = version_id;      se->version_id = version_id;
     se->section_id = global_section_id++;      se->section_id = global_section_id++;
     se->set_params = set_params;      se->set_params = set_params;
Line 1130  int register_savevm_live(DeviceState *de Line 1195  int register_savevm_live(DeviceState *de
         if (id) {          if (id) {
             pstrcpy(se->idstr, sizeof(se->idstr), id);              pstrcpy(se->idstr, sizeof(se->idstr), id);
             pstrcat(se->idstr, sizeof(se->idstr), "/");              pstrcat(se->idstr, sizeof(se->idstr), "/");
             qemu_free(id);              g_free(id);
   
             se->compat = qemu_mallocz(sizeof(CompatEntry));              se->compat = g_malloc0(sizeof(CompatEntry));
             pstrcpy(se->compat->idstr, sizeof(se->compat->idstr), idstr);              pstrcpy(se->compat->idstr, sizeof(se->compat->idstr), idstr);
             se->compat->instance_id = instance_id == -1 ?              se->compat->instance_id = instance_id == -1 ?
                          calculate_compat_instance_id(idstr) : instance_id;                           calculate_compat_instance_id(idstr) : instance_id;
Line 1174  void unregister_savevm(DeviceState *dev, Line 1239  void unregister_savevm(DeviceState *dev,
         if (path) {          if (path) {
             pstrcpy(id, sizeof(id), path);              pstrcpy(id, sizeof(id), path);
             pstrcat(id, sizeof(id), "/");              pstrcat(id, sizeof(id), "/");
             qemu_free(path);              g_free(path);
         }          }
     }      }
     pstrcat(id, sizeof(id), idstr);      pstrcat(id, sizeof(id), idstr);
Line 1183  void unregister_savevm(DeviceState *dev, Line 1248  void unregister_savevm(DeviceState *dev,
         if (strcmp(se->idstr, id) == 0 && se->opaque == opaque) {          if (strcmp(se->idstr, id) == 0 && se->opaque == opaque) {
             QTAILQ_REMOVE(&savevm_handlers, se, entry);              QTAILQ_REMOVE(&savevm_handlers, se, entry);
             if (se->compat) {              if (se->compat) {
                 qemu_free(se->compat);                  g_free(se->compat);
             }              }
             qemu_free(se);              g_free(se);
         }  
     }  
 }  
   
 /* mark a device as not to be migrated, that is the device should be  
    unplugged before migration */  
 void register_device_unmigratable(DeviceState *dev, const char *idstr,  
                                                             void *opaque)  
 {  
     SaveStateEntry *se;  
     char id[256] = "";  
   
     if (dev && dev->parent_bus && dev->parent_bus->info->get_dev_path) {  
         char *path = dev->parent_bus->info->get_dev_path(dev);  
         if (path) {  
             pstrcpy(id, sizeof(id), path);  
             pstrcat(id, sizeof(id), "/");  
             qemu_free(path);  
         }  
     }  
     pstrcat(id, sizeof(id), idstr);  
   
     QTAILQ_FOREACH(se, &savevm_handlers, entry) {  
         if (strcmp(se->idstr, id) == 0 && se->opaque == opaque) {  
             se->no_migrate = 1;  
         }          }
     }      }
 }  }
Line 1225  int vmstate_register_with_alias_id(Devic Line 1265  int vmstate_register_with_alias_id(Devic
     /* If this triggers, alias support can be dropped for the vmsd. */      /* If this triggers, alias support can be dropped for the vmsd. */
     assert(alias_id == -1 || required_for_version >= vmsd->minimum_version_id);      assert(alias_id == -1 || required_for_version >= vmsd->minimum_version_id);
   
     se = qemu_mallocz(sizeof(SaveStateEntry));      se = g_malloc0(sizeof(SaveStateEntry));
     se->version_id = vmsd->version_id;      se->version_id = vmsd->version_id;
     se->section_id = global_section_id++;      se->section_id = global_section_id++;
     se->save_live_state = NULL;      se->save_live_state = NULL;
Line 1234  int vmstate_register_with_alias_id(Devic Line 1274  int vmstate_register_with_alias_id(Devic
     se->opaque = opaque;      se->opaque = opaque;
     se->vmsd = vmsd;      se->vmsd = vmsd;
     se->alias_id = alias_id;      se->alias_id = alias_id;
       se->no_migrate = vmsd->unmigratable;
   
     if (dev && dev->parent_bus && dev->parent_bus->info->get_dev_path) {      if (dev && dev->parent_bus && dev->parent_bus->info->get_dev_path) {
         char *id = dev->parent_bus->info->get_dev_path(dev);          char *id = dev->parent_bus->info->get_dev_path(dev);
         if (id) {          if (id) {
             pstrcpy(se->idstr, sizeof(se->idstr), id);              pstrcpy(se->idstr, sizeof(se->idstr), id);
             pstrcat(se->idstr, sizeof(se->idstr), "/");              pstrcat(se->idstr, sizeof(se->idstr), "/");
             qemu_free(id);              g_free(id);
   
             se->compat = qemu_mallocz(sizeof(CompatEntry));              se->compat = g_malloc0(sizeof(CompatEntry));
             pstrcpy(se->compat->idstr, sizeof(se->compat->idstr), vmsd->name);              pstrcpy(se->compat->idstr, sizeof(se->compat->idstr), vmsd->name);
             se->compat->instance_id = instance_id == -1 ?              se->compat->instance_id = instance_id == -1 ?
                          calculate_compat_instance_id(vmsd->name) : instance_id;                           calculate_compat_instance_id(vmsd->name) : instance_id;
Line 1278  void vmstate_unregister(DeviceState *dev Line 1319  void vmstate_unregister(DeviceState *dev
         if (se->vmsd == vmsd && se->opaque == opaque) {          if (se->vmsd == vmsd && se->opaque == opaque) {
             QTAILQ_REMOVE(&savevm_handlers, se, entry);              QTAILQ_REMOVE(&savevm_handlers, se, entry);
             if (se->compat) {              if (se->compat) {
                 qemu_free(se->compat);                  g_free(se->compat);
             }              }
             qemu_free(se);              g_free(se);
         }          }
     }      }
 }  }
Line 1465  int qemu_savevm_state_begin(Monitor *mon Line 1506  int qemu_savevm_state_begin(Monitor *mon
                             int shared)                              int shared)
 {  {
     SaveStateEntry *se;      SaveStateEntry *se;
       int ret;
   
     QTAILQ_FOREACH(se, &savevm_handlers, entry) {      QTAILQ_FOREACH(se, &savevm_handlers, entry) {
         if(se->set_params == NULL) {          if(se->set_params == NULL) {
Line 1494  int qemu_savevm_state_begin(Monitor *mon Line 1536  int qemu_savevm_state_begin(Monitor *mon
         qemu_put_be32(f, se->instance_id);          qemu_put_be32(f, se->instance_id);
         qemu_put_be32(f, se->version_id);          qemu_put_be32(f, se->version_id);
   
         se->save_live_state(mon, f, QEMU_VM_SECTION_START, se->opaque);          ret = se->save_live_state(mon, f, QEMU_VM_SECTION_START, se->opaque);
           if (ret < 0) {
               qemu_savevm_state_cancel(mon, f);
               return ret;
           }
     }      }
       ret = qemu_file_get_error(f);
     if (qemu_file_has_error(f)) {      if (ret != 0) {
         qemu_savevm_state_cancel(mon, f);          qemu_savevm_state_cancel(mon, f);
         return -EIO;  
     }      }
   
     return 0;      return ret;
   
 }  }
   
   /*
    * this funtion has three return values:
    *   negative: there was one error, and we have -errno.
    *   0 : We haven't finished, caller have to go again
    *   1 : We have finished, we can go to complete phase
    */
 int qemu_savevm_state_iterate(Monitor *mon, QEMUFile *f)  int qemu_savevm_state_iterate(Monitor *mon, QEMUFile *f)
 {  {
     SaveStateEntry *se;      SaveStateEntry *se;
Line 1519  int qemu_savevm_state_iterate(Monitor *m Line 1571  int qemu_savevm_state_iterate(Monitor *m
         qemu_put_be32(f, se->section_id);          qemu_put_be32(f, se->section_id);
   
         ret = se->save_live_state(mon, f, QEMU_VM_SECTION_PART, se->opaque);          ret = se->save_live_state(mon, f, QEMU_VM_SECTION_PART, se->opaque);
         if (!ret) {          if (ret <= 0) {
             /* Do not proceed to the next vmstate before this one reported              /* Do not proceed to the next vmstate before this one reported
                completion of the current stage. This serializes the migration                 completion of the current stage. This serializes the migration
                and reduces the probability that a faster changing state is                 and reduces the probability that a faster changing state is
Line 1527  int qemu_savevm_state_iterate(Monitor *m Line 1579  int qemu_savevm_state_iterate(Monitor *m
             break;              break;
         }          }
     }      }
       if (ret != 0) {
     if (ret)          return ret;
         return 1;      }
       ret = qemu_file_get_error(f);
     if (qemu_file_has_error(f)) {      if (ret != 0) {
         qemu_savevm_state_cancel(mon, f);          qemu_savevm_state_cancel(mon, f);
         return -EIO;  
     }      }
       return ret;
     return 0;  
 }  }
   
 int qemu_savevm_state_complete(Monitor *mon, QEMUFile *f)  int qemu_savevm_state_complete(Monitor *mon, QEMUFile *f)
 {  {
     SaveStateEntry *se;      SaveStateEntry *se;
       int ret;
   
     cpu_synchronize_all_states();      cpu_synchronize_all_states();
   
Line 1553  int qemu_savevm_state_complete(Monitor * Line 1604  int qemu_savevm_state_complete(Monitor *
         qemu_put_byte(f, QEMU_VM_SECTION_END);          qemu_put_byte(f, QEMU_VM_SECTION_END);
         qemu_put_be32(f, se->section_id);          qemu_put_be32(f, se->section_id);
   
         se->save_live_state(mon, f, QEMU_VM_SECTION_END, se->opaque);          ret = se->save_live_state(mon, f, QEMU_VM_SECTION_END, se->opaque);
           if (ret < 0) {
               return ret;
           }
     }      }
   
     QTAILQ_FOREACH(se, &savevm_handlers, entry) {      QTAILQ_FOREACH(se, &savevm_handlers, entry) {
Line 1579  int qemu_savevm_state_complete(Monitor * Line 1633  int qemu_savevm_state_complete(Monitor *
   
     qemu_put_byte(f, QEMU_VM_EOF);      qemu_put_byte(f, QEMU_VM_EOF);
   
     if (qemu_file_has_error(f))      return qemu_file_get_error(f);
         return -EIO;  
   
     return 0;  
 }  }
   
 void qemu_savevm_state_cancel(Monitor *mon, QEMUFile *f)  void qemu_savevm_state_cancel(Monitor *mon, QEMUFile *f)
Line 1598  void qemu_savevm_state_cancel(Monitor *m Line 1649  void qemu_savevm_state_cancel(Monitor *m
   
 static int qemu_savevm_state(Monitor *mon, QEMUFile *f)  static int qemu_savevm_state(Monitor *mon, QEMUFile *f)
 {  {
     int saved_vm_running;  
     int ret;      int ret;
   
     saved_vm_running = vm_running;  
     vm_stop(VMSTOP_SAVEVM);  
   
     if (qemu_savevm_state_blocked(mon)) {      if (qemu_savevm_state_blocked(mon)) {
         ret = -EINVAL;          ret = -EINVAL;
         goto out;          goto out;
Line 1622  static int qemu_savevm_state(Monitor *mo Line 1669  static int qemu_savevm_state(Monitor *mo
     ret = qemu_savevm_state_complete(mon, f);      ret = qemu_savevm_state_complete(mon, f);
   
 out:  out:
     if (qemu_file_has_error(f))      if (ret == 0) {
         ret = -EIO;          ret = qemu_file_get_error(f);
       }
     if (!ret && saved_vm_running)  
         vm_start();  
   
     return ret;      return ret;
 }  }
Line 1665  static const VMStateDescription *vmstate Line 1710  static const VMStateDescription *vmstate
 static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd,  static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd,
                                    void *opaque)                                     void *opaque)
 {  {
     const VMStateSubsection *sub = vmsd->subsections;      while (qemu_peek_byte(f, 0) == QEMU_VM_SUBSECTION) {
   
     if (!sub || !sub->needed) {  
         return 0;  
     }  
   
     while (qemu_peek_byte(f) == QEMU_VM_SUBSECTION) {  
         char idstr[256];          char idstr[256];
         int ret;          int ret;
         uint8_t version_id, len;          uint8_t version_id, len, size;
         const VMStateDescription *sub_vmsd;          const VMStateDescription *sub_vmsd;
   
         qemu_get_byte(f); /* subsection */          len = qemu_peek_byte(f, 1);
         len = qemu_get_byte(f);          if (len < strlen(vmsd->name) + 1) {
         qemu_get_buffer(f, (uint8_t *)idstr, len);              /* subsection name has be be "section_name/a" */
         idstr[len] = 0;              return 0;
         version_id = qemu_get_be32(f);          }
           size = qemu_peek_buffer(f, (uint8_t *)idstr, len, 2);
           if (size != len) {
               return 0;
           }
           idstr[size] = 0;
   
         sub_vmsd = vmstate_get_subsection(sub, idstr);          if (strncmp(vmsd->name, idstr, strlen(vmsd->name)) != 0) {
               /* it don't have a valid subsection name */
               return 0;
           }
           sub_vmsd = vmstate_get_subsection(vmsd->subsections, idstr);
         if (sub_vmsd == NULL) {          if (sub_vmsd == NULL) {
             return -ENOENT;              return -ENOENT;
         }          }
         assert(!sub_vmsd->subsections);          qemu_file_skip(f, 1); /* subsection */
           qemu_file_skip(f, 1); /* len */
           qemu_file_skip(f, len); /* idstr */
           version_id = qemu_get_be32(f);
   
         ret = vmstate_load_state(f, sub_vmsd, opaque, version_id);          ret = vmstate_load_state(f, sub_vmsd, opaque, version_id);
         if (ret) {          if (ret) {
             return ret;              return ret;
Line 1711  static void vmstate_subsection_save(QEMU Line 1763  static void vmstate_subsection_save(QEMU
             qemu_put_byte(f, len);              qemu_put_byte(f, len);
             qemu_put_buffer(f, (uint8_t *)vmsd->name, len);              qemu_put_buffer(f, (uint8_t *)vmsd->name, len);
             qemu_put_be32(f, vmsd->version_id);              qemu_put_be32(f, vmsd->version_id);
             assert(!vmsd->subsections);  
             vmstate_save_state(f, vmsd, opaque);              vmstate_save_state(f, vmsd, opaque);
         }          }
         sub++;          sub++;
Line 1784  int qemu_loadvm_state(QEMUFile *f) Line 1835  int qemu_loadvm_state(QEMUFile *f)
             }              }
   
             /* Add entry */              /* Add entry */
             le = qemu_mallocz(sizeof(*le));              le = g_malloc0(sizeof(*le));
   
             le->se = se;              le->se = se;
             le->section_id = section_id;              le->section_id = section_id;
Line 1834  int qemu_loadvm_state(QEMUFile *f) Line 1885  int qemu_loadvm_state(QEMUFile *f)
 out:  out:
     QLIST_FOREACH_SAFE(le, &loadvm_handlers, entry, new_le) {      QLIST_FOREACH_SAFE(le, &loadvm_handlers, entry, new_le) {
         QLIST_REMOVE(le, entry);          QLIST_REMOVE(le, entry);
         qemu_free(le);          g_free(le);
     }      }
   
     if (qemu_file_has_error(f))      if (ret == 0) {
         ret = -EIO;          ret = qemu_file_get_error(f);
       }
   
     return ret;      return ret;
 }  }
Line 1861  static int bdrv_snapshot_find(BlockDrive Line 1913  static int bdrv_snapshot_find(BlockDrive
             break;              break;
         }          }
     }      }
     qemu_free(sn_tab);      g_free(sn_tab);
     return ret;      return ret;
 }  }
   
Line 1913  void do_savevm(Monitor *mon, const QDict Line 1965  void do_savevm(Monitor *mon, const QDict
     bs = NULL;      bs = NULL;
     while ((bs = bdrv_next(bs))) {      while ((bs = bdrv_next(bs))) {
   
         if (bdrv_is_removable(bs) || bdrv_is_read_only(bs)) {          if (!bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) {
             continue;              continue;
         }          }
   
Line 1930  void do_savevm(Monitor *mon, const QDict Line 1982  void do_savevm(Monitor *mon, const QDict
         return;          return;
     }      }
   
     saved_vm_running = vm_running;      saved_vm_running = runstate_is_running();
     vm_stop(VMSTOP_SAVEVM);      vm_stop(RUN_STATE_SAVE_VM);
   
     memset(sn, 0, sizeof(*sn));      memset(sn, 0, sizeof(*sn));
   
Line 2033  int load_vmstate(const char *name) Line 2085  int load_vmstate(const char *name)
     bs = NULL;      bs = NULL;
     while ((bs = bdrv_next(bs))) {      while ((bs = bdrv_next(bs))) {
   
         if (bdrv_is_removable(bs) || bdrv_is_read_only(bs)) {          if (!bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) {
             continue;              continue;
         }          }
   
Line 2140  void do_info_snapshots(Monitor *mon) Line 2192  void do_info_snapshots(Monitor *mon)
         return;          return;
     }      }
   
     available_snapshots = qemu_mallocz(sizeof(int) * nb_sns);      available_snapshots = g_malloc0(sizeof(int) * nb_sns);
     total = 0;      total = 0;
     for (i = 0; i < nb_sns; i++) {      for (i = 0; i < nb_sns; i++) {
         sn = &sn_tab[i];          sn = &sn_tab[i];
Line 2173  void do_info_snapshots(Monitor *mon) Line 2225  void do_info_snapshots(Monitor *mon)
         monitor_printf(mon, "There is no suitable snapshot available\n");          monitor_printf(mon, "There is no suitable snapshot available\n");
     }      }
   
     qemu_free(sn_tab);      g_free(sn_tab);
     qemu_free(available_snapshots);      g_free(available_snapshots);
   
 }  }

Removed from v.1.1.1.10  
changed lines
  Added in v.1.1.1.11


unix.superglobalmegacorp.com