Commit 7d5aca9ee6e92e3a746b9c7b59d31489f68a66f0
1 parent
72da4208
qemu: dynamic drive/drive_opt index allocation (Marcelo Tosatti)
Dynamically allocate drive options and drive table index, to reuse indexes when devices are removed. Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6594 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
44 additions
and
11 deletions
sysemu.h
| @@ -134,6 +134,7 @@ typedef struct DriveInfo { | @@ -134,6 +134,7 @@ typedef struct DriveInfo { | ||
| 134 | BlockInterfaceType type; | 134 | BlockInterfaceType type; |
| 135 | int bus; | 135 | int bus; |
| 136 | int unit; | 136 | int unit; |
| 137 | + int used; | ||
| 137 | BlockInterfaceErrorAction onerror; | 138 | BlockInterfaceErrorAction onerror; |
| 138 | char serial[21]; | 139 | char serial[21]; |
| 139 | } DriveInfo; | 140 | } DriveInfo; |
vl.c
| @@ -246,6 +246,7 @@ static int nb_drives_opt; | @@ -246,6 +246,7 @@ static int nb_drives_opt; | ||
| 246 | static struct drive_opt { | 246 | static struct drive_opt { |
| 247 | const char *file; | 247 | const char *file; |
| 248 | char opt[1024]; | 248 | char opt[1024]; |
| 249 | + int used; | ||
| 249 | } drives_opt[MAX_DRIVES]; | 250 | } drives_opt[MAX_DRIVES]; |
| 250 | 251 | ||
| 251 | static CPUState *cur_cpu; | 252 | static CPUState *cur_cpu; |
| @@ -2135,22 +2136,50 @@ static int bt_parse(const char *opt) | @@ -2135,22 +2136,50 @@ static int bt_parse(const char *opt) | ||
| 2135 | #define MTD_ALIAS "if=mtd" | 2136 | #define MTD_ALIAS "if=mtd" |
| 2136 | #define SD_ALIAS "index=0,if=sd" | 2137 | #define SD_ALIAS "index=0,if=sd" |
| 2137 | 2138 | ||
| 2139 | +static int drive_opt_get_free_idx(void) | ||
| 2140 | +{ | ||
| 2141 | + int index; | ||
| 2142 | + | ||
| 2143 | + for (index = 0; index < MAX_DRIVES; index++) | ||
| 2144 | + if (!drives_opt[index].used) { | ||
| 2145 | + drives_opt[index].used = 1; | ||
| 2146 | + return index; | ||
| 2147 | + } | ||
| 2148 | + | ||
| 2149 | + return -1; | ||
| 2150 | +} | ||
| 2151 | + | ||
| 2152 | +static int drive_get_free_idx(void) | ||
| 2153 | +{ | ||
| 2154 | + int index; | ||
| 2155 | + | ||
| 2156 | + for (index = 0; index < MAX_DRIVES; index++) | ||
| 2157 | + if (!drives_table[index].used) { | ||
| 2158 | + drives_table[index].used = 1; | ||
| 2159 | + return index; | ||
| 2160 | + } | ||
| 2161 | + | ||
| 2162 | + return -1; | ||
| 2163 | +} | ||
| 2164 | + | ||
| 2138 | static int drive_add(const char *file, const char *fmt, ...) | 2165 | static int drive_add(const char *file, const char *fmt, ...) |
| 2139 | { | 2166 | { |
| 2140 | va_list ap; | 2167 | va_list ap; |
| 2168 | + int index = drive_opt_get_free_idx(); | ||
| 2141 | 2169 | ||
| 2142 | - if (nb_drives_opt >= MAX_DRIVES) { | 2170 | + if (nb_drives_opt >= MAX_DRIVES || index == -1) { |
| 2143 | fprintf(stderr, "qemu: too many drives\n"); | 2171 | fprintf(stderr, "qemu: too many drives\n"); |
| 2144 | exit(1); | 2172 | exit(1); |
| 2145 | } | 2173 | } |
| 2146 | 2174 | ||
| 2147 | - drives_opt[nb_drives_opt].file = file; | 2175 | + drives_opt[index].file = file; |
| 2148 | va_start(ap, fmt); | 2176 | va_start(ap, fmt); |
| 2149 | - vsnprintf(drives_opt[nb_drives_opt].opt, | 2177 | + vsnprintf(drives_opt[index].opt, |
| 2150 | sizeof(drives_opt[0].opt), fmt, ap); | 2178 | sizeof(drives_opt[0].opt), fmt, ap); |
| 2151 | va_end(ap); | 2179 | va_end(ap); |
| 2152 | 2180 | ||
| 2153 | - return nb_drives_opt++; | 2181 | + nb_drives_opt++; |
| 2182 | + return index; | ||
| 2154 | } | 2183 | } |
| 2155 | 2184 | ||
| 2156 | int drive_get_index(BlockInterfaceType type, int bus, int unit) | 2185 | int drive_get_index(BlockInterfaceType type, int bus, int unit) |
| @@ -2159,10 +2188,11 @@ int drive_get_index(BlockInterfaceType type, int bus, int unit) | @@ -2159,10 +2188,11 @@ int drive_get_index(BlockInterfaceType type, int bus, int unit) | ||
| 2159 | 2188 | ||
| 2160 | /* seek interface, bus and unit */ | 2189 | /* seek interface, bus and unit */ |
| 2161 | 2190 | ||
| 2162 | - for (index = 0; index < nb_drives; index++) | 2191 | + for (index = 0; index < MAX_DRIVES; index++) |
| 2163 | if (drives_table[index].type == type && | 2192 | if (drives_table[index].type == type && |
| 2164 | drives_table[index].bus == bus && | 2193 | drives_table[index].bus == bus && |
| 2165 | - drives_table[index].unit == unit) | 2194 | + drives_table[index].unit == unit && |
| 2195 | + drives_table[index].used) | ||
| 2166 | return index; | 2196 | return index; |
| 2167 | 2197 | ||
| 2168 | return -1; | 2198 | return -1; |
| @@ -2227,6 +2257,7 @@ static int drive_init(struct drive_opt *arg, int snapshot, | @@ -2227,6 +2257,7 @@ static int drive_init(struct drive_opt *arg, int snapshot, | ||
| 2227 | int index; | 2257 | int index; |
| 2228 | int cache; | 2258 | int cache; |
| 2229 | int bdrv_flags, onerror; | 2259 | int bdrv_flags, onerror; |
| 2260 | + int drives_table_idx; | ||
| 2230 | char *str = arg->opt; | 2261 | char *str = arg->opt; |
| 2231 | static const char * const params[] = { "bus", "unit", "if", "index", | 2262 | static const char * const params[] = { "bus", "unit", "if", "index", |
| 2232 | "cyls", "heads", "secs", "trans", | 2263 | "cyls", "heads", "secs", "trans", |
| @@ -2501,11 +2532,12 @@ static int drive_init(struct drive_opt *arg, int snapshot, | @@ -2501,11 +2532,12 @@ static int drive_init(struct drive_opt *arg, int snapshot, | ||
| 2501 | snprintf(buf, sizeof(buf), "%s%s%i", | 2532 | snprintf(buf, sizeof(buf), "%s%s%i", |
| 2502 | devname, mediastr, unit_id); | 2533 | devname, mediastr, unit_id); |
| 2503 | bdrv = bdrv_new(buf); | 2534 | bdrv = bdrv_new(buf); |
| 2504 | - drives_table[nb_drives].bdrv = bdrv; | ||
| 2505 | - drives_table[nb_drives].type = type; | ||
| 2506 | - drives_table[nb_drives].bus = bus_id; | ||
| 2507 | - drives_table[nb_drives].unit = unit_id; | ||
| 2508 | - drives_table[nb_drives].onerror = onerror; | 2535 | + drives_table_idx = drive_get_free_idx(); |
| 2536 | + drives_table[drives_table_idx].bdrv = bdrv; | ||
| 2537 | + drives_table[drives_table_idx].type = type; | ||
| 2538 | + drives_table[drives_table_idx].bus = bus_id; | ||
| 2539 | + drives_table[drives_table_idx].unit = unit_id; | ||
| 2540 | + drives_table[drives_table_idx].onerror = onerror; | ||
| 2509 | strncpy(drives_table[nb_drives].serial, serial, sizeof(serial)); | 2541 | strncpy(drives_table[nb_drives].serial, serial, sizeof(serial)); |
| 2510 | nb_drives++; | 2542 | nb_drives++; |
| 2511 | 2543 |