Revision 3b0ba927
b/hw/device-hotplug.c | ||
---|---|---|
30 | 30 |
|
31 | 31 |
DriveInfo *add_init_drive(const char *opts) |
32 | 32 |
{ |
33 |
int drive_opt_idx; |
|
34 | 33 |
int fatal_error; |
35 | 34 |
DriveInfo *dinfo; |
35 |
DriveOpt *dopt; |
|
36 | 36 |
|
37 |
drive_opt_idx = drive_add(NULL, "%s", opts);
|
|
38 |
if (!drive_opt_idx)
|
|
37 |
dopt = drive_add(NULL, "%s", opts);
|
|
38 |
if (!dopt)
|
|
39 | 39 |
return NULL; |
40 | 40 |
|
41 |
dinfo = drive_init(&drives_opt[drive_opt_idx], 0, current_machine, &fatal_error);
|
|
41 |
dinfo = drive_init(dopt, 0, current_machine, &fatal_error);
|
|
42 | 42 |
if (!dinfo) { |
43 |
drive_remove(drive_opt_idx);
|
|
43 |
drive_remove(dopt);
|
|
44 | 44 |
return NULL; |
45 | 45 |
} |
46 | 46 |
|
b/sysemu.h | ||
---|---|---|
159 | 159 |
|
160 | 160 |
#define BLOCK_SERIAL_STRLEN 20 |
161 | 161 |
|
162 |
typedef struct DriveOpt { |
|
163 |
const char *file; |
|
164 |
char opt[1024]; |
|
165 |
TAILQ_ENTRY(DriveOpt) next; |
|
166 |
} DriveOpt; |
|
167 |
|
|
162 | 168 |
typedef struct DriveInfo { |
163 | 169 |
BlockDriverState *bdrv; |
164 | 170 |
char *id; |
... | ... | |
166 | 172 |
BlockInterfaceType type; |
167 | 173 |
int bus; |
168 | 174 |
int unit; |
169 |
int drive_opt_idx;
|
|
175 |
DriveOpt *opt;
|
|
170 | 176 |
BlockInterfaceErrorAction onerror; |
171 | 177 |
char serial[BLOCK_SERIAL_STRLEN + 1]; |
172 | 178 |
TAILQ_ENTRY(DriveInfo) next; |
... | ... | |
177 | 183 |
#define MAX_DRIVES 32 |
178 | 184 |
|
179 | 185 |
extern TAILQ_HEAD(drivelist, DriveInfo) drives; |
186 |
extern TAILQ_HEAD(driveoptlist, DriveOpt) driveopts; |
|
180 | 187 |
|
181 | 188 |
extern DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit); |
182 | 189 |
extern DriveInfo *drive_get_by_id(char *id); |
183 | 190 |
extern int drive_get_max_bus(BlockInterfaceType type); |
184 | 191 |
extern void drive_uninit(BlockDriverState *bdrv); |
185 |
extern void drive_remove(int index);
|
|
192 |
extern void drive_remove(DriveOpt *opt);
|
|
186 | 193 |
extern const char *drive_get_serial(BlockDriverState *bdrv); |
187 | 194 |
extern BlockInterfaceErrorAction drive_get_onerror(BlockDriverState *bdrv); |
188 | 195 |
|
189 | 196 |
BlockDriverState *qdev_init_bdrv(DeviceState *dev, BlockInterfaceType type); |
190 | 197 |
|
191 |
struct drive_opt { |
|
192 |
const char *file; |
|
193 |
char opt[1024]; |
|
194 |
int used; |
|
195 |
}; |
|
196 |
|
|
197 |
extern struct drive_opt drives_opt[MAX_DRIVES]; |
|
198 |
extern int nb_drives_opt; |
|
199 |
|
|
200 |
extern int drive_add(const char *file, const char *fmt, ...); |
|
201 |
extern DriveInfo *drive_init(struct drive_opt *arg, int snapshot, void *machine, |
|
198 |
extern DriveOpt *drive_add(const char *file, const char *fmt, ...); |
|
199 |
extern DriveInfo *drive_init(DriveOpt *arg, int snapshot, void *machine, |
|
202 | 200 |
int *fatal_error); |
203 | 201 |
|
204 | 202 |
/* acpi */ |
b/vl.c | ||
---|---|---|
181 | 181 |
/* Note: drives_table[MAX_DRIVES] is a dummy block driver if none available |
182 | 182 |
to store the VM snapshots */ |
183 | 183 |
struct drivelist drives = TAILQ_HEAD_INITIALIZER(drives); |
184 |
struct driveoptlist driveopts = TAILQ_HEAD_INITIALIZER(driveopts); |
|
184 | 185 |
enum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB; |
185 | 186 |
static DisplayState *display_state; |
186 | 187 |
DisplayType display_type = DT_DEFAULT; |
... | ... | |
248 | 249 |
unsigned int nb_prom_envs = 0; |
249 | 250 |
const char *prom_envs[MAX_PROM_ENVS]; |
250 | 251 |
#endif |
251 |
int nb_drives_opt; |
|
252 |
struct drive_opt drives_opt[MAX_DRIVES]; |
|
253 | 252 |
int boot_menu; |
254 | 253 |
|
255 | 254 |
int nb_numa_nodes; |
... | ... | |
1865 | 1864 |
#define MTD_ALIAS "if=mtd" |
1866 | 1865 |
#define SD_ALIAS "index=0,if=sd" |
1867 | 1866 |
|
1868 |
static int drive_opt_get_free_idx(void) |
|
1869 |
{ |
|
1870 |
int index; |
|
1871 |
|
|
1872 |
for (index = 0; index < MAX_DRIVES; index++) |
|
1873 |
if (!drives_opt[index].used) { |
|
1874 |
drives_opt[index].used = 1; |
|
1875 |
return index; |
|
1876 |
} |
|
1877 |
|
|
1878 |
return -1; |
|
1879 |
} |
|
1880 |
|
|
1881 |
int drive_add(const char *file, const char *fmt, ...) |
|
1867 |
DriveOpt *drive_add(const char *file, const char *fmt, ...) |
|
1882 | 1868 |
{ |
1883 | 1869 |
va_list ap; |
1884 |
int index = drive_opt_get_free_idx();
|
|
1870 |
DriveOpt *dopt;
|
|
1885 | 1871 |
|
1886 |
if (nb_drives_opt >= MAX_DRIVES || index == -1) { |
|
1887 |
fprintf(stderr, "qemu: too many drives\n"); |
|
1888 |
return -1; |
|
1889 |
} |
|
1872 |
dopt = qemu_mallocz(sizeof(*dopt)); |
|
1890 | 1873 |
|
1891 |
drives_opt[index].file = file;
|
|
1874 |
dopt->file = file;
|
|
1892 | 1875 |
va_start(ap, fmt); |
1893 |
vsnprintf(drives_opt[index].opt,
|
|
1894 |
sizeof(drives_opt[0].opt), fmt, ap);
|
|
1876 |
vsnprintf(dopt->opt,
|
|
1877 |
sizeof(dopt->opt), fmt, ap);
|
|
1895 | 1878 |
va_end(ap); |
1896 | 1879 |
|
1897 |
nb_drives_opt++;
|
|
1898 |
return index;
|
|
1880 |
TAILQ_INSERT_TAIL(&driveopts, dopt, next);
|
|
1881 |
return dopt;
|
|
1899 | 1882 |
} |
1900 | 1883 |
|
1901 |
void drive_remove(int index)
|
|
1884 |
void drive_remove(DriveOpt *dopt)
|
|
1902 | 1885 |
{ |
1903 |
drives_opt[index].used = 0;
|
|
1904 |
nb_drives_opt--;
|
|
1886 |
TAILQ_REMOVE(&driveopts, dopt, next);
|
|
1887 |
qemu_free(dopt);
|
|
1905 | 1888 |
} |
1906 | 1889 |
|
1907 | 1890 |
DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit) |
... | ... | |
1982 | 1965 |
TAILQ_FOREACH(dinfo, &drives, next) { |
1983 | 1966 |
if (dinfo->bdrv != bdrv) |
1984 | 1967 |
continue; |
1985 |
drive_remove(dinfo->drive_opt_idx);
|
|
1968 |
drive_remove(dinfo->opt);
|
|
1986 | 1969 |
TAILQ_REMOVE(&drives, dinfo, next); |
1987 | 1970 |
qemu_free(dinfo); |
1988 | 1971 |
break; |
1989 | 1972 |
} |
1990 | 1973 |
} |
1991 | 1974 |
|
1992 |
DriveInfo *drive_init(struct drive_opt *arg, int snapshot, void *opaque,
|
|
1975 |
DriveInfo *drive_init(DriveOpt *arg, int snapshot, void *opaque,
|
|
1993 | 1976 |
int *fatal_error) |
1994 | 1977 |
{ |
1995 | 1978 |
char buf[128]; |
... | ... | |
2309 | 2292 |
dinfo->bus = bus_id; |
2310 | 2293 |
dinfo->unit = unit_id; |
2311 | 2294 |
dinfo->onerror = onerror; |
2312 |
dinfo->drive_opt_idx = arg - drives_opt;
|
|
2295 |
dinfo->opt = arg;
|
|
2313 | 2296 |
strncpy(dinfo->serial, serial, sizeof(serial)); |
2314 | 2297 |
TAILQ_INSERT_TAIL(&drives, dinfo, next); |
2315 | 2298 |
|
... | ... | |
4896 | 4879 |
int cyls, heads, secs, translation; |
4897 | 4880 |
const char *net_clients[MAX_NET_CLIENTS]; |
4898 | 4881 |
int nb_net_clients; |
4899 |
int hda_index;
|
|
4882 |
DriveOpt *dopt, *hda_opt = NULL;
|
|
4900 | 4883 |
int optind; |
4901 | 4884 |
const char *r, *optarg; |
4902 | 4885 |
CharDriverState *monitor_hd = NULL; |
... | ... | |
4990 | 4973 |
} |
4991 | 4974 |
|
4992 | 4975 |
nb_net_clients = 0; |
4993 |
nb_drives_opt = 0; |
|
4994 | 4976 |
nb_numa_nodes = 0; |
4995 |
hda_index = -1; |
|
4996 |
|
|
4997 | 4977 |
nb_nics = 0; |
4998 | 4978 |
|
4999 | 4979 |
tb_size = 0; |
... | ... | |
5007 | 4987 |
break; |
5008 | 4988 |
r = argv[optind]; |
5009 | 4989 |
if (r[0] != '-') { |
5010 |
hda_index = drive_add(argv[optind++], HD_ALIAS, 0);
|
|
4990 |
hda_opt = drive_add(argv[optind++], HD_ALIAS, 0);
|
|
5011 | 4991 |
} else { |
5012 | 4992 |
const QEMUOption *popt; |
5013 | 4993 |
|
... | ... | |
5071 | 5051 |
break; |
5072 | 5052 |
case QEMU_OPTION_hda: |
5073 | 5053 |
if (cyls == 0) |
5074 |
hda_index = drive_add(optarg, HD_ALIAS, 0);
|
|
5054 |
hda_opt = drive_add(optarg, HD_ALIAS, 0);
|
|
5075 | 5055 |
else |
5076 |
hda_index = drive_add(optarg, HD_ALIAS
|
|
5056 |
hda_opt = drive_add(optarg, HD_ALIAS
|
|
5077 | 5057 |
",cyls=%d,heads=%d,secs=%d%s", |
5078 | 5058 |
0, cyls, heads, secs, |
5079 | 5059 |
translation == BIOS_ATA_TRANSLATION_LBA ? |
... | ... | |
5135 | 5115 |
fprintf(stderr, "qemu: invalid physical CHS format\n"); |
5136 | 5116 |
exit(1); |
5137 | 5117 |
} |
5138 |
if (hda_index != -1)
|
|
5139 |
snprintf(drives_opt[hda_index].opt,
|
|
5140 |
sizeof(drives_opt[hda_index].opt),
|
|
5118 |
if (hda_opt != NULL)
|
|
5119 |
snprintf(hda_opt->opt,
|
|
5120 |
sizeof(hda_opt->opt),
|
|
5141 | 5121 |
HD_ALIAS ",cyls=%d,heads=%d,secs=%d%s", |
5142 | 5122 |
0, cyls, heads, secs, |
5143 | 5123 |
translation == BIOS_ATA_TRANSLATION_LBA ? |
... | ... | |
5846 | 5826 |
bdrv_init(); |
5847 | 5827 |
|
5848 | 5828 |
/* we always create the cdrom drive, even if no disk is there */ |
5849 |
|
|
5850 |
if (nb_drives_opt < MAX_DRIVES) |
|
5851 |
drive_add(NULL, CDROM_ALIAS); |
|
5829 |
drive_add(NULL, CDROM_ALIAS); |
|
5852 | 5830 |
|
5853 | 5831 |
/* we always create at least one floppy */ |
5854 |
|
|
5855 |
if (nb_drives_opt < MAX_DRIVES) |
|
5856 |
drive_add(NULL, FD_ALIAS, 0); |
|
5832 |
drive_add(NULL, FD_ALIAS, 0); |
|
5857 | 5833 |
|
5858 | 5834 |
/* we always create one sd slot, even if no card is in it */ |
5859 |
|
|
5860 |
if (nb_drives_opt < MAX_DRIVES) |
|
5861 |
drive_add(NULL, SD_ALIAS); |
|
5835 |
drive_add(NULL, SD_ALIAS); |
|
5862 | 5836 |
|
5863 | 5837 |
/* open the virtual block devices */ |
5864 | 5838 |
|
5865 |
for(i = 0; i < nb_drives_opt; i++) {
|
|
5839 |
TAILQ_FOREACH(dopt, &driveopts, next) {
|
|
5866 | 5840 |
int fatal_error; |
5867 |
if (drive_init(&drives_opt[i], snapshot, machine, &fatal_error) == NULL)
|
|
5841 |
if (drive_init(dopt, snapshot, machine, &fatal_error) == NULL)
|
|
5868 | 5842 |
if (fatal_error) |
5869 | 5843 |
exit(1); |
5870 | 5844 |
} |
Also available in: Unified diff