Commit b338082b3f0f1831deec6fa68145ae01ae136398
1 parent
9dc39cba
remoable device support
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@658 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
173 additions
and
16 deletions
block.c
... | ... | @@ -50,7 +50,13 @@ |
50 | 50 | struct BlockDriverState { |
51 | 51 | int fd; /* if -1, only COW mappings */ |
52 | 52 | int64_t total_sectors; |
53 | - int read_only; | |
53 | + int read_only; /* if true, the media is read only */ | |
54 | + int inserted; /* if true, the media is present */ | |
55 | + int removable; /* if true, the media can be removed */ | |
56 | + int locked; /* if true, the media cannot temporarily be ejected */ | |
57 | + /* event callback when inserting/removing */ | |
58 | + void (*change_cb)(void *opaque); | |
59 | + void *change_opaque; | |
54 | 60 | |
55 | 61 | uint8_t *cow_bitmap; /* if non NULL, COW mappings are used first */ |
56 | 62 | uint8_t *cow_bitmap_addr; /* mmap address of cow_bitmap */ |
... | ... | @@ -61,20 +67,42 @@ struct BlockDriverState { |
61 | 67 | uint8_t boot_sector_data[512]; |
62 | 68 | |
63 | 69 | char filename[1024]; |
70 | + | |
71 | + /* NOTE: the following infos are only hints for real hardware | |
72 | + drivers. They are not used by the block driver */ | |
73 | + int cyls, heads, secs; | |
74 | + int type; | |
75 | + char device_name[32]; | |
76 | + BlockDriverState *next; | |
64 | 77 | }; |
65 | 78 | |
66 | -BlockDriverState *bdrv_open(const char *filename, int snapshot) | |
79 | +static BlockDriverState *bdrv_first; | |
80 | + | |
81 | +/* create a new block device (by default it is empty) */ | |
82 | +BlockDriverState *bdrv_new(const char *device_name) | |
83 | +{ | |
84 | + BlockDriverState **pbs, *bs; | |
85 | + | |
86 | + bs = qemu_mallocz(sizeof(BlockDriverState)); | |
87 | + if(!bs) | |
88 | + return NULL; | |
89 | + pstrcpy(bs->device_name, sizeof(bs->device_name), device_name); | |
90 | + /* insert at the end */ | |
91 | + pbs = &bdrv_first; | |
92 | + while (*pbs != NULL) | |
93 | + pbs = &(*pbs)->next; | |
94 | + *pbs = bs; | |
95 | + return bs; | |
96 | +} | |
97 | + | |
98 | +int bdrv_open(BlockDriverState *bs, const char *filename, int snapshot) | |
67 | 99 | { |
68 | - BlockDriverState *bs; | |
69 | 100 | int fd, cow_fd; |
70 | 101 | int64_t size; |
71 | 102 | char template[] = "/tmp/vl.XXXXXX"; |
72 | 103 | struct cow_header_v2 cow_header; |
73 | 104 | struct stat st; |
74 | 105 | |
75 | - bs = malloc(sizeof(BlockDriverState)); | |
76 | - if(!bs) | |
77 | - return NULL; | |
78 | 106 | bs->read_only = 0; |
79 | 107 | bs->fd = -1; |
80 | 108 | bs->cow_fd = -1; |
... | ... | @@ -163,22 +191,40 @@ BlockDriverState *bdrv_open(const char *filename, int snapshot) |
163 | 191 | bs->cow_sectors_offset = 0; |
164 | 192 | } |
165 | 193 | |
166 | - return bs; | |
194 | + bs->inserted = 1; | |
195 | + | |
196 | + /* call the change callback */ | |
197 | + if (bs->change_cb) | |
198 | + bs->change_cb(bs->change_opaque); | |
199 | + | |
200 | + return 0; | |
167 | 201 | fail: |
168 | 202 | bdrv_close(bs); |
169 | - return NULL; | |
203 | + return -1; | |
170 | 204 | } |
171 | 205 | |
172 | 206 | void bdrv_close(BlockDriverState *bs) |
173 | 207 | { |
174 | - /* we unmap the mapping so that it is written to the COW file */ | |
175 | - if (bs->cow_bitmap_addr) | |
176 | - munmap(bs->cow_bitmap_addr, bs->cow_bitmap_size); | |
177 | - if (bs->cow_fd >= 0) | |
178 | - close(bs->cow_fd); | |
179 | - if (bs->fd >= 0) | |
180 | - close(bs->fd); | |
181 | - free(bs); | |
208 | + if (bs->inserted) { | |
209 | + /* we unmap the mapping so that it is written to the COW file */ | |
210 | + if (bs->cow_bitmap_addr) | |
211 | + munmap(bs->cow_bitmap_addr, bs->cow_bitmap_size); | |
212 | + if (bs->cow_fd >= 0) | |
213 | + close(bs->cow_fd); | |
214 | + if (bs->fd >= 0) | |
215 | + close(bs->fd); | |
216 | + bs->inserted = 0; | |
217 | + | |
218 | + /* call the change callback */ | |
219 | + if (bs->change_cb) | |
220 | + bs->change_cb(bs->change_opaque); | |
221 | + } | |
222 | +} | |
223 | + | |
224 | +void bdrv_delete(BlockDriverState *bs) | |
225 | +{ | |
226 | + bdrv_close(bs); | |
227 | + qemu_free(bs); | |
182 | 228 | } |
183 | 229 | |
184 | 230 | static inline void set_bit(uint8_t *bitmap, int64_t bitnum) |
... | ... | @@ -221,6 +267,9 @@ int bdrv_commit(BlockDriverState *bs) |
221 | 267 | int64_t i; |
222 | 268 | uint8_t *cow_bitmap; |
223 | 269 | |
270 | + if (!bs->inserted) | |
271 | + return -1; | |
272 | + | |
224 | 273 | if (!bs->cow_bitmap) { |
225 | 274 | fprintf(stderr, "Already committed to %s\n", bs->filename); |
226 | 275 | return 0; |
... | ... | @@ -263,6 +312,9 @@ int bdrv_read(BlockDriverState *bs, int64_t sector_num, |
263 | 312 | int ret, n, fd; |
264 | 313 | int64_t offset; |
265 | 314 | |
315 | + if (!bs->inserted) | |
316 | + return -1; | |
317 | + | |
266 | 318 | while (nb_sectors > 0) { |
267 | 319 | if (is_changed(bs->cow_bitmap, sector_num, nb_sectors, &n)) { |
268 | 320 | fd = bs->cow_fd; |
... | ... | @@ -302,6 +354,8 @@ int bdrv_write(BlockDriverState *bs, int64_t sector_num, |
302 | 354 | int ret, fd, i; |
303 | 355 | int64_t offset, retl; |
304 | 356 | |
357 | + if (!bs->inserted) | |
358 | + return -1; | |
305 | 359 | if (bs->read_only) |
306 | 360 | return -1; |
307 | 361 | |
... | ... | @@ -344,3 +398,106 @@ void bdrv_set_boot_sector(BlockDriverState *bs, const uint8_t *data, int size) |
344 | 398 | memcpy(bs->boot_sector_data, data, size); |
345 | 399 | memset(bs->boot_sector_data + size, 0, 512 - size); |
346 | 400 | } |
401 | + | |
402 | +void bdrv_set_geometry_hint(BlockDriverState *bs, | |
403 | + int cyls, int heads, int secs) | |
404 | +{ | |
405 | + bs->cyls = cyls; | |
406 | + bs->heads = heads; | |
407 | + bs->secs = secs; | |
408 | +} | |
409 | + | |
410 | +void bdrv_set_type_hint(BlockDriverState *bs, int type) | |
411 | +{ | |
412 | + bs->type = type; | |
413 | + bs->removable = ((type == BDRV_TYPE_CDROM || | |
414 | + type == BDRV_TYPE_FLOPPY)); | |
415 | +} | |
416 | + | |
417 | +void bdrv_get_geometry_hint(BlockDriverState *bs, | |
418 | + int *pcyls, int *pheads, int *psecs) | |
419 | +{ | |
420 | + *pcyls = bs->cyls; | |
421 | + *pheads = bs->heads; | |
422 | + *psecs = bs->secs; | |
423 | +} | |
424 | + | |
425 | +int bdrv_get_type_hint(BlockDriverState *bs) | |
426 | +{ | |
427 | + return bs->type; | |
428 | +} | |
429 | + | |
430 | +int bdrv_is_removable(BlockDriverState *bs) | |
431 | +{ | |
432 | + return bs->removable; | |
433 | +} | |
434 | + | |
435 | +int bdrv_is_read_only(BlockDriverState *bs) | |
436 | +{ | |
437 | + return bs->read_only; | |
438 | +} | |
439 | + | |
440 | +int bdrv_is_inserted(BlockDriverState *bs) | |
441 | +{ | |
442 | + return bs->inserted; | |
443 | +} | |
444 | + | |
445 | +int bdrv_is_locked(BlockDriverState *bs) | |
446 | +{ | |
447 | + return bs->locked; | |
448 | +} | |
449 | + | |
450 | +void bdrv_set_locked(BlockDriverState *bs, int locked) | |
451 | +{ | |
452 | + bs->locked = locked; | |
453 | +} | |
454 | + | |
455 | +void bdrv_set_change_cb(BlockDriverState *bs, | |
456 | + void (*change_cb)(void *opaque), void *opaque) | |
457 | +{ | |
458 | + bs->change_cb = change_cb; | |
459 | + bs->change_opaque = opaque; | |
460 | +} | |
461 | + | |
462 | +BlockDriverState *bdrv_find(const char *name) | |
463 | +{ | |
464 | + BlockDriverState *bs; | |
465 | + | |
466 | + for (bs = bdrv_first; bs != NULL; bs = bs->next) { | |
467 | + if (!strcmp(name, bs->device_name)) | |
468 | + return bs; | |
469 | + } | |
470 | + return NULL; | |
471 | +} | |
472 | + | |
473 | +void bdrv_info(void) | |
474 | +{ | |
475 | + BlockDriverState *bs; | |
476 | + | |
477 | + for (bs = bdrv_first; bs != NULL; bs = bs->next) { | |
478 | + term_printf("%s:", bs->device_name); | |
479 | + term_printf(" type="); | |
480 | + switch(bs->type) { | |
481 | + case BDRV_TYPE_HD: | |
482 | + term_printf("hd"); | |
483 | + break; | |
484 | + case BDRV_TYPE_CDROM: | |
485 | + term_printf("cdrom"); | |
486 | + break; | |
487 | + case BDRV_TYPE_FLOPPY: | |
488 | + term_printf("floppy"); | |
489 | + break; | |
490 | + } | |
491 | + term_printf(" removable=%d", bs->removable); | |
492 | + if (bs->removable) { | |
493 | + term_printf(" locked=%d", bs->locked); | |
494 | + } | |
495 | + if (bs->inserted) { | |
496 | + term_printf(" file=%s", bs->filename); | |
497 | + term_printf(" ro=%d", bs->read_only); | |
498 | + } else { | |
499 | + term_printf(" [not inserted]"); | |
500 | + } | |
501 | + term_printf("\n"); | |
502 | + } | |
503 | +} | ... | ... |