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 | +} | ... | ... |