ia64/xen-unstable

view tools/ioemu/block.c @ 17391:633099ff88a8

tools: Use PATH_MAX for pathname char arrays.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Fri Apr 04 14:49:37 2008 +0100 (2008-04-04)
parents d8fc3b73fb76
children e3be00bd6aa9
line source
1 /*
2 * QEMU System Emulator block driver
3 *
4 * Copyright (c) 2003 Fabrice Bellard
5 *
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:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
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
22 * THE SOFTWARE.
23 */
24 #include "vl.h"
25 #include "block_int.h"
27 #ifdef _BSD
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <sys/ioctl.h>
31 #include <sys/queue.h>
32 #include <sys/disk.h>
33 #endif
35 #define SECTOR_BITS 9
36 #define SECTOR_SIZE (1 << SECTOR_BITS)
38 typedef struct BlockDriverAIOCBSync {
39 BlockDriverAIOCB common;
40 QEMUBH *bh;
41 int ret;
42 } BlockDriverAIOCBSync;
44 static BlockDriverAIOCB *bdrv_aio_read_em(BlockDriverState *bs,
45 int64_t sector_num, uint8_t *buf, int nb_sectors,
46 BlockDriverCompletionFunc *cb, void *opaque);
47 static BlockDriverAIOCB *bdrv_aio_write_em(BlockDriverState *bs,
48 int64_t sector_num, const uint8_t *buf, int nb_sectors,
49 BlockDriverCompletionFunc *cb, void *opaque);
50 static void bdrv_aio_cancel_em(BlockDriverAIOCB *acb);
51 static BlockDriverAIOCB *bdrv_aio_flush_em(BlockDriverState *bs,
52 BlockDriverCompletionFunc *cb, void *opaque);
53 static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,
54 uint8_t *buf, int nb_sectors);
55 static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num,
56 const uint8_t *buf, int nb_sectors);
58 static BlockDriverState *bdrv_first;
59 static BlockDriver *first_drv;
61 int path_is_absolute(const char *path)
62 {
63 const char *p;
64 #ifdef _WIN32
65 /* specific case for names like: "\\.\d:" */
66 if (*path == '/' || *path == '\\')
67 return 1;
68 #endif
69 p = strchr(path, ':');
70 if (p)
71 p++;
72 else
73 p = path;
74 #ifdef _WIN32
75 return (*p == '/' || *p == '\\');
76 #else
77 return (*p == '/');
78 #endif
79 }
81 /* if filename is absolute, just copy it to dest. Otherwise, build a
82 path to it by considering it is relative to base_path. URL are
83 supported. */
84 void path_combine(char *dest, int dest_size,
85 const char *base_path,
86 const char *filename)
87 {
88 const char *p, *p1;
89 int len;
91 if (dest_size <= 0)
92 return;
93 if (path_is_absolute(filename)) {
94 pstrcpy(dest, dest_size, filename);
95 } else {
96 p = strchr(base_path, ':');
97 if (p)
98 p++;
99 else
100 p = base_path;
101 p1 = strrchr(base_path, '/');
102 #ifdef _WIN32
103 {
104 const char *p2;
105 p2 = strrchr(base_path, '\\');
106 if (!p1 || p2 > p1)
107 p1 = p2;
108 }
109 #endif
110 if (p1)
111 p1++;
112 else
113 p1 = base_path;
114 if (p1 > p)
115 p = p1;
116 len = p - base_path;
117 if (len > dest_size - 1)
118 len = dest_size - 1;
119 memcpy(dest, base_path, len);
120 dest[len] = '\0';
121 pstrcat(dest, dest_size, filename);
122 }
123 }
125 static int bdrv_rw_badreq_sectors(BlockDriverState *bs,
126 int64_t sector_num, int nb_sectors)
127 {
128 return (
129 nb_sectors < 0 ||
130 nb_sectors > bs->total_sectors ||
131 sector_num > bs->total_sectors - nb_sectors
132 ) && !bs->extendable;
133 }
135 static int bdrv_rw_badreq_bytes(BlockDriverState *bs,
136 int64_t offset, int count)
137 {
138 int64_t size = bs->total_sectors << SECTOR_BITS;
139 return (
140 count < 0 ||
141 count > size ||
142 offset > size - count
143 ) && !bs->extendable;
145 }
147 void bdrv_register(BlockDriver *bdrv)
148 {
149 if (!bdrv->bdrv_aio_read) {
150 /* add AIO emulation layer */
151 bdrv->bdrv_aio_read = bdrv_aio_read_em;
152 bdrv->bdrv_aio_write = bdrv_aio_write_em;
153 bdrv->bdrv_aio_cancel = bdrv_aio_cancel_em;
154 bdrv->aiocb_size = sizeof(BlockDriverAIOCBSync);
155 } else if (!bdrv->bdrv_read && !bdrv->bdrv_pread) {
156 /* add synchronous IO emulation layer */
157 bdrv->bdrv_read = bdrv_read_em;
158 bdrv->bdrv_write = bdrv_write_em;
159 }
160 if (!bdrv->bdrv_aio_flush)
161 bdrv->bdrv_aio_flush = bdrv_aio_flush_em;
162 bdrv->next = first_drv;
163 first_drv = bdrv;
164 }
166 /* create a new block device (by default it is empty) */
167 BlockDriverState *bdrv_new(const char *device_name)
168 {
169 BlockDriverState **pbs, *bs;
171 bs = qemu_mallocz(sizeof(BlockDriverState));
172 if(!bs)
173 return NULL;
174 pstrcpy(bs->device_name, sizeof(bs->device_name), device_name);
175 if (device_name[0] != '\0') {
176 /* insert at the end */
177 pbs = &bdrv_first;
178 while (*pbs != NULL)
179 pbs = &(*pbs)->next;
180 *pbs = bs;
181 }
182 return bs;
183 }
185 BlockDriver *bdrv_find_format(const char *format_name)
186 {
187 BlockDriver *drv1;
188 for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
189 if (!strcmp(drv1->format_name, format_name))
190 return drv1;
191 }
192 return NULL;
193 }
195 int bdrv_create(BlockDriver *drv,
196 const char *filename, int64_t size_in_sectors,
197 const char *backing_file, int flags)
198 {
199 if (!drv->bdrv_create)
200 return -ENOTSUP;
201 return drv->bdrv_create(filename, size_in_sectors, backing_file, flags);
202 }
204 #ifdef _WIN32
205 void get_tmp_filename(char *filename, int size)
206 {
207 char temp_dir[MAX_PATH];
209 GetTempPath(MAX_PATH, temp_dir);
210 GetTempFileName(temp_dir, "qem", 0, filename);
211 }
212 #else
213 void get_tmp_filename(char *filename, int size)
214 {
215 int fd;
216 /* XXX: race condition possible */
217 pstrcpy(filename, size, "/tmp/vl.XXXXXX");
218 fd = mkstemp(filename);
219 close(fd);
220 }
221 #endif
223 #ifdef _WIN32
224 static int is_windows_drive_prefix(const char *filename)
225 {
226 return (((filename[0] >= 'a' && filename[0] <= 'z') ||
227 (filename[0] >= 'A' && filename[0] <= 'Z')) &&
228 filename[1] == ':');
229 }
231 static int is_windows_drive(const char *filename)
232 {
233 if (is_windows_drive_prefix(filename) &&
234 filename[2] == '\0')
235 return 1;
236 if (strstart(filename, "\\\\.\\", NULL) ||
237 strstart(filename, "//./", NULL))
238 return 1;
239 return 0;
240 }
241 #endif
243 static BlockDriver *find_protocol(const char *filename)
244 {
245 BlockDriver *drv1;
246 char protocol[128];
247 int len;
248 const char *p;
250 #ifdef _WIN32
251 if (is_windows_drive(filename) ||
252 is_windows_drive_prefix(filename))
253 return &bdrv_raw;
254 #endif
255 p = strchr(filename, ':');
256 if (!p)
257 return &bdrv_raw;
258 len = p - filename;
259 if (len > sizeof(protocol) - 1)
260 len = sizeof(protocol) - 1;
261 memcpy(protocol, filename, len);
262 protocol[len] = '\0';
263 for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
264 if (drv1->protocol_name &&
265 !strcmp(drv1->protocol_name, protocol))
266 return drv1;
267 }
268 return NULL;
269 }
271 /* XXX: force raw format if block or character device ? It would
272 simplify the BSD case */
273 static BlockDriver *find_image_format(const char *filename)
274 {
275 int ret, score, score_max;
276 BlockDriver *drv1, *drv;
277 uint8_t buf[2048];
278 BlockDriverState *bs;
280 /* detect host devices. By convention, /dev/cdrom[N] is always
281 recognized as a host CDROM */
282 if (strstart(filename, "/dev/cdrom", NULL))
283 return &bdrv_host_device;
284 #ifdef _WIN32
285 if (is_windows_drive(filename))
286 return &bdrv_host_device;
287 #else
288 {
289 struct stat st;
290 if (stat(filename, &st) >= 0 &&
291 (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode))) {
292 return &bdrv_host_device;
293 }
294 }
295 #endif
297 drv = find_protocol(filename);
298 /* no need to test disk image formats for vvfat */
299 if (drv == &bdrv_vvfat)
300 return drv;
302 ret = bdrv_file_open(&bs, filename, BDRV_O_RDONLY);
303 if (ret < 0)
304 return NULL;
305 ret = bdrv_pread(bs, 0, buf, sizeof(buf));
306 bdrv_delete(bs);
307 if (ret < 0) {
308 return NULL;
309 }
311 score_max = 0;
312 for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
313 if (drv1->bdrv_probe) {
314 score = drv1->bdrv_probe(buf, ret, filename);
315 if (score > score_max) {
316 score_max = score;
317 drv = drv1;
318 }
319 }
320 }
321 return drv;
322 }
324 int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags)
325 {
326 BlockDriverState *bs;
327 int ret;
329 bs = bdrv_new("");
330 if (!bs)
331 return -ENOMEM;
332 ret = bdrv_open2(bs, filename, flags | BDRV_O_FILE, NULL);
333 if (ret < 0) {
334 bdrv_delete(bs);
335 return ret;
336 }
337 *pbs = bs;
338 return 0;
339 }
341 int bdrv_open(BlockDriverState *bs, const char *filename, int flags)
342 {
343 return bdrv_open2(bs, filename, flags, NULL);
344 }
346 int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
347 BlockDriver *drv)
348 {
349 int ret, open_flags;
350 char tmp_filename[PATH_MAX];
351 char backing_filename[PATH_MAX];
353 bs->read_only = 0;
354 bs->is_temporary = 0;
355 bs->encrypted = 0;
357 if (flags & BDRV_O_EXTENDABLE)
358 bs->extendable = 1;
360 if (flags & BDRV_O_SNAPSHOT) {
361 BlockDriverState *bs1;
362 int64_t total_size;
364 /* if snapshot, we create a temporary backing file and open it
365 instead of opening 'filename' directly */
367 /* if there is a backing file, use it */
368 bs1 = bdrv_new("");
369 if (!bs1) {
370 return -ENOMEM;
371 }
372 if (bdrv_open(bs1, filename, 0) < 0) {
373 bdrv_delete(bs1);
374 return -1;
375 }
376 total_size = bdrv_getlength(bs1) >> SECTOR_BITS;
377 bdrv_delete(bs1);
379 get_tmp_filename(tmp_filename, sizeof(tmp_filename));
380 realpath(filename, backing_filename);
381 if (bdrv_create(&bdrv_qcow2, tmp_filename,
382 total_size, backing_filename, 0) < 0) {
383 return -1;
384 }
385 filename = tmp_filename;
386 bs->is_temporary = 1;
387 }
389 pstrcpy(bs->filename, sizeof(bs->filename), filename);
390 if (flags & BDRV_O_FILE) {
391 drv = find_protocol(filename);
392 if (!drv)
393 return -ENOENT;
394 } else {
395 if (!drv) {
396 drv = find_image_format(filename);
397 if (!drv)
398 return -1;
399 }
400 }
401 bs->drv = drv;
402 bs->opaque = qemu_mallocz(drv->instance_size);
403 bs->total_sectors = 0; /* driver will set if it does not do getlength */
404 if (bs->opaque == NULL && drv->instance_size > 0)
405 return -1;
406 /* Note: for compatibility, we open disk image files as RDWR, and
407 RDONLY as fallback */
408 if (!(flags & BDRV_O_FILE))
409 open_flags = BDRV_O_RDWR;
410 else
411 open_flags = flags & ~(BDRV_O_FILE | BDRV_O_SNAPSHOT);
412 ret = drv->bdrv_open(bs, filename, open_flags);
413 if (ret == -EACCES && !(flags & BDRV_O_FILE)) {
414 ret = drv->bdrv_open(bs, filename, BDRV_O_RDONLY);
415 bs->read_only = 1;
416 }
417 if (ret < 0) {
418 qemu_free(bs->opaque);
419 bs->opaque = NULL;
420 bs->drv = NULL;
421 return ret;
422 }
423 if (drv->bdrv_getlength) {
424 bs->total_sectors = bdrv_getlength(bs) >> SECTOR_BITS;
425 }
426 #ifndef _WIN32
427 if (bs->is_temporary) {
428 unlink(filename);
429 }
430 #endif
431 if (bs->backing_file[0] != '\0') {
432 /* if there is a backing file, use it */
433 bs->backing_hd = bdrv_new("");
434 if (!bs->backing_hd) {
435 fail:
436 bdrv_close(bs);
437 return -ENOMEM;
438 }
439 path_combine(backing_filename, sizeof(backing_filename),
440 filename, bs->backing_file);
441 if (bdrv_open(bs->backing_hd, backing_filename, 0) < 0)
442 goto fail;
443 }
445 /* call the change callback */
446 bs->media_changed = 1;
447 if (bs->change_cb)
448 bs->change_cb(bs->change_opaque);
450 return 0;
451 }
453 void bdrv_close(BlockDriverState *bs)
454 {
455 if (bs->drv) {
456 if (bs->backing_hd)
457 bdrv_delete(bs->backing_hd);
458 bs->drv->bdrv_close(bs);
459 qemu_free(bs->opaque);
460 #ifdef _WIN32
461 if (bs->is_temporary) {
462 unlink(bs->filename);
463 }
464 #endif
465 bs->opaque = NULL;
466 bs->drv = NULL;
468 /* call the change callback */
469 bs->total_sectors = 0;
470 bs->media_changed = 1;
471 if (bs->change_cb)
472 bs->change_cb(bs->change_opaque);
473 }
474 }
476 void bdrv_delete(BlockDriverState *bs)
477 {
478 /* XXX: remove the driver list */
479 bdrv_close(bs);
480 qemu_free(bs);
481 }
483 /* commit COW file into the raw image */
484 int bdrv_commit(BlockDriverState *bs)
485 {
486 BlockDriver *drv = bs->drv;
487 int64_t i, total_sectors;
488 int n, j;
489 unsigned char sector[512];
491 if (!drv)
492 return -ENOMEDIUM;
494 if (bs->read_only) {
495 return -EACCES;
496 }
498 if (!bs->backing_hd) {
499 return -ENOTSUP;
500 }
502 total_sectors = bdrv_getlength(bs) >> SECTOR_BITS;
503 for (i = 0; i < total_sectors;) {
504 if (drv->bdrv_is_allocated(bs, i, 65536, &n)) {
505 for(j = 0; j < n; j++) {
506 if (bdrv_read(bs, i, sector, 1) != 0) {
507 return -EIO;
508 }
510 if (bdrv_write(bs->backing_hd, i, sector, 1) != 0) {
511 return -EIO;
512 }
513 i++;
514 }
515 } else {
516 i += n;
517 }
518 }
520 if (drv->bdrv_make_empty)
521 return drv->bdrv_make_empty(bs);
523 return 0;
524 }
526 /* return < 0 if error. See bdrv_write() for the return codes */
527 int bdrv_read(BlockDriverState *bs, int64_t sector_num,
528 uint8_t *buf, int nb_sectors)
529 {
530 BlockDriver *drv = bs->drv;
532 if (!drv)
533 return -ENOMEDIUM;
535 if (bdrv_rw_badreq_sectors(bs, sector_num, nb_sectors))
536 return -EDOM;
537 if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
538 memcpy(buf, bs->boot_sector_data, 512);
539 sector_num++;
540 nb_sectors--;
541 buf += 512;
542 if (nb_sectors == 0)
543 return 0;
544 }
545 if (drv->bdrv_pread) {
546 int ret, len;
547 len = nb_sectors * 512;
548 ret = drv->bdrv_pread(bs, sector_num * 512, buf, len);
549 if (ret < 0)
550 return ret;
551 else if (ret != len)
552 return -EINVAL;
553 else
554 return 0;
555 } else {
556 return drv->bdrv_read(bs, sector_num, buf, nb_sectors);
557 }
558 }
560 /* Return < 0 if error. Important errors are:
561 -EIO generic I/O error (may happen for all errors)
562 -ENOMEDIUM No media inserted.
563 -EINVAL Invalid sector number or nb_sectors
564 -EACCES Trying to write a read-only device
565 */
566 int bdrv_write(BlockDriverState *bs, int64_t sector_num,
567 const uint8_t *buf, int nb_sectors)
568 {
569 BlockDriver *drv = bs->drv;
570 if (!bs->drv)
571 return -ENOMEDIUM;
572 if (bs->read_only)
573 return -EACCES;
574 if (bdrv_rw_badreq_sectors(bs, sector_num, nb_sectors))
575 return -EDOM;
576 if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
577 memcpy(bs->boot_sector_data, buf, 512);
578 }
579 if (drv->bdrv_pwrite) {
580 int ret, len;
581 len = nb_sectors * 512;
582 ret = drv->bdrv_pwrite(bs, sector_num * 512, buf, len);
583 if (ret < 0)
584 return ret;
585 else if (ret != len)
586 return -EIO;
587 else
588 return 0;
589 } else {
590 return drv->bdrv_write(bs, sector_num, buf, nb_sectors);
591 }
592 }
594 static int bdrv_pread_em(BlockDriverState *bs, int64_t offset,
595 uint8_t *buf, int count1)
596 {
597 uint8_t tmp_buf[SECTOR_SIZE];
598 int len, nb_sectors, count;
599 int64_t sector_num;
601 count = count1;
602 /* first read to align to sector start */
603 len = (SECTOR_SIZE - offset) & (SECTOR_SIZE - 1);
604 if (len > count)
605 len = count;
606 sector_num = offset >> SECTOR_BITS;
607 if (len > 0) {
608 if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
609 return -EIO;
610 memcpy(buf, tmp_buf + (offset & (SECTOR_SIZE - 1)), len);
611 count -= len;
612 if (count == 0)
613 return count1;
614 sector_num++;
615 buf += len;
616 }
618 /* read the sectors "in place" */
619 nb_sectors = count >> SECTOR_BITS;
620 if (nb_sectors > 0) {
621 if (bdrv_read(bs, sector_num, buf, nb_sectors) < 0)
622 return -EIO;
623 sector_num += nb_sectors;
624 len = nb_sectors << SECTOR_BITS;
625 buf += len;
626 count -= len;
627 }
629 /* add data from the last sector */
630 if (count > 0) {
631 if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
632 return -EIO;
633 memcpy(buf, tmp_buf, count);
634 }
635 return count1;
636 }
638 static int bdrv_pwrite_em(BlockDriverState *bs, int64_t offset,
639 const uint8_t *buf, int count1)
640 {
641 uint8_t tmp_buf[SECTOR_SIZE];
642 int len, nb_sectors, count;
643 int64_t sector_num;
645 count = count1;
646 /* first write to align to sector start */
647 len = (SECTOR_SIZE - offset) & (SECTOR_SIZE - 1);
648 if (len > count)
649 len = count;
650 sector_num = offset >> SECTOR_BITS;
651 if (len > 0) {
652 if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
653 return -EIO;
654 memcpy(tmp_buf + (offset & (SECTOR_SIZE - 1)), buf, len);
655 if (bdrv_write(bs, sector_num, tmp_buf, 1) < 0)
656 return -EIO;
657 count -= len;
658 if (count == 0)
659 return count1;
660 sector_num++;
661 buf += len;
662 }
664 /* write the sectors "in place" */
665 nb_sectors = count >> SECTOR_BITS;
666 if (nb_sectors > 0) {
667 if (bdrv_write(bs, sector_num, buf, nb_sectors) < 0)
668 return -EIO;
669 sector_num += nb_sectors;
670 len = nb_sectors << SECTOR_BITS;
671 buf += len;
672 count -= len;
673 }
675 /* add data from the last sector */
676 if (count > 0) {
677 if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
678 return -EIO;
679 memcpy(tmp_buf, buf, count);
680 if (bdrv_write(bs, sector_num, tmp_buf, 1) < 0)
681 return -EIO;
682 }
683 return count1;
684 }
686 /**
687 * Read with byte offsets (needed only for file protocols)
688 */
689 int bdrv_pread(BlockDriverState *bs, int64_t offset,
690 void *buf1, int count1)
691 {
692 BlockDriver *drv = bs->drv;
694 if (!drv)
695 return -ENOMEDIUM;
696 if (!drv->bdrv_pread)
697 return bdrv_pread_em(bs, offset, buf1, count1);
698 if (bdrv_rw_badreq_bytes(bs, offset, count1))
699 return -EDOM;
700 return drv->bdrv_pread(bs, offset, buf1, count1);
701 }
703 /**
704 * Write with byte offsets (needed only for file protocols)
705 */
706 int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
707 const void *buf1, int count1)
708 {
709 BlockDriver *drv = bs->drv;
711 if (!drv)
712 return -ENOMEDIUM;
713 if (!drv->bdrv_pwrite)
714 return bdrv_pwrite_em(bs, offset, buf1, count1);
715 if (bdrv_rw_badreq_bytes(bs, offset, count1))
716 return -EDOM;
717 return drv->bdrv_pwrite(bs, offset, buf1, count1);
718 }
720 /**
721 * Truncate file to 'offset' bytes (needed only for file protocols)
722 */
723 int bdrv_truncate(BlockDriverState *bs, int64_t offset)
724 {
725 BlockDriver *drv = bs->drv;
726 if (!drv)
727 return -ENOMEDIUM;
728 if (!drv->bdrv_truncate)
729 return -ENOTSUP;
730 return drv->bdrv_truncate(bs, offset);
731 }
733 /**
734 * Length of a file in bytes. Return < 0 if error or unknown.
735 */
736 int64_t bdrv_getlength(BlockDriverState *bs)
737 {
738 BlockDriver *drv = bs->drv;
739 if (!drv)
740 return -ENOMEDIUM;
741 if (!drv->bdrv_getlength) {
742 /* legacy mode */
743 return bs->total_sectors * SECTOR_SIZE;
744 }
745 return drv->bdrv_getlength(bs);
746 }
748 /* return 0 as number of sectors if no device present or error */
749 void bdrv_get_geometry(BlockDriverState *bs, int64_t *nb_sectors_ptr)
750 {
751 int64_t length;
752 length = bdrv_getlength(bs);
753 if (length < 0)
754 length = 0;
755 else
756 length = length >> SECTOR_BITS;
757 *nb_sectors_ptr = length;
758 }
760 /* force a given boot sector. */
761 void bdrv_set_boot_sector(BlockDriverState *bs, const uint8_t *data, int size)
762 {
763 bs->boot_sector_enabled = 1;
764 if (size > 512)
765 size = 512;
766 memcpy(bs->boot_sector_data, data, size);
767 memset(bs->boot_sector_data + size, 0, 512 - size);
768 }
770 void bdrv_set_geometry_hint(BlockDriverState *bs,
771 int cyls, int heads, int secs)
772 {
773 bs->cyls = cyls;
774 bs->heads = heads;
775 bs->secs = secs;
776 }
778 void bdrv_set_type_hint(BlockDriverState *bs, int type)
779 {
780 bs->type = type;
781 bs->removable = ((type == BDRV_TYPE_CDROM ||
782 type == BDRV_TYPE_FLOPPY));
783 }
785 void bdrv_set_translation_hint(BlockDriverState *bs, int translation)
786 {
787 bs->translation = translation;
788 }
790 void bdrv_get_geometry_hint(BlockDriverState *bs,
791 int *pcyls, int *pheads, int *psecs)
792 {
793 *pcyls = bs->cyls;
794 *pheads = bs->heads;
795 *psecs = bs->secs;
796 }
798 int bdrv_get_type_hint(BlockDriverState *bs)
799 {
800 return bs->type;
801 }
803 int bdrv_get_translation_hint(BlockDriverState *bs)
804 {
805 return bs->translation;
806 }
808 int bdrv_is_removable(BlockDriverState *bs)
809 {
810 return bs->removable;
811 }
813 int bdrv_is_read_only(BlockDriverState *bs)
814 {
815 return bs->read_only;
816 }
818 /* XXX: no longer used */
819 void bdrv_set_change_cb(BlockDriverState *bs,
820 void (*change_cb)(void *opaque), void *opaque)
821 {
822 bs->change_cb = change_cb;
823 bs->change_opaque = opaque;
824 }
826 int bdrv_is_encrypted(BlockDriverState *bs)
827 {
828 if (bs->backing_hd && bs->backing_hd->encrypted)
829 return 1;
830 return bs->encrypted;
831 }
833 int bdrv_set_key(BlockDriverState *bs, const char *key)
834 {
835 int ret;
836 if (bs->backing_hd && bs->backing_hd->encrypted) {
837 ret = bdrv_set_key(bs->backing_hd, key);
838 if (ret < 0)
839 return ret;
840 if (!bs->encrypted)
841 return 0;
842 }
843 if (!bs->encrypted || !bs->drv || !bs->drv->bdrv_set_key)
844 return -1;
845 return bs->drv->bdrv_set_key(bs, key);
846 }
848 void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size)
849 {
850 if (!bs->drv) {
851 buf[0] = '\0';
852 } else {
853 pstrcpy(buf, buf_size, bs->drv->format_name);
854 }
855 }
857 void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
858 void *opaque)
859 {
860 BlockDriver *drv;
862 for (drv = first_drv; drv != NULL; drv = drv->next) {
863 it(opaque, drv->format_name);
864 }
865 }
867 BlockDriverState *bdrv_find(const char *name)
868 {
869 BlockDriverState *bs;
871 for (bs = bdrv_first; bs != NULL; bs = bs->next) {
872 if (!strcmp(name, bs->device_name))
873 return bs;
874 }
875 return NULL;
876 }
878 void bdrv_iterate(void (*it)(void *opaque, const char *name), void *opaque)
879 {
880 BlockDriverState *bs;
882 for (bs = bdrv_first; bs != NULL; bs = bs->next) {
883 it(opaque, bs->device_name);
884 }
885 }
887 const char *bdrv_get_device_name(BlockDriverState *bs)
888 {
889 return bs->device_name;
890 }
892 int bdrv_flush(BlockDriverState *bs)
893 {
894 int ret = 0;
895 if (bs->drv->bdrv_flush)
896 ret = bs->drv->bdrv_flush(bs);
897 if (!ret && bs->backing_hd)
898 ret = bdrv_flush(bs->backing_hd);
899 return ret;
900 }
902 void bdrv_info(void)
903 {
904 BlockDriverState *bs;
906 for (bs = bdrv_first; bs != NULL; bs = bs->next) {
907 term_printf("%s:", bs->device_name);
908 term_printf(" type=");
909 switch(bs->type) {
910 case BDRV_TYPE_HD:
911 term_printf("hd");
912 break;
913 case BDRV_TYPE_CDROM:
914 term_printf("cdrom");
915 break;
916 case BDRV_TYPE_FLOPPY:
917 term_printf("floppy");
918 break;
919 }
920 term_printf(" removable=%d", bs->removable);
921 if (bs->removable) {
922 term_printf(" locked=%d", bs->locked);
923 }
924 if (bs->drv) {
925 term_printf(" file=");
926 term_print_filename(bs->filename);
927 if (bs->backing_file[0] != '\0') {
928 term_printf(" backing_file=");
929 term_print_filename(bs->backing_file);
930 }
931 term_printf(" ro=%d", bs->read_only);
932 term_printf(" drv=%s", bs->drv->format_name);
933 if (bs->encrypted)
934 term_printf(" encrypted");
935 } else {
936 term_printf(" [not inserted]");
937 }
938 term_printf("\n");
939 }
940 }
942 void bdrv_get_backing_filename(BlockDriverState *bs,
943 char *filename, int filename_size)
944 {
945 if (!bs->backing_hd) {
946 pstrcpy(filename, filename_size, "");
947 } else {
948 pstrcpy(filename, filename_size, bs->backing_file);
949 }
950 }
952 int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num,
953 const uint8_t *buf, int nb_sectors)
954 {
955 BlockDriver *drv = bs->drv;
956 if (!drv)
957 return -ENOMEDIUM;
958 if (!drv->bdrv_write_compressed)
959 return -ENOTSUP;
960 if (bdrv_rw_badreq_sectors(bs, sector_num, nb_sectors))
961 return -EDOM;
962 return drv->bdrv_write_compressed(bs, sector_num, buf, nb_sectors);
963 }
965 int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
966 {
967 BlockDriver *drv = bs->drv;
968 if (!drv)
969 return -ENOMEDIUM;
970 if (!drv->bdrv_get_info)
971 return -ENOTSUP;
972 memset(bdi, 0, sizeof(*bdi));
973 return drv->bdrv_get_info(bs, bdi);
974 }
976 /**************************************************************/
977 /* handling of snapshots */
979 int bdrv_snapshot_create(BlockDriverState *bs,
980 QEMUSnapshotInfo *sn_info)
981 {
982 BlockDriver *drv = bs->drv;
983 if (!drv)
984 return -ENOMEDIUM;
985 if (!drv->bdrv_snapshot_create)
986 return -ENOTSUP;
987 return drv->bdrv_snapshot_create(bs, sn_info);
988 }
990 int bdrv_snapshot_goto(BlockDriverState *bs,
991 const char *snapshot_id)
992 {
993 BlockDriver *drv = bs->drv;
994 if (!drv)
995 return -ENOMEDIUM;
996 if (!drv->bdrv_snapshot_goto)
997 return -ENOTSUP;
998 return drv->bdrv_snapshot_goto(bs, snapshot_id);
999 }
1001 int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id)
1003 BlockDriver *drv = bs->drv;
1004 if (!drv)
1005 return -ENOMEDIUM;
1006 if (!drv->bdrv_snapshot_delete)
1007 return -ENOTSUP;
1008 return drv->bdrv_snapshot_delete(bs, snapshot_id);
1011 int bdrv_snapshot_list(BlockDriverState *bs,
1012 QEMUSnapshotInfo **psn_info)
1014 BlockDriver *drv = bs->drv;
1015 if (!drv)
1016 return -ENOMEDIUM;
1017 if (!drv->bdrv_snapshot_list)
1018 return -ENOTSUP;
1019 return drv->bdrv_snapshot_list(bs, psn_info);
1022 #define NB_SUFFIXES 4
1024 char *get_human_readable_size(char *buf, int buf_size, int64_t size)
1026 static const char suffixes[NB_SUFFIXES] = "KMGT";
1027 int64_t base;
1028 int i;
1030 if (size <= 999) {
1031 snprintf(buf, buf_size, "%" PRId64, size);
1032 } else {
1033 base = 1024;
1034 for(i = 0; i < NB_SUFFIXES; i++) {
1035 if (size < (10 * base)) {
1036 snprintf(buf, buf_size, "%0.1f%c",
1037 (double)size / base,
1038 suffixes[i]);
1039 break;
1040 } else if (size < (1000 * base) || i == (NB_SUFFIXES - 1)) {
1041 snprintf(buf, buf_size, "%" PRId64 "%c",
1042 ((size + (base >> 1)) / base),
1043 suffixes[i]);
1044 break;
1046 base = base * 1024;
1049 return buf;
1052 char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn)
1054 char buf1[128], date_buf[128], clock_buf[128];
1055 #ifdef _WIN32
1056 struct tm *ptm;
1057 #else
1058 struct tm tm;
1059 #endif
1060 time_t ti;
1061 int64_t secs;
1063 if (!sn) {
1064 snprintf(buf, buf_size,
1065 "%-10s%-20s%7s%20s%15s",
1066 "ID", "TAG", "VM SIZE", "DATE", "VM CLOCK");
1067 } else {
1068 ti = sn->date_sec;
1069 #ifdef _WIN32
1070 ptm = localtime(&ti);
1071 strftime(date_buf, sizeof(date_buf),
1072 "%Y-%m-%d %H:%M:%S", ptm);
1073 #else
1074 localtime_r(&ti, &tm);
1075 strftime(date_buf, sizeof(date_buf),
1076 "%Y-%m-%d %H:%M:%S", &tm);
1077 #endif
1078 secs = sn->vm_clock_nsec / 1000000000;
1079 snprintf(clock_buf, sizeof(clock_buf),
1080 "%02d:%02d:%02d.%03d",
1081 (int)(secs / 3600),
1082 (int)((secs / 60) % 60),
1083 (int)(secs % 60),
1084 (int)((sn->vm_clock_nsec / 1000000) % 1000));
1085 snprintf(buf, buf_size,
1086 "%-10s%-20s%7s%20s%15s",
1087 sn->id_str, sn->name,
1088 get_human_readable_size(buf1, sizeof(buf1), sn->vm_state_size),
1089 date_buf,
1090 clock_buf);
1092 return buf;
1096 /**************************************************************/
1097 /* async I/Os */
1099 BlockDriverAIOCB *bdrv_aio_read(BlockDriverState *bs, int64_t sector_num,
1100 uint8_t *buf, int nb_sectors,
1101 BlockDriverCompletionFunc *cb, void *opaque)
1103 BlockDriver *drv = bs->drv;
1105 if (!drv)
1106 return NULL;
1107 if (bdrv_rw_badreq_sectors(bs, sector_num, nb_sectors))
1108 return NULL;
1110 /* XXX: we assume that nb_sectors == 0 is suppored by the async read */
1111 if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
1112 memcpy(buf, bs->boot_sector_data, 512);
1113 sector_num++;
1114 nb_sectors--;
1115 buf += 512;
1118 return drv->bdrv_aio_read(bs, sector_num, buf, nb_sectors, cb, opaque);
1121 BlockDriverAIOCB *bdrv_aio_write(BlockDriverState *bs, int64_t sector_num,
1122 const uint8_t *buf, int nb_sectors,
1123 BlockDriverCompletionFunc *cb, void *opaque)
1125 BlockDriver *drv = bs->drv;
1127 if (!drv)
1128 return NULL;
1129 if (bs->read_only)
1130 return NULL;
1131 if (bdrv_rw_badreq_sectors(bs, sector_num, nb_sectors))
1132 return NULL;
1133 if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
1134 memcpy(bs->boot_sector_data, buf, 512);
1137 return drv->bdrv_aio_write(bs, sector_num, buf, nb_sectors, cb, opaque);
1140 void bdrv_aio_cancel(BlockDriverAIOCB *acb)
1142 BlockDriver *drv = acb->bs->drv;
1144 drv->bdrv_aio_cancel(acb);
1147 BlockDriverAIOCB *bdrv_aio_flush(BlockDriverState *bs,
1148 BlockDriverCompletionFunc *cb, void *opaque)
1150 BlockDriver *drv = bs->drv;
1152 if (!drv)
1153 return NULL;
1155 return drv->bdrv_aio_flush(bs, cb, opaque);
1159 /**************************************************************/
1160 /* async block device emulation */
1162 #ifdef QEMU_TOOL
1163 static BlockDriverAIOCB *bdrv_aio_read_em(BlockDriverState *bs,
1164 int64_t sector_num, uint8_t *buf, int nb_sectors,
1165 BlockDriverCompletionFunc *cb, void *opaque)
1167 int ret;
1168 ret = bdrv_read(bs, sector_num, buf, nb_sectors);
1169 cb(opaque, ret);
1170 return NULL;
1173 static BlockDriverAIOCB *bdrv_aio_write_em(BlockDriverState *bs,
1174 int64_t sector_num, const uint8_t *buf, int nb_sectors,
1175 BlockDriverCompletionFunc *cb, void *opaque)
1177 int ret;
1178 ret = bdrv_write(bs, sector_num, buf, nb_sectors);
1179 cb(opaque, ret);
1180 return NULL;
1183 static void bdrv_aio_cancel_em(BlockDriverAIOCB *acb)
1186 #else
1187 static void bdrv_aio_bh_cb(void *opaque)
1189 BlockDriverAIOCBSync *acb = opaque;
1190 acb->common.cb(acb->common.opaque, acb->ret);
1191 qemu_aio_release(acb);
1194 static BlockDriverAIOCB *bdrv_aio_read_em(BlockDriverState *bs,
1195 int64_t sector_num, uint8_t *buf, int nb_sectors,
1196 BlockDriverCompletionFunc *cb, void *opaque)
1198 BlockDriverAIOCBSync *acb;
1199 int ret;
1201 acb = qemu_aio_get(bs, cb, opaque);
1202 if (!acb->bh)
1203 acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
1204 ret = bdrv_read(bs, sector_num, buf, nb_sectors);
1205 acb->ret = ret;
1206 qemu_bh_schedule(acb->bh);
1207 return &acb->common;
1210 static BlockDriverAIOCB *bdrv_aio_write_em(BlockDriverState *bs,
1211 int64_t sector_num, const uint8_t *buf, int nb_sectors,
1212 BlockDriverCompletionFunc *cb, void *opaque)
1214 BlockDriverAIOCBSync *acb;
1215 int ret;
1217 acb = qemu_aio_get(bs, cb, opaque);
1218 if (!acb->bh)
1219 acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
1220 ret = bdrv_write(bs, sector_num, buf, nb_sectors);
1221 acb->ret = ret;
1222 qemu_bh_schedule(acb->bh);
1223 return &acb->common;
1226 static void bdrv_aio_cancel_em(BlockDriverAIOCB *blockacb)
1228 BlockDriverAIOCBSync *acb = (BlockDriverAIOCBSync *)blockacb;
1229 qemu_bh_cancel(acb->bh);
1230 qemu_aio_release(acb);
1232 #endif /* !QEMU_TOOL */
1234 static BlockDriverAIOCB *bdrv_aio_flush_em(BlockDriverState *bs,
1235 BlockDriverCompletionFunc *cb, void *opaque)
1237 int ret;
1238 ret = bdrv_flush(bs);
1239 cb(opaque, ret);
1240 return NULL;
1243 /**************************************************************/
1244 /* sync block device emulation */
1246 static void bdrv_rw_em_cb(void *opaque, int ret)
1248 *(int *)opaque = ret;
1251 #define NOT_DONE 0x7fffffff
1253 static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,
1254 uint8_t *buf, int nb_sectors)
1256 int async_ret;
1257 BlockDriverAIOCB *acb;
1259 async_ret = NOT_DONE;
1260 qemu_aio_wait_start();
1261 acb = bdrv_aio_read(bs, sector_num, buf, nb_sectors,
1262 bdrv_rw_em_cb, &async_ret);
1263 if (acb == NULL) {
1264 qemu_aio_wait_end();
1265 return -1;
1267 while (async_ret == NOT_DONE) {
1268 qemu_aio_wait();
1270 qemu_aio_wait_end();
1271 return async_ret;
1274 static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num,
1275 const uint8_t *buf, int nb_sectors)
1277 int async_ret;
1278 BlockDriverAIOCB *acb;
1280 async_ret = NOT_DONE;
1281 qemu_aio_wait_start();
1282 acb = bdrv_aio_write(bs, sector_num, buf, nb_sectors,
1283 bdrv_rw_em_cb, &async_ret);
1284 if (acb == NULL) {
1285 qemu_aio_wait_end();
1286 return -1;
1288 while (async_ret == NOT_DONE) {
1289 qemu_aio_wait();
1291 qemu_aio_wait_end();
1292 return async_ret;
1295 void bdrv_init(void)
1297 bdrv_register(&bdrv_raw);
1298 bdrv_register(&bdrv_host_device);
1299 #ifdef CONFIG_STUBDOM
1300 bdrv_register(&bdrv_vbd);
1301 #endif
1302 #ifndef _WIN32
1303 bdrv_register(&bdrv_cow);
1304 #endif
1305 bdrv_register(&bdrv_qcow);
1306 bdrv_register(&bdrv_vmdk);
1307 bdrv_register(&bdrv_cloop);
1308 bdrv_register(&bdrv_dmg);
1309 bdrv_register(&bdrv_bochs);
1310 bdrv_register(&bdrv_vpc);
1311 bdrv_register(&bdrv_vvfat);
1312 bdrv_register(&bdrv_qcow2);
1315 void *qemu_aio_get(BlockDriverState *bs, BlockDriverCompletionFunc *cb,
1316 void *opaque)
1318 BlockDriver *drv;
1319 BlockDriverAIOCB *acb;
1321 drv = bs->drv;
1322 if (drv->free_aiocb) {
1323 acb = drv->free_aiocb;
1324 drv->free_aiocb = acb->next;
1325 } else {
1326 acb = qemu_mallocz(drv->aiocb_size);
1327 if (!acb)
1328 return NULL;
1330 acb->bs = bs;
1331 acb->cb = cb;
1332 acb->opaque = opaque;
1333 return acb;
1336 void qemu_aio_release(void *p)
1338 BlockDriverAIOCB *acb = p;
1339 BlockDriver *drv = acb->bs->drv;
1340 acb->next = drv->free_aiocb;
1341 drv->free_aiocb = acb;
1344 /**************************************************************/
1345 /* removable device support */
1347 /**
1348 * Return TRUE if the media is present
1349 */
1350 int bdrv_is_inserted(BlockDriverState *bs)
1352 BlockDriver *drv = bs->drv;
1353 int ret;
1354 if (!drv)
1355 return 0;
1356 if (!drv->bdrv_is_inserted)
1357 return 1;
1358 ret = drv->bdrv_is_inserted(bs);
1359 return ret;
1362 /**
1363 * Return TRUE if the media changed since the last call to this
1364 * function. It is currently only used for floppy disks
1365 */
1366 int bdrv_media_changed(BlockDriverState *bs)
1368 BlockDriver *drv = bs->drv;
1369 int ret;
1371 if (!drv || !drv->bdrv_media_changed)
1372 ret = -ENOTSUP;
1373 else
1374 ret = drv->bdrv_media_changed(bs);
1375 if (ret == -ENOTSUP)
1376 ret = bs->media_changed;
1377 bs->media_changed = 0;
1378 return ret;
1381 /**
1382 * If eject_flag is TRUE, eject the media. Otherwise, close the tray
1383 */
1384 void bdrv_eject(BlockDriverState *bs, int eject_flag)
1386 BlockDriver *drv = bs->drv;
1387 int ret;
1389 if (!drv || !drv->bdrv_eject) {
1390 ret = -ENOTSUP;
1391 } else {
1392 ret = drv->bdrv_eject(bs, eject_flag);
1394 if (ret == -ENOTSUP) {
1395 if (eject_flag)
1396 bdrv_close(bs);
1400 int bdrv_is_locked(BlockDriverState *bs)
1402 return bs->locked;
1405 /**
1406 * Lock or unlock the media (if it is locked, the user won't be able
1407 * to eject it manually).
1408 */
1409 void bdrv_set_locked(BlockDriverState *bs, int locked)
1411 BlockDriver *drv = bs->drv;
1413 bs->locked = locked;
1414 if (drv && drv->bdrv_set_locked) {
1415 drv->bdrv_set_locked(bs, locked);