Revision 7685ee6a savevm.c
b/savevm.c | ||
---|---|---|
72 | 72 |
|
73 | 73 |
#include "qemu-common.h" |
74 | 74 |
#include "hw/hw.h" |
75 |
#include "hw/qdev.h" |
|
75 | 76 |
#include "net.h" |
76 | 77 |
#include "monitor.h" |
77 | 78 |
#include "sysemu.h" |
... | ... | |
985 | 986 |
.put = put_unused_buffer, |
986 | 987 |
}; |
987 | 988 |
|
989 |
typedef struct CompatEntry { |
|
990 |
char idstr[256]; |
|
991 |
int instance_id; |
|
992 |
} CompatEntry; |
|
993 |
|
|
988 | 994 |
typedef struct SaveStateEntry { |
989 | 995 |
QTAILQ_ENTRY(SaveStateEntry) entry; |
990 | 996 |
char idstr[256]; |
... | ... | |
998 | 1004 |
LoadStateHandler *load_state; |
999 | 1005 |
const VMStateDescription *vmsd; |
1000 | 1006 |
void *opaque; |
1007 |
CompatEntry *compat; |
|
1001 | 1008 |
} SaveStateEntry; |
1002 | 1009 |
|
1003 | 1010 |
|
... | ... | |
1019 | 1026 |
return instance_id; |
1020 | 1027 |
} |
1021 | 1028 |
|
1029 |
static int calculate_compat_instance_id(const char *idstr) |
|
1030 |
{ |
|
1031 |
SaveStateEntry *se; |
|
1032 |
int instance_id = 0; |
|
1033 |
|
|
1034 |
QTAILQ_FOREACH(se, &savevm_handlers, entry) { |
|
1035 |
if (!se->compat) |
|
1036 |
continue; |
|
1037 |
|
|
1038 |
if (strcmp(idstr, se->compat->idstr) == 0 |
|
1039 |
&& instance_id <= se->compat->instance_id) { |
|
1040 |
instance_id = se->compat->instance_id + 1; |
|
1041 |
} |
|
1042 |
} |
|
1043 |
return instance_id; |
|
1044 |
} |
|
1045 |
|
|
1022 | 1046 |
/* TODO: Individual devices generally have very little idea about the rest |
1023 | 1047 |
of the system, so instance_id should be removed/replaced. |
1024 | 1048 |
Meanwhile pass -1 as instance_id if you do not already have a clearly |
... | ... | |
1036 | 1060 |
SaveStateEntry *se; |
1037 | 1061 |
|
1038 | 1062 |
se = qemu_mallocz(sizeof(SaveStateEntry)); |
1039 |
pstrcpy(se->idstr, sizeof(se->idstr), idstr); |
|
1040 | 1063 |
se->version_id = version_id; |
1041 | 1064 |
se->section_id = global_section_id++; |
1042 | 1065 |
se->set_params = set_params; |
... | ... | |
1046 | 1069 |
se->opaque = opaque; |
1047 | 1070 |
se->vmsd = NULL; |
1048 | 1071 |
|
1072 |
if (dev && dev->parent_bus && dev->parent_bus->info->get_dev_path) { |
|
1073 |
char *id = dev->parent_bus->info->get_dev_path(dev); |
|
1074 |
if (id) { |
|
1075 |
pstrcpy(se->idstr, sizeof(se->idstr), id); |
|
1076 |
pstrcat(se->idstr, sizeof(se->idstr), "/"); |
|
1077 |
qemu_free(id); |
|
1078 |
|
|
1079 |
se->compat = qemu_mallocz(sizeof(CompatEntry)); |
|
1080 |
pstrcpy(se->compat->idstr, sizeof(se->compat->idstr), idstr); |
|
1081 |
se->compat->instance_id = instance_id == -1 ? |
|
1082 |
calculate_compat_instance_id(idstr) : instance_id; |
|
1083 |
instance_id = -1; |
|
1084 |
} |
|
1085 |
} |
|
1086 |
pstrcat(se->idstr, sizeof(se->idstr), idstr); |
|
1087 |
|
|
1049 | 1088 |
if (instance_id == -1) { |
1050 |
se->instance_id = calculate_new_instance_id(idstr); |
|
1089 |
se->instance_id = calculate_new_instance_id(se->idstr);
|
|
1051 | 1090 |
} else { |
1052 | 1091 |
se->instance_id = instance_id; |
1053 | 1092 |
} |
1093 |
assert(!se->compat || se->instance_id == 0); |
|
1054 | 1094 |
/* add at the end of list */ |
1055 | 1095 |
QTAILQ_INSERT_TAIL(&savevm_handlers, se, entry); |
1056 | 1096 |
return 0; |
... | ... | |
1071 | 1111 |
void unregister_savevm(DeviceState *dev, const char *idstr, void *opaque) |
1072 | 1112 |
{ |
1073 | 1113 |
SaveStateEntry *se, *new_se; |
1114 |
char id[256] = ""; |
|
1115 |
|
|
1116 |
if (dev && dev->parent_bus && dev->parent_bus->info->get_dev_path) { |
|
1117 |
char *path = dev->parent_bus->info->get_dev_path(dev); |
|
1118 |
if (path) { |
|
1119 |
pstrcpy(id, sizeof(id), path); |
|
1120 |
pstrcat(id, sizeof(id), "/"); |
|
1121 |
qemu_free(path); |
|
1122 |
} |
|
1123 |
} |
|
1124 |
pstrcat(id, sizeof(id), idstr); |
|
1074 | 1125 |
|
1075 | 1126 |
QTAILQ_FOREACH_SAFE(se, &savevm_handlers, entry, new_se) { |
1076 |
if (strcmp(se->idstr, idstr) == 0 && se->opaque == opaque) {
|
|
1127 |
if (strcmp(se->idstr, id) == 0 && se->opaque == opaque) { |
|
1077 | 1128 |
QTAILQ_REMOVE(&savevm_handlers, se, entry); |
1078 | 1129 |
qemu_free(se); |
1079 | 1130 |
} |
... | ... | |
1091 | 1142 |
assert(alias_id == -1 || required_for_version >= vmsd->minimum_version_id); |
1092 | 1143 |
|
1093 | 1144 |
se = qemu_mallocz(sizeof(SaveStateEntry)); |
1094 |
pstrcpy(se->idstr, sizeof(se->idstr), vmsd->name); |
|
1095 | 1145 |
se->version_id = vmsd->version_id; |
1096 | 1146 |
se->section_id = global_section_id++; |
1097 | 1147 |
se->save_live_state = NULL; |
... | ... | |
1101 | 1151 |
se->vmsd = vmsd; |
1102 | 1152 |
se->alias_id = alias_id; |
1103 | 1153 |
|
1154 |
if (dev && dev->parent_bus && dev->parent_bus->info->get_dev_path) { |
|
1155 |
char *id = dev->parent_bus->info->get_dev_path(dev); |
|
1156 |
if (id) { |
|
1157 |
pstrcpy(se->idstr, sizeof(se->idstr), id); |
|
1158 |
pstrcat(se->idstr, sizeof(se->idstr), "/"); |
|
1159 |
qemu_free(id); |
|
1160 |
|
|
1161 |
se->compat = qemu_mallocz(sizeof(CompatEntry)); |
|
1162 |
pstrcpy(se->compat->idstr, sizeof(se->compat->idstr), vmsd->name); |
|
1163 |
se->compat->instance_id = instance_id == -1 ? |
|
1164 |
calculate_compat_instance_id(vmsd->name) : instance_id; |
|
1165 |
instance_id = -1; |
|
1166 |
} |
|
1167 |
} |
|
1168 |
pstrcat(se->idstr, sizeof(se->idstr), vmsd->name); |
|
1169 |
|
|
1104 | 1170 |
if (instance_id == -1) { |
1105 |
se->instance_id = calculate_new_instance_id(vmsd->name);
|
|
1171 |
se->instance_id = calculate_new_instance_id(se->idstr);
|
|
1106 | 1172 |
} else { |
1107 | 1173 |
se->instance_id = instance_id; |
1108 | 1174 |
} |
1175 |
assert(!se->compat || se->instance_id == 0); |
|
1109 | 1176 |
/* add at the end of list */ |
1110 | 1177 |
QTAILQ_INSERT_TAIL(&savevm_handlers, se, entry); |
1111 | 1178 |
return 0; |
... | ... | |
1451 | 1518 |
(instance_id == se->instance_id || |
1452 | 1519 |
instance_id == se->alias_id)) |
1453 | 1520 |
return se; |
1521 |
/* Migrating from an older version? */ |
|
1522 |
if (strstr(se->idstr, idstr) && se->compat) { |
|
1523 |
if (!strcmp(se->compat->idstr, idstr) && |
|
1524 |
(instance_id == se->compat->instance_id || |
|
1525 |
instance_id == se->alias_id)) |
|
1526 |
return se; |
|
1527 |
} |
|
1454 | 1528 |
} |
1455 | 1529 |
return NULL; |
1456 | 1530 |
} |
Also available in: Unified diff