Commit b338082b3f0f1831deec6fa68145ae01ae136398

Authored by bellard
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
... ... @@ -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 +}
... ...