2 * QEMU System Emulator block driver
4 * Copyright (c) 2003 Fabrice Bellard
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 #include "block_int.h"
27 static BlockDriverState
*bdrv_first
;
28 static BlockDriver
*first_drv
;
30 void bdrv_register(BlockDriver
*bdrv
)
32 bdrv
->next
= first_drv
;
36 /* create a new block device (by default it is empty) */
37 BlockDriverState
*bdrv_new(const char *device_name
)
39 BlockDriverState
**pbs
, *bs
;
41 bs
= qemu_mallocz(sizeof(BlockDriverState
));
44 pstrcpy(bs
->device_name
, sizeof(bs
->device_name
), device_name
);
45 if (device_name
[0] != '\0') {
46 /* insert at the end */
55 BlockDriver
*bdrv_find_format(const char *format_name
)
58 for(drv1
= first_drv
; drv1
!= NULL
; drv1
= drv1
->next
) {
59 if (!strcmp(drv1
->format_name
, format_name
))
65 int bdrv_create(BlockDriver
*drv
,
66 const char *filename
, int64_t size_in_sectors
,
67 const char *backing_file
, int flags
)
69 if (!drv
->bdrv_create
)
71 return drv
->bdrv_create(filename
, size_in_sectors
, backing_file
, flags
);
75 static void get_tmp_filename(char *filename
, int size
)
77 /* XXX: find a better function */
81 static void get_tmp_filename(char *filename
, int size
)
84 /* XXX: race condition possible */
85 pstrcpy(filename
, size
, "/tmp/vl.XXXXXX");
86 fd
= mkstemp(filename
);
91 static BlockDriver
*find_image_format(const char *filename
)
93 int fd
, ret
, score
, score_max
;
94 BlockDriver
*drv1
, *drv
;
97 fd
= open(filename
, O_RDONLY
| O_BINARY
| O_LARGEFILE
);
100 ret
= read(fd
, buf
, sizeof(buf
));
109 for(drv1
= first_drv
; drv1
!= NULL
; drv1
= drv1
->next
) {
110 score
= drv1
->bdrv_probe(buf
, ret
, filename
);
111 if (score
> score_max
) {
119 int bdrv_open(BlockDriverState
*bs
, const char *filename
, int snapshot
)
121 return bdrv_open2(bs
, filename
, snapshot
, NULL
);
124 int bdrv_open2(BlockDriverState
*bs
, const char *filename
, int snapshot
,
128 char tmp_filename
[1024];
131 bs
->is_temporary
= 0;
135 BlockDriverState
*bs1
;
138 /* if snapshot, we create a temporary backing file and open it
139 instead of opening 'filename' directly */
141 /* if there is a backing file, use it */
146 if (bdrv_open(bs1
, filename
, 0) < 0) {
150 total_size
= bs1
->total_sectors
;
153 get_tmp_filename(tmp_filename
, sizeof(tmp_filename
));
154 /* XXX: use cow for linux as it is more efficient ? */
155 if (bdrv_create(&bdrv_qcow
, tmp_filename
,
156 total_size
, filename
, 0) < 0) {
159 filename
= tmp_filename
;
160 bs
->is_temporary
= 1;
163 pstrcpy(bs
->filename
, sizeof(bs
->filename
), filename
);
165 drv
= find_image_format(filename
);
170 bs
->opaque
= qemu_mallocz(drv
->instance_size
);
171 if (bs
->opaque
== NULL
&& drv
->instance_size
> 0)
174 ret
= drv
->bdrv_open(bs
, filename
);
176 qemu_free(bs
->opaque
);
180 if (bs
->is_temporary
) {
184 if (bs
->backing_file
[0] != '\0' && drv
->bdrv_is_allocated
) {
185 /* if there is a backing file, use it */
186 bs
->backing_hd
= bdrv_new("");
187 if (!bs
->backing_hd
) {
192 if (bdrv_open(bs
->backing_hd
, bs
->backing_file
, 0) < 0)
198 /* call the change callback */
200 bs
->change_cb(bs
->change_opaque
);
205 void bdrv_close(BlockDriverState
*bs
)
209 bdrv_delete(bs
->backing_hd
);
210 bs
->drv
->bdrv_close(bs
);
211 qemu_free(bs
->opaque
);
213 if (bs
->is_temporary
) {
214 unlink(bs
->filename
);
221 /* call the change callback */
223 bs
->change_cb(bs
->change_opaque
);
227 void bdrv_delete(BlockDriverState
*bs
)
229 /* XXX: remove the driver list */
234 /* commit COW file into the raw image */
235 int bdrv_commit(BlockDriverState
*bs
)
239 unsigned char sector
[512];
248 if (!bs
->backing_hd
) {
252 for (i
= 0; i
< bs
->total_sectors
;) {
253 if (bs
->drv
->bdrv_is_allocated(bs
, i
, 65536, &n
)) {
254 for(j
= 0; j
< n
; j
++) {
255 if (bdrv_read(bs
, i
, sector
, 1) != 0) {
259 if (bdrv_write(bs
->backing_hd
, i
, sector
, 1) != 0) {
271 /* return -1 if error */
272 int bdrv_read(BlockDriverState
*bs
, int64_t sector_num
,
273 uint8_t *buf
, int nb_sectors
)
276 BlockDriver
*drv
= bs
->drv
;
281 while (nb_sectors
> 0) {
282 if (sector_num
== 0 && bs
->boot_sector_enabled
) {
283 memcpy(buf
, bs
->boot_sector_data
, 512);
285 } else if (bs
->backing_hd
) {
286 if (drv
->bdrv_is_allocated(bs
, sector_num
, nb_sectors
, &n
)) {
287 ret
= drv
->bdrv_read(bs
, sector_num
, buf
, n
);
291 /* read from the base image */
292 ret
= bdrv_read(bs
->backing_hd
, sector_num
, buf
, n
);
297 ret
= drv
->bdrv_read(bs
, sector_num
, buf
, nb_sectors
);
300 /* no need to loop */
310 /* return -1 if error */
311 int bdrv_write(BlockDriverState
*bs
, int64_t sector_num
,
312 const uint8_t *buf
, int nb_sectors
)
318 return bs
->drv
->bdrv_write(bs
, sector_num
, buf
, nb_sectors
);
321 void bdrv_get_geometry(BlockDriverState
*bs
, int64_t *nb_sectors_ptr
)
323 *nb_sectors_ptr
= bs
->total_sectors
;
326 /* force a given boot sector. */
327 void bdrv_set_boot_sector(BlockDriverState
*bs
, const uint8_t *data
, int size
)
329 bs
->boot_sector_enabled
= 1;
332 memcpy(bs
->boot_sector_data
, data
, size
);
333 memset(bs
->boot_sector_data
+ size
, 0, 512 - size
);
336 void bdrv_set_geometry_hint(BlockDriverState
*bs
,
337 int cyls
, int heads
, int secs
)
344 void bdrv_set_type_hint(BlockDriverState
*bs
, int type
)
347 bs
->removable
= ((type
== BDRV_TYPE_CDROM
||
348 type
== BDRV_TYPE_FLOPPY
));
351 void bdrv_set_translation_hint(BlockDriverState
*bs
, int translation
)
353 bs
->translation
= translation
;
356 void bdrv_get_geometry_hint(BlockDriverState
*bs
,
357 int *pcyls
, int *pheads
, int *psecs
)
364 int bdrv_get_type_hint(BlockDriverState
*bs
)
369 int bdrv_get_translation_hint(BlockDriverState
*bs
)
371 return bs
->translation
;
374 int bdrv_is_removable(BlockDriverState
*bs
)
376 return bs
->removable
;
379 int bdrv_is_read_only(BlockDriverState
*bs
)
381 return bs
->read_only
;
384 int bdrv_is_inserted(BlockDriverState
*bs
)
389 int bdrv_is_locked(BlockDriverState
*bs
)
394 void bdrv_set_locked(BlockDriverState
*bs
, int locked
)
399 void bdrv_set_change_cb(BlockDriverState
*bs
,
400 void (*change_cb
)(void *opaque
), void *opaque
)
402 bs
->change_cb
= change_cb
;
403 bs
->change_opaque
= opaque
;
406 int bdrv_is_encrypted(BlockDriverState
*bs
)
408 if (bs
->backing_hd
&& bs
->backing_hd
->encrypted
)
410 return bs
->encrypted
;
413 int bdrv_set_key(BlockDriverState
*bs
, const char *key
)
416 if (bs
->backing_hd
&& bs
->backing_hd
->encrypted
) {
417 ret
= bdrv_set_key(bs
->backing_hd
, key
);
423 if (!bs
->encrypted
|| !bs
->drv
|| !bs
->drv
->bdrv_set_key
)
425 return bs
->drv
->bdrv_set_key(bs
, key
);
428 void bdrv_get_format(BlockDriverState
*bs
, char *buf
, int buf_size
)
430 if (!bs
->inserted
|| !bs
->drv
) {
433 pstrcpy(buf
, buf_size
, bs
->drv
->format_name
);
437 void bdrv_iterate_format(void (*it
)(void *opaque
, const char *name
),
442 for (drv
= first_drv
; drv
!= NULL
; drv
= drv
->next
) {
443 it(opaque
, drv
->format_name
);
447 BlockDriverState
*bdrv_find(const char *name
)
449 BlockDriverState
*bs
;
451 for (bs
= bdrv_first
; bs
!= NULL
; bs
= bs
->next
) {
452 if (!strcmp(name
, bs
->device_name
))
458 void bdrv_iterate(void (*it
)(void *opaque
, const char *name
), void *opaque
)
460 BlockDriverState
*bs
;
462 for (bs
= bdrv_first
; bs
!= NULL
; bs
= bs
->next
) {
463 it(opaque
, bs
->device_name
);
467 const char *bdrv_get_device_name(BlockDriverState
*bs
)
469 return bs
->device_name
;
474 BlockDriverState
*bs
;
476 for (bs
= bdrv_first
; bs
!= NULL
; bs
= bs
->next
) {
477 term_printf("%s:", bs
->device_name
);
478 term_printf(" type=");
483 case BDRV_TYPE_CDROM
:
484 term_printf("cdrom");
486 case BDRV_TYPE_FLOPPY
:
487 term_printf("floppy");
490 term_printf(" removable=%d", bs
->removable
);
492 term_printf(" locked=%d", bs
->locked
);
495 term_printf(" file=%s", bs
->filename
);
496 if (bs
->backing_file
[0] != '\0')
497 term_printf(" backing_file=%s", bs
->backing_file
);
498 term_printf(" ro=%d", bs
->read_only
);
499 term_printf(" drv=%s", bs
->drv
->format_name
);
501 term_printf(" encrypted");
503 term_printf(" [not inserted]");
510 /**************************************************************/
511 /* RAW block driver */
513 typedef struct BDRVRawState
{
517 static int raw_probe(const uint8_t *buf
, int buf_size
, const char *filename
)
519 return 1; /* maybe */
522 static int raw_open(BlockDriverState
*bs
, const char *filename
)
524 BDRVRawState
*s
= bs
->opaque
;
528 fd
= open(filename
, O_RDWR
| O_BINARY
| O_LARGEFILE
);
530 fd
= open(filename
, O_RDONLY
| O_BINARY
| O_LARGEFILE
);
535 size
= lseek(fd
, 0, SEEK_END
);
536 bs
->total_sectors
= size
/ 512;
541 static int raw_read(BlockDriverState
*bs
, int64_t sector_num
,
542 uint8_t *buf
, int nb_sectors
)
544 BDRVRawState
*s
= bs
->opaque
;
547 lseek(s
->fd
, sector_num
* 512, SEEK_SET
);
548 ret
= read(s
->fd
, buf
, nb_sectors
* 512);
549 if (ret
!= nb_sectors
* 512)
554 static int raw_write(BlockDriverState
*bs
, int64_t sector_num
,
555 const uint8_t *buf
, int nb_sectors
)
557 BDRVRawState
*s
= bs
->opaque
;
560 lseek(s
->fd
, sector_num
* 512, SEEK_SET
);
561 ret
= write(s
->fd
, buf
, nb_sectors
* 512);
562 if (ret
!= nb_sectors
* 512)
567 static void raw_close(BlockDriverState
*bs
)
569 BDRVRawState
*s
= bs
->opaque
;
573 static int raw_create(const char *filename
, int64_t total_size
,
574 const char *backing_file
, int flags
)
578 if (flags
|| backing_file
)
581 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
| O_BINARY
| O_LARGEFILE
,
585 ftruncate(fd
, total_size
* 512);
590 BlockDriver bdrv_raw
= {
592 sizeof(BDRVRawState
),
603 bdrv_register(&bdrv_raw
);
605 bdrv_register(&bdrv_cow
);
607 bdrv_register(&bdrv_qcow
);
608 bdrv_register(&bdrv_vmdk
);
609 bdrv_register(&bdrv_cloop
);
610 bdrv_register(&bdrv_dmg
);