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 "config-host.h" 25 #ifdef _BSD 26 /* include native header before sys-queue.h */ 27 #include <sys/queue.h> 28 #endif 29 30 #include "qemu-common.h" 31 #include "console.h" 32 #include "block_int.h" 33 34 #ifdef _BSD 35 #include <sys/types.h> 36 #include <sys/stat.h> 37 #include <sys/ioctl.h> 38 #include <sys/disk.h> 39 #endif 40 41 #define SECTOR_BITS 9 42 #define SECTOR_SIZE (1 << SECTOR_BITS) 43 44 typedef struct BlockDriverAIOCBSync { 45 BlockDriverAIOCB common; 46 QEMUBH *bh; 47 int ret; 48 } BlockDriverAIOCBSync; 49 50 static BlockDriverAIOCB *bdrv_aio_read_em(BlockDriverState *bs, 51 int64_t sector_num, uint8_t *buf, int nb_sectors, 52 BlockDriverCompletionFunc *cb, void *opaque); 53 static BlockDriverAIOCB *bdrv_aio_write_em(BlockDriverState *bs, 54 int64_t sector_num, const uint8_t *buf, int nb_sectors, 55 BlockDriverCompletionFunc *cb, void *opaque); 56 static void bdrv_aio_cancel_em(BlockDriverAIOCB *acb); 57 static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num, 58 uint8_t *buf, int nb_sectors); 59 static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num, 60 const uint8_t *buf, int nb_sectors); 61 62 BlockDriverState *bdrv_first; 63 64 static BlockDriver *first_drv; 65 66 int path_is_absolute(const char *path) 67 { 68 const char *p; 69 #ifdef _WIN32 70 /* specific case for names like: "\\.\d:" */ 71 if (*path == '/' || *path == '\\') 72 return 1; 73 #endif 74 p = strchr(path, ':'); 75 if (p) 76 p++; 77 else 78 p = path; 79 #ifdef _WIN32 80 return (*p == '/' || *p == '\\'); 81 #else 82 return (*p == '/'); 83 #endif 84 } 85 86 /* if filename is absolute, just copy it to dest. Otherwise, build a 87 path to it by considering it is relative to base_path. URL are 88 supported. */ 89 void path_combine(char *dest, int dest_size, 90 const char *base_path, 91 const char *filename) 92 { 93 const char *p, *p1; 94 int len; 95 96 if (dest_size <= 0) 97 return; 98 if (path_is_absolute(filename)) { 99 pstrcpy(dest, dest_size, filename); 100 } else { 101 p = strchr(base_path, ':'); 102 if (p) 103 p++; 104 else 105 p = base_path; 106 p1 = strrchr(base_path, '/'); 107 #ifdef _WIN32 108 { 109 const char *p2; 110 p2 = strrchr(base_path, '\\'); 111 if (!p1 || p2 > p1) 112 p1 = p2; 113 } 114 #endif 115 if (p1) 116 p1++; 117 else 118 p1 = base_path; 119 if (p1 > p) 120 p = p1; 121 len = p - base_path; 122 if (len > dest_size - 1) 123 len = dest_size - 1; 124 memcpy(dest, base_path, len); 125 dest[len] = '\0'; 126 pstrcat(dest, dest_size, filename); 127 } 128 } 129 130 131 static void bdrv_register(BlockDriver *bdrv) 132 { 133 if (!bdrv->bdrv_aio_read) { 134 /* add AIO emulation layer */ 135 bdrv->bdrv_aio_read = bdrv_aio_read_em; 136 bdrv->bdrv_aio_write = bdrv_aio_write_em; 137 bdrv->bdrv_aio_cancel = bdrv_aio_cancel_em; 138 bdrv->aiocb_size = sizeof(BlockDriverAIOCBSync); 139 } else if (!bdrv->bdrv_read && !bdrv->bdrv_pread) { 140 /* add synchronous IO emulation layer */ 141 bdrv->bdrv_read = bdrv_read_em; 142 bdrv->bdrv_write = bdrv_write_em; 143 } 144 bdrv->next = first_drv; 145 first_drv = bdrv; 146 } 147 148 /* create a new block device (by default it is empty) */ 149 BlockDriverState *bdrv_new(const char *device_name) 150 { 151 BlockDriverState **pbs, *bs; 152 153 bs = qemu_mallocz(sizeof(BlockDriverState)); 154 if(!bs) 155 return NULL; 156 pstrcpy(bs->device_name, sizeof(bs->device_name), device_name); 157 if (device_name[0] != '\0') { 158 /* insert at the end */ 159 pbs = &bdrv_first; 160 while (*pbs != NULL) 161 pbs = &(*pbs)->next; 162 *pbs = bs; 163 } 164 return bs; 165 } 166 167 BlockDriver *bdrv_find_format(const char *format_name) 168 { 169 BlockDriver *drv1; 170 for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) { 171 if (!strcmp(drv1->format_name, format_name)) 172 return drv1; 173 } 174 return NULL; 175 } 176 177 int bdrv_create(BlockDriver *drv, 178 const char *filename, int64_t size_in_sectors, 179 const char *backing_file, int flags) 180 { 181 if (!drv->bdrv_create) 182 return -ENOTSUP; 183 return drv->bdrv_create(filename, size_in_sectors, backing_file, flags); 184 } 185 186 #ifdef _WIN32 187 void get_tmp_filename(char *filename, int size) 188 { 189 char temp_dir[MAX_PATH]; 190 191 GetTempPath(MAX_PATH, temp_dir); 192 GetTempFileName(temp_dir, "qem", 0, filename); 193 } 194 #else 195 void get_tmp_filename(char *filename, int size) 196 { 197 int fd; 198 const char *tmpdir; 199 /* XXX: race condition possible */ 200 tmpdir = getenv("TMPDIR"); 201 if (!tmpdir) 202 tmpdir = "/tmp"; 203 snprintf(filename, size, "%s/vl.XXXXXX", tmpdir); 204 fd = mkstemp(filename); 205 close(fd); 206 } 207 #endif 208 209 #ifdef _WIN32 210 static int is_windows_drive_prefix(const char *filename) 211 { 212 return (((filename[0] >= 'a' && filename[0] <= 'z') || 213 (filename[0] >= 'A' && filename[0] <= 'Z')) && 214 filename[1] == ':'); 215 } 216 217 static int is_windows_drive(const char *filename) 218 { 219 if (is_windows_drive_prefix(filename) && 220 filename[2] == '\0') 221 return 1; 222 if (strstart(filename, "\\\\.\\", NULL) || 223 strstart(filename, "//./", NULL)) 224 return 1; 225 return 0; 226 } 227 #endif 228 229 static BlockDriver *find_protocol(const char *filename) 230 { 231 BlockDriver *drv1; 232 char protocol[128]; 233 int len; 234 const char *p; 235 236 #ifdef _WIN32 237 if (is_windows_drive(filename) || 238 is_windows_drive_prefix(filename)) 239 return &bdrv_raw; 240 #endif 241 p = strchr(filename, ':'); 242 if (!p) 243 return &bdrv_raw; 244 len = p - filename; 245 if (len > sizeof(protocol) - 1) 246 len = sizeof(protocol) - 1; 247 memcpy(protocol, filename, len); 248 protocol[len] = '\0'; 249 for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) { 250 if (drv1->protocol_name && 251 !strcmp(drv1->protocol_name, protocol)) 252 return drv1; 253 } 254 return NULL; 255 } 256 257 /* XXX: force raw format if block or character device ? It would 258 simplify the BSD case */ 259 static BlockDriver *find_image_format(const char *filename) 260 { 261 int ret, score, score_max; 262 BlockDriver *drv1, *drv; 263 uint8_t buf[2048]; 264 BlockDriverState *bs; 265 266 /* detect host devices. By convention, /dev/cdrom[N] is always 267 recognized as a host CDROM */ 268 if (strstart(filename, "/dev/cdrom", NULL)) 269 return &bdrv_host_device; 270 #ifdef _WIN32 271 if (is_windows_drive(filename)) 272 return &bdrv_host_device; 273 #else 274 { 275 struct stat st; 276 if (stat(filename, &st) >= 0 && 277 (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode))) { 278 return &bdrv_host_device; 279 } 280 } 281 #endif 282 283 drv = find_protocol(filename); 284 /* no need to test disk image formats for vvfat */ 285 if (drv == &bdrv_vvfat) 286 return drv; 287 288 ret = bdrv_file_open(&bs, filename, BDRV_O_RDONLY); 289 if (ret < 0) 290 return NULL; 291 ret = bdrv_pread(bs, 0, buf, sizeof(buf)); 292 bdrv_delete(bs); 293 if (ret < 0) { 294 return NULL; 295 } 296 297 score_max = 0; 298 for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) { 299 if (drv1->bdrv_probe) { 300 score = drv1->bdrv_probe(buf, ret, filename); 301 if (score > score_max) { 302 score_max = score; 303 drv = drv1; 304 } 305 } 306 } 307 return drv; 308 } 309 310 int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags) 311 { 312 BlockDriverState *bs; 313 int ret; 314 315 bs = bdrv_new(""); 316 if (!bs) 317 return -ENOMEM; 318 ret = bdrv_open2(bs, filename, flags | BDRV_O_FILE, NULL); 319 if (ret < 0) { 320 bdrv_delete(bs); 321 return ret; 322 } 323 *pbs = bs; 324 return 0; 325 } 326 327 int bdrv_open(BlockDriverState *bs, const char *filename, int flags) 328 { 329 return bdrv_open2(bs, filename, flags, NULL); 330 } 331 332 int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, 333 BlockDriver *drv) 334 { 335 int ret, open_flags; 336 char tmp_filename[PATH_MAX]; 337 char backing_filename[PATH_MAX]; 338 339 bs->read_only = 0; 340 bs->is_temporary = 0; 341 bs->encrypted = 0; 342 343 if (flags & BDRV_O_SNAPSHOT) { 344 BlockDriverState *bs1; 345 int64_t total_size; 346 int is_protocol = 0; 347 348 /* if snapshot, we create a temporary backing file and open it 349 instead of opening 'filename' directly */ 350 351 /* if there is a backing file, use it */ 352 bs1 = bdrv_new(""); 353 if (!bs1) { 354 return -ENOMEM; 355 } 356 if (bdrv_open(bs1, filename, 0) < 0) { 357 bdrv_delete(bs1); 358 return -1; 359 } 360 total_size = bdrv_getlength(bs1) >> SECTOR_BITS; 361 362 if (bs1->drv && bs1->drv->protocol_name) 363 is_protocol = 1; 364 365 bdrv_delete(bs1); 366 367 get_tmp_filename(tmp_filename, sizeof(tmp_filename)); 368 369 /* Real path is meaningless for protocols */ 370 if (is_protocol) 371 snprintf(backing_filename, sizeof(backing_filename), 372 "%s", filename); 373 else 374 realpath(filename, backing_filename); 375 376 if (bdrv_create(&bdrv_qcow2, tmp_filename, 377 total_size, backing_filename, 0) < 0) { 378 return -1; 379 } 380 filename = tmp_filename; 381 bs->is_temporary = 1; 382 } 383 384 pstrcpy(bs->filename, sizeof(bs->filename), filename); 385 if (flags & BDRV_O_FILE) { 386 drv = find_protocol(filename); 387 if (!drv) 388 return -ENOENT; 389 } else { 390 if (!drv) { 391 drv = find_image_format(filename); 392 if (!drv) 393 return -1; 394 } 395 } 396 bs->drv = drv; 397 bs->opaque = qemu_mallocz(drv->instance_size); 398 if (bs->opaque == NULL && drv->instance_size > 0) 399 return -1; 400 /* Note: for compatibility, we open disk image files as RDWR, and 401 RDONLY as fallback */ 402 if (!(flags & BDRV_O_FILE)) 403 open_flags = BDRV_O_RDWR | (flags & BDRV_O_CACHE_MASK); 404 else 405 open_flags = flags & ~(BDRV_O_FILE | BDRV_O_SNAPSHOT); 406 ret = drv->bdrv_open(bs, filename, open_flags); 407 if ((ret == -EACCES || ret == -EPERM) && !(flags & BDRV_O_FILE)) { 408 ret = drv->bdrv_open(bs, filename, open_flags & ~BDRV_O_RDWR); 409 bs->read_only = 1; 410 } 411 if (ret < 0) { 412 qemu_free(bs->opaque); 413 bs->opaque = NULL; 414 bs->drv = NULL; 415 return ret; 416 } 417 if (drv->bdrv_getlength) { 418 bs->total_sectors = bdrv_getlength(bs) >> SECTOR_BITS; 419 } 420 #ifndef _WIN32 421 if (bs->is_temporary) { 422 unlink(filename); 423 } 424 #endif 425 if (bs->backing_file[0] != '\0') { 426 /* if there is a backing file, use it */ 427 bs->backing_hd = bdrv_new(""); 428 if (!bs->backing_hd) { 429 fail: 430 bdrv_close(bs); 431 return -ENOMEM; 432 } 433 path_combine(backing_filename, sizeof(backing_filename), 434 filename, bs->backing_file); 435 if (bdrv_open(bs->backing_hd, backing_filename, open_flags) < 0) 436 goto fail; 437 } 438 439 /* call the change callback */ 440 bs->media_changed = 1; 441 if (bs->change_cb) 442 bs->change_cb(bs->change_opaque); 443 444 return 0; 445 } 446 447 void bdrv_close(BlockDriverState *bs) 448 { 449 if (bs->drv) { 450 if (bs->backing_hd) 451 bdrv_delete(bs->backing_hd); 452 bs->drv->bdrv_close(bs); 453 qemu_free(bs->opaque); 454 #ifdef _WIN32 455 if (bs->is_temporary) { 456 unlink(bs->filename); 457 } 458 #endif 459 bs->opaque = NULL; 460 bs->drv = NULL; 461 462 /* call the change callback */ 463 bs->media_changed = 1; 464 if (bs->change_cb) 465 bs->change_cb(bs->change_opaque); 466 } 467 } 468 469 void bdrv_delete(BlockDriverState *bs) 470 { 471 BlockDriverState **pbs; 472 473 pbs = &bdrv_first; 474 while (*pbs != bs && *pbs != NULL) 475 pbs = &(*pbs)->next; 476 if (*pbs == bs) 477 *pbs = bs->next; 478 479 bdrv_close(bs); 480 qemu_free(bs); 481 } 482 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]; 490 491 if (!drv) 492 return -ENOMEDIUM; 493 494 if (bs->read_only) { 495 return -EACCES; 496 } 497 498 if (!bs->backing_hd) { 499 return -ENOTSUP; 500 } 501 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 } 509 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 } 519 520 if (drv->bdrv_make_empty) 521 return drv->bdrv_make_empty(bs); 522 523 return 0; 524 } 525 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; 531 532 if (!drv) 533 return -ENOMEDIUM; 534 535 if (drv->bdrv_pread) { 536 int ret, len; 537 len = nb_sectors * 512; 538 ret = drv->bdrv_pread(bs, sector_num * 512, buf, len); 539 if (ret < 0) 540 return ret; 541 else if (ret != len) 542 return -EINVAL; 543 else { 544 bs->rd_bytes += (unsigned) len; 545 bs->rd_ops ++; 546 return 0; 547 } 548 } else { 549 return drv->bdrv_read(bs, sector_num, buf, nb_sectors); 550 } 551 } 552 553 /* Return < 0 if error. Important errors are: 554 -EIO generic I/O error (may happen for all errors) 555 -ENOMEDIUM No media inserted. 556 -EINVAL Invalid sector number or nb_sectors 557 -EACCES Trying to write a read-only device 558 */ 559 int bdrv_write(BlockDriverState *bs, int64_t sector_num, 560 const uint8_t *buf, int nb_sectors) 561 { 562 BlockDriver *drv = bs->drv; 563 if (!bs->drv) 564 return -ENOMEDIUM; 565 if (bs->read_only) 566 return -EACCES; 567 if (drv->bdrv_pwrite) { 568 int ret, len; 569 len = nb_sectors * 512; 570 ret = drv->bdrv_pwrite(bs, sector_num * 512, buf, len); 571 if (ret < 0) 572 return ret; 573 else if (ret != len) 574 return -EIO; 575 else { 576 bs->wr_bytes += (unsigned) len; 577 bs->wr_ops ++; 578 return 0; 579 } 580 } else { 581 return drv->bdrv_write(bs, sector_num, buf, nb_sectors); 582 } 583 } 584 585 static int bdrv_pread_em(BlockDriverState *bs, int64_t offset, 586 uint8_t *buf, int count1) 587 { 588 uint8_t tmp_buf[SECTOR_SIZE]; 589 int len, nb_sectors, count; 590 int64_t sector_num; 591 592 count = count1; 593 /* first read to align to sector start */ 594 len = (SECTOR_SIZE - offset) & (SECTOR_SIZE - 1); 595 if (len > count) 596 len = count; 597 sector_num = offset >> SECTOR_BITS; 598 if (len > 0) { 599 if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0) 600 return -EIO; 601 memcpy(buf, tmp_buf + (offset & (SECTOR_SIZE - 1)), len); 602 count -= len; 603 if (count == 0) 604 return count1; 605 sector_num++; 606 buf += len; 607 } 608 609 /* read the sectors "in place" */ 610 nb_sectors = count >> SECTOR_BITS; 611 if (nb_sectors > 0) { 612 if (bdrv_read(bs, sector_num, buf, nb_sectors) < 0) 613 return -EIO; 614 sector_num += nb_sectors; 615 len = nb_sectors << SECTOR_BITS; 616 buf += len; 617 count -= len; 618 } 619 620 /* add data from the last sector */ 621 if (count > 0) { 622 if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0) 623 return -EIO; 624 memcpy(buf, tmp_buf, count); 625 } 626 return count1; 627 } 628 629 static int bdrv_pwrite_em(BlockDriverState *bs, int64_t offset, 630 const uint8_t *buf, int count1) 631 { 632 uint8_t tmp_buf[SECTOR_SIZE]; 633 int len, nb_sectors, count; 634 int64_t sector_num; 635 636 count = count1; 637 /* first write to align to sector start */ 638 len = (SECTOR_SIZE - offset) & (SECTOR_SIZE - 1); 639 if (len > count) 640 len = count; 641 sector_num = offset >> SECTOR_BITS; 642 if (len > 0) { 643 if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0) 644 return -EIO; 645 memcpy(tmp_buf + (offset & (SECTOR_SIZE - 1)), buf, len); 646 if (bdrv_write(bs, sector_num, tmp_buf, 1) < 0) 647 return -EIO; 648 count -= len; 649 if (count == 0) 650 return count1; 651 sector_num++; 652 buf += len; 653 } 654 655 /* write the sectors "in place" */ 656 nb_sectors = count >> SECTOR_BITS; 657 if (nb_sectors > 0) { 658 if (bdrv_write(bs, sector_num, buf, nb_sectors) < 0) 659 return -EIO; 660 sector_num += nb_sectors; 661 len = nb_sectors << SECTOR_BITS; 662 buf += len; 663 count -= len; 664 } 665 666 /* add data from the last sector */ 667 if (count > 0) { 668 if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0) 669 return -EIO; 670 memcpy(tmp_buf, buf, count); 671 if (bdrv_write(bs, sector_num, tmp_buf, 1) < 0) 672 return -EIO; 673 } 674 return count1; 675 } 676 677 /** 678 * Read with byte offsets (needed only for file protocols) 679 */ 680 int bdrv_pread(BlockDriverState *bs, int64_t offset, 681 void *buf1, int count1) 682 { 683 BlockDriver *drv = bs->drv; 684 685 if (!drv) 686 return -ENOMEDIUM; 687 if (!drv->bdrv_pread) 688 return bdrv_pread_em(bs, offset, buf1, count1); 689 return drv->bdrv_pread(bs, offset, buf1, count1); 690 } 691 692 /** 693 * Write with byte offsets (needed only for file protocols) 694 */ 695 int bdrv_pwrite(BlockDriverState *bs, int64_t offset, 696 const void *buf1, int count1) 697 { 698 BlockDriver *drv = bs->drv; 699 700 if (!drv) 701 return -ENOMEDIUM; 702 if (!drv->bdrv_pwrite) 703 return bdrv_pwrite_em(bs, offset, buf1, count1); 704 return drv->bdrv_pwrite(bs, offset, buf1, count1); 705 } 706 707 /** 708 * Truncate file to 'offset' bytes (needed only for file protocols) 709 */ 710 int bdrv_truncate(BlockDriverState *bs, int64_t offset) 711 { 712 BlockDriver *drv = bs->drv; 713 if (!drv) 714 return -ENOMEDIUM; 715 if (!drv->bdrv_truncate) 716 return -ENOTSUP; 717 return drv->bdrv_truncate(bs, offset); 718 } 719 720 /** 721 * Length of a file in bytes. Return < 0 if error or unknown. 722 */ 723 int64_t bdrv_getlength(BlockDriverState *bs) 724 { 725 BlockDriver *drv = bs->drv; 726 if (!drv) 727 return -ENOMEDIUM; 728 if (!drv->bdrv_getlength) { 729 /* legacy mode */ 730 return bs->total_sectors * SECTOR_SIZE; 731 } 732 return drv->bdrv_getlength(bs); 733 } 734 735 /* return 0 as number of sectors if no device present or error */ 736 void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr) 737 { 738 int64_t length; 739 length = bdrv_getlength(bs); 740 if (length < 0) 741 length = 0; 742 else 743 length = length >> SECTOR_BITS; 744 *nb_sectors_ptr = length; 745 } 746 747 struct partition { 748 uint8_t boot_ind; /* 0x80 - active */ 749 uint8_t head; /* starting head */ 750 uint8_t sector; /* starting sector */ 751 uint8_t cyl; /* starting cylinder */ 752 uint8_t sys_ind; /* What partition type */ 753 uint8_t end_head; /* end head */ 754 uint8_t end_sector; /* end sector */ 755 uint8_t end_cyl; /* end cylinder */ 756 uint32_t start_sect; /* starting sector counting from 0 */ 757 uint32_t nr_sects; /* nr of sectors in partition */ 758 } __attribute__((packed)); 759 760 /* try to guess the disk logical geometry from the MSDOS partition table. Return 0 if OK, -1 if could not guess */ 761 static int guess_disk_lchs(BlockDriverState *bs, 762 int *pcylinders, int *pheads, int *psectors) 763 { 764 uint8_t buf[512]; 765 int ret, i, heads, sectors, cylinders; 766 struct partition *p; 767 uint32_t nr_sects; 768 uint64_t nb_sectors; 769 770 bdrv_get_geometry(bs, &nb_sectors); 771 772 ret = bdrv_read(bs, 0, buf, 1); 773 if (ret < 0) 774 return -1; 775 /* test msdos magic */ 776 if (buf[510] != 0x55 || buf[511] != 0xaa) 777 return -1; 778 for(i = 0; i < 4; i++) { 779 p = ((struct partition *)(buf + 0x1be)) + i; 780 nr_sects = le32_to_cpu(p->nr_sects); 781 if (nr_sects && p->end_head) { 782 /* We make the assumption that the partition terminates on 783 a cylinder boundary */ 784 heads = p->end_head + 1; 785 sectors = p->end_sector & 63; 786 if (sectors == 0) 787 continue; 788 cylinders = nb_sectors / (heads * sectors); 789 if (cylinders < 1 || cylinders > 16383) 790 continue; 791 *pheads = heads; 792 *psectors = sectors; 793 *pcylinders = cylinders; 794 #if 0 795 printf("guessed geometry: LCHS=%d %d %d\n", 796 cylinders, heads, sectors); 797 #endif 798 return 0; 799 } 800 } 801 return -1; 802 } 803 804 void bdrv_guess_geometry(BlockDriverState *bs, int *pcyls, int *pheads, int *psecs) 805 { 806 int translation, lba_detected = 0; 807 int cylinders, heads, secs; 808 uint64_t nb_sectors; 809 810 /* if a geometry hint is available, use it */ 811 bdrv_get_geometry(bs, &nb_sectors); 812 bdrv_get_geometry_hint(bs, &cylinders, &heads, &secs); 813 translation = bdrv_get_translation_hint(bs); 814 if (cylinders != 0) { 815 *pcyls = cylinders; 816 *pheads = heads; 817 *psecs = secs; 818 } else { 819 if (guess_disk_lchs(bs, &cylinders, &heads, &secs) == 0) { 820 if (heads > 16) { 821 /* if heads > 16, it means that a BIOS LBA 822 translation was active, so the default 823 hardware geometry is OK */ 824 lba_detected = 1; 825 goto default_geometry; 826 } else { 827 *pcyls = cylinders; 828 *pheads = heads; 829 *psecs = secs; 830 /* disable any translation to be in sync with 831 the logical geometry */ 832 if (translation == BIOS_ATA_TRANSLATION_AUTO) { 833 bdrv_set_translation_hint(bs, 834 BIOS_ATA_TRANSLATION_NONE); 835 } 836 } 837 } else { 838 default_geometry: 839 /* if no geometry, use a standard physical disk geometry */ 840 cylinders = nb_sectors / (16 * 63); 841 842 if (cylinders > 16383) 843 cylinders = 16383; 844 else if (cylinders < 2) 845 cylinders = 2; 846 *pcyls = cylinders; 847 *pheads = 16; 848 *psecs = 63; 849 if ((lba_detected == 1) && (translation == BIOS_ATA_TRANSLATION_AUTO)) { 850 if ((*pcyls * *pheads) <= 131072) { 851 bdrv_set_translation_hint(bs, 852 BIOS_ATA_TRANSLATION_LARGE); 853 } else { 854 bdrv_set_translation_hint(bs, 855 BIOS_ATA_TRANSLATION_LBA); 856 } 857 } 858 } 859 bdrv_set_geometry_hint(bs, *pcyls, *pheads, *psecs); 860 } 861 } 862 863 void bdrv_set_geometry_hint(BlockDriverState *bs, 864 int cyls, int heads, int secs) 865 { 866 bs->cyls = cyls; 867 bs->heads = heads; 868 bs->secs = secs; 869 } 870 871 void bdrv_set_type_hint(BlockDriverState *bs, int type) 872 { 873 bs->type = type; 874 bs->removable = ((type == BDRV_TYPE_CDROM || 875 type == BDRV_TYPE_FLOPPY)); 876 } 877 878 void bdrv_set_translation_hint(BlockDriverState *bs, int translation) 879 { 880 bs->translation = translation; 881 } 882 883 void bdrv_get_geometry_hint(BlockDriverState *bs, 884 int *pcyls, int *pheads, int *psecs) 885 { 886 *pcyls = bs->cyls; 887 *pheads = bs->heads; 888 *psecs = bs->secs; 889 } 890 891 int bdrv_get_type_hint(BlockDriverState *bs) 892 { 893 return bs->type; 894 } 895 896 int bdrv_get_translation_hint(BlockDriverState *bs) 897 { 898 return bs->translation; 899 } 900 901 int bdrv_is_removable(BlockDriverState *bs) 902 { 903 return bs->removable; 904 } 905 906 int bdrv_is_read_only(BlockDriverState *bs) 907 { 908 return bs->read_only; 909 } 910 911 int bdrv_is_sg(BlockDriverState *bs) 912 { 913 return bs->sg; 914 } 915 916 /* XXX: no longer used */ 917 void bdrv_set_change_cb(BlockDriverState *bs, 918 void (*change_cb)(void *opaque), void *opaque) 919 { 920 bs->change_cb = change_cb; 921 bs->change_opaque = opaque; 922 } 923 924 int bdrv_is_encrypted(BlockDriverState *bs) 925 { 926 if (bs->backing_hd && bs->backing_hd->encrypted) 927 return 1; 928 return bs->encrypted; 929 } 930 931 int bdrv_set_key(BlockDriverState *bs, const char *key) 932 { 933 int ret; 934 if (bs->backing_hd && bs->backing_hd->encrypted) { 935 ret = bdrv_set_key(bs->backing_hd, key); 936 if (ret < 0) 937 return ret; 938 if (!bs->encrypted) 939 return 0; 940 } 941 if (!bs->encrypted || !bs->drv || !bs->drv->bdrv_set_key) 942 return -1; 943 return bs->drv->bdrv_set_key(bs, key); 944 } 945 946 void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size) 947 { 948 if (!bs->drv) { 949 buf[0] = '\0'; 950 } else { 951 pstrcpy(buf, buf_size, bs->drv->format_name); 952 } 953 } 954 955 void bdrv_iterate_format(void (*it)(void *opaque, const char *name), 956 void *opaque) 957 { 958 BlockDriver *drv; 959 960 for (drv = first_drv; drv != NULL; drv = drv->next) { 961 it(opaque, drv->format_name); 962 } 963 } 964 965 BlockDriverState *bdrv_find(const char *name) 966 { 967 BlockDriverState *bs; 968 969 for (bs = bdrv_first; bs != NULL; bs = bs->next) { 970 if (!strcmp(name, bs->device_name)) 971 return bs; 972 } 973 return NULL; 974 } 975 976 void bdrv_iterate(void (*it)(void *opaque, const char *name), void *opaque) 977 { 978 BlockDriverState *bs; 979 980 for (bs = bdrv_first; bs != NULL; bs = bs->next) { 981 it(opaque, bs->device_name); 982 } 983 } 984 985 const char *bdrv_get_device_name(BlockDriverState *bs) 986 { 987 return bs->device_name; 988 } 989 990 void bdrv_flush(BlockDriverState *bs) 991 { 992 if (bs->drv->bdrv_flush) 993 bs->drv->bdrv_flush(bs); 994 if (bs->backing_hd) 995 bdrv_flush(bs->backing_hd); 996 } 997 998 void bdrv_flush_all(void) 999 { 1000 BlockDriverState *bs; 1001 1002 for (bs = bdrv_first; bs != NULL; bs = bs->next) 1003 if (bs->drv && !bdrv_is_read_only(bs) && 1004 (!bdrv_is_removable(bs) || bdrv_is_inserted(bs))) 1005 bdrv_flush(bs); 1006 } 1007 1008 /* 1009 * Returns true iff the specified sector is present in the disk image. Drivers 1010 * not implementing the functionality are assumed to not support backing files, 1011 * hence all their sectors are reported as allocated. 1012 * 1013 * 'pnum' is set to the number of sectors (including and immediately following 1014 * the specified sector) that are known to be in the same 1015 * allocated/unallocated state. 1016 * 1017 * 'nb_sectors' is the max value 'pnum' should be set to. 1018 */ 1019 int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors, 1020 int *pnum) 1021 { 1022 int64_t n; 1023 if (!bs->drv->bdrv_is_allocated) { 1024 if (sector_num >= bs->total_sectors) { 1025 *pnum = 0; 1026 return 0; 1027 } 1028 n = bs->total_sectors - sector_num; 1029 *pnum = (n < nb_sectors) ? (n) : (nb_sectors); 1030 return 1; 1031 } 1032 return bs->drv->bdrv_is_allocated(bs, sector_num, nb_sectors, pnum); 1033 } 1034 1035 void bdrv_info(void) 1036 { 1037 BlockDriverState *bs; 1038 1039 for (bs = bdrv_first; bs != NULL; bs = bs->next) { 1040 term_printf("%s:", bs->device_name); 1041 term_printf(" type="); 1042 switch(bs->type) { 1043 case BDRV_TYPE_HD: 1044 term_printf("hd"); 1045 break; 1046 case BDRV_TYPE_CDROM: 1047 term_printf("cdrom"); 1048 break; 1049 case BDRV_TYPE_FLOPPY: 1050 term_printf("floppy"); 1051 break; 1052 } 1053 term_printf(" removable=%d", bs->removable); 1054 if (bs->removable) { 1055 term_printf(" locked=%d", bs->locked); 1056 } 1057 if (bs->drv) { 1058 term_printf(" file="); 1059 term_print_filename(bs->filename); 1060 if (bs->backing_file[0] != '\0') { 1061 term_printf(" backing_file="); 1062 term_print_filename(bs->backing_file); 1063 } 1064 term_printf(" ro=%d", bs->read_only); 1065 term_printf(" drv=%s", bs->drv->format_name); 1066 if (bs->encrypted) 1067 term_printf(" encrypted"); 1068 } else { 1069 term_printf(" [not inserted]"); 1070 } 1071 term_printf("\n"); 1072 } 1073 } 1074 1075 /* The "info blockstats" command. */ 1076 void bdrv_info_stats (void) 1077 { 1078 BlockDriverState *bs; 1079 1080 for (bs = bdrv_first; bs != NULL; bs = bs->next) { 1081 term_printf ("%s:" 1082 " rd_bytes=%" PRIu64 1083 " wr_bytes=%" PRIu64 1084 " rd_operations=%" PRIu64 1085 " wr_operations=%" PRIu64 1086 "\n", 1087 bs->device_name, 1088 bs->rd_bytes, bs->wr_bytes, 1089 bs->rd_ops, bs->wr_ops); 1090 } 1091 } 1092 1093 void bdrv_get_backing_filename(BlockDriverState *bs, 1094 char *filename, int filename_size) 1095 { 1096 if (!bs->backing_hd) { 1097 pstrcpy(filename, filename_size, ""); 1098 } else { 1099 pstrcpy(filename, filename_size, bs->backing_file); 1100 } 1101 } 1102 1103 int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num, 1104 const uint8_t *buf, int nb_sectors) 1105 { 1106 BlockDriver *drv = bs->drv; 1107 if (!drv) 1108 return -ENOMEDIUM; 1109 if (!drv->bdrv_write_compressed) 1110 return -ENOTSUP; 1111 return drv->bdrv_write_compressed(bs, sector_num, buf, nb_sectors); 1112 } 1113 1114 int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi) 1115 { 1116 BlockDriver *drv = bs->drv; 1117 if (!drv) 1118 return -ENOMEDIUM; 1119 if (!drv->bdrv_get_info) 1120 return -ENOTSUP; 1121 memset(bdi, 0, sizeof(*bdi)); 1122 return drv->bdrv_get_info(bs, bdi); 1123 } 1124 1125 /**************************************************************/ 1126 /* handling of snapshots */ 1127 1128 int bdrv_snapshot_create(BlockDriverState *bs, 1129 QEMUSnapshotInfo *sn_info) 1130 { 1131 BlockDriver *drv = bs->drv; 1132 if (!drv) 1133 return -ENOMEDIUM; 1134 if (!drv->bdrv_snapshot_create) 1135 return -ENOTSUP; 1136 return drv->bdrv_snapshot_create(bs, sn_info); 1137 } 1138 1139 int bdrv_snapshot_goto(BlockDriverState *bs, 1140 const char *snapshot_id) 1141 { 1142 BlockDriver *drv = bs->drv; 1143 if (!drv) 1144 return -ENOMEDIUM; 1145 if (!drv->bdrv_snapshot_goto) 1146 return -ENOTSUP; 1147 return drv->bdrv_snapshot_goto(bs, snapshot_id); 1148 } 1149 1150 int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id) 1151 { 1152 BlockDriver *drv = bs->drv; 1153 if (!drv) 1154 return -ENOMEDIUM; 1155 if (!drv->bdrv_snapshot_delete) 1156 return -ENOTSUP; 1157 return drv->bdrv_snapshot_delete(bs, snapshot_id); 1158 } 1159 1160 int bdrv_snapshot_list(BlockDriverState *bs, 1161 QEMUSnapshotInfo **psn_info) 1162 { 1163 BlockDriver *drv = bs->drv; 1164 if (!drv) 1165 return -ENOMEDIUM; 1166 if (!drv->bdrv_snapshot_list) 1167 return -ENOTSUP; 1168 return drv->bdrv_snapshot_list(bs, psn_info); 1169 } 1170 1171 #define NB_SUFFIXES 4 1172 1173 char *get_human_readable_size(char *buf, int buf_size, int64_t size) 1174 { 1175 static const char suffixes[NB_SUFFIXES] = "KMGT"; 1176 int64_t base; 1177 int i; 1178 1179 if (size <= 999) { 1180 snprintf(buf, buf_size, "%" PRId64, size); 1181 } else { 1182 base = 1024; 1183 for(i = 0; i < NB_SUFFIXES; i++) { 1184 if (size < (10 * base)) { 1185 snprintf(buf, buf_size, "%0.1f%c", 1186 (double)size / base, 1187 suffixes[i]); 1188 break; 1189 } else if (size < (1000 * base) || i == (NB_SUFFIXES - 1)) { 1190 snprintf(buf, buf_size, "%" PRId64 "%c", 1191 ((size + (base >> 1)) / base), 1192 suffixes[i]); 1193 break; 1194 } 1195 base = base * 1024; 1196 } 1197 } 1198 return buf; 1199 } 1200 1201 char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn) 1202 { 1203 char buf1[128], date_buf[128], clock_buf[128]; 1204 #ifdef _WIN32 1205 struct tm *ptm; 1206 #else 1207 struct tm tm; 1208 #endif 1209 time_t ti; 1210 int64_t secs; 1211 1212 if (!sn) { 1213 snprintf(buf, buf_size, 1214 "%-10s%-20s%7s%20s%15s", 1215 "ID", "TAG", "VM SIZE", "DATE", "VM CLOCK"); 1216 } else { 1217 ti = sn->date_sec; 1218 #ifdef _WIN32 1219 ptm = localtime(&ti); 1220 strftime(date_buf, sizeof(date_buf), 1221 "%Y-%m-%d %H:%M:%S", ptm); 1222 #else 1223 localtime_r(&ti, &tm); 1224 strftime(date_buf, sizeof(date_buf), 1225 "%Y-%m-%d %H:%M:%S", &tm); 1226 #endif 1227 secs = sn->vm_clock_nsec / 1000000000; 1228 snprintf(clock_buf, sizeof(clock_buf), 1229 "%02d:%02d:%02d.%03d", 1230 (int)(secs / 3600), 1231 (int)((secs / 60) % 60), 1232 (int)(secs % 60), 1233 (int)((sn->vm_clock_nsec / 1000000) % 1000)); 1234 snprintf(buf, buf_size, 1235 "%-10s%-20s%7s%20s%15s", 1236 sn->id_str, sn->name, 1237 get_human_readable_size(buf1, sizeof(buf1), sn->vm_state_size), 1238 date_buf, 1239 clock_buf); 1240 } 1241 return buf; 1242 } 1243 1244 1245 /**************************************************************/ 1246 /* async I/Os */ 1247 1248 BlockDriverAIOCB *bdrv_aio_read(BlockDriverState *bs, int64_t sector_num, 1249 uint8_t *buf, int nb_sectors, 1250 BlockDriverCompletionFunc *cb, void *opaque) 1251 { 1252 BlockDriver *drv = bs->drv; 1253 BlockDriverAIOCB *ret; 1254 1255 if (!drv) 1256 return NULL; 1257 1258 ret = drv->bdrv_aio_read(bs, sector_num, buf, nb_sectors, cb, opaque); 1259 1260 if (ret) { 1261 /* Update stats even though technically transfer has not happened. */ 1262 bs->rd_bytes += (unsigned) nb_sectors * SECTOR_SIZE; 1263 bs->rd_ops ++; 1264 } 1265 1266 return ret; 1267 } 1268 1269 BlockDriverAIOCB *bdrv_aio_write(BlockDriverState *bs, int64_t sector_num, 1270 const uint8_t *buf, int nb_sectors, 1271 BlockDriverCompletionFunc *cb, void *opaque) 1272 { 1273 BlockDriver *drv = bs->drv; 1274 BlockDriverAIOCB *ret; 1275 1276 if (!drv) 1277 return NULL; 1278 if (bs->read_only) 1279 return NULL; 1280 1281 ret = drv->bdrv_aio_write(bs, sector_num, buf, nb_sectors, cb, opaque); 1282 1283 if (ret) { 1284 /* Update stats even though technically transfer has not happened. */ 1285 bs->wr_bytes += (unsigned) nb_sectors * SECTOR_SIZE; 1286 bs->wr_ops ++; 1287 } 1288 1289 return ret; 1290 } 1291 1292 void bdrv_aio_cancel(BlockDriverAIOCB *acb) 1293 { 1294 BlockDriver *drv = acb->bs->drv; 1295 1296 drv->bdrv_aio_cancel(acb); 1297 } 1298 1299 1300 /**************************************************************/ 1301 /* async block device emulation */ 1302 1303 static void bdrv_aio_bh_cb(void *opaque) 1304 { 1305 BlockDriverAIOCBSync *acb = opaque; 1306 acb->common.cb(acb->common.opaque, acb->ret); 1307 qemu_aio_release(acb); 1308 } 1309 1310 static BlockDriverAIOCB *bdrv_aio_read_em(BlockDriverState *bs, 1311 int64_t sector_num, uint8_t *buf, int nb_sectors, 1312 BlockDriverCompletionFunc *cb, void *opaque) 1313 { 1314 BlockDriverAIOCBSync *acb; 1315 int ret; 1316 1317 acb = qemu_aio_get(bs, cb, opaque); 1318 if (!acb->bh) 1319 acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb); 1320 ret = bdrv_read(bs, sector_num, buf, nb_sectors); 1321 acb->ret = ret; 1322 qemu_bh_schedule(acb->bh); 1323 return &acb->common; 1324 } 1325 1326 static BlockDriverAIOCB *bdrv_aio_write_em(BlockDriverState *bs, 1327 int64_t sector_num, const uint8_t *buf, int nb_sectors, 1328 BlockDriverCompletionFunc *cb, void *opaque) 1329 { 1330 BlockDriverAIOCBSync *acb; 1331 int ret; 1332 1333 acb = qemu_aio_get(bs, cb, opaque); 1334 if (!acb->bh) 1335 acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb); 1336 ret = bdrv_write(bs, sector_num, buf, nb_sectors); 1337 acb->ret = ret; 1338 qemu_bh_schedule(acb->bh); 1339 return &acb->common; 1340 } 1341 1342 static void bdrv_aio_cancel_em(BlockDriverAIOCB *blockacb) 1343 { 1344 BlockDriverAIOCBSync *acb = (BlockDriverAIOCBSync *)blockacb; 1345 qemu_bh_cancel(acb->bh); 1346 qemu_aio_release(acb); 1347 } 1348 1349 /**************************************************************/ 1350 /* sync block device emulation */ 1351 1352 static void bdrv_rw_em_cb(void *opaque, int ret) 1353 { 1354 *(int *)opaque = ret; 1355 } 1356 1357 #define NOT_DONE 0x7fffffff 1358 1359 static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num, 1360 uint8_t *buf, int nb_sectors) 1361 { 1362 int async_ret; 1363 BlockDriverAIOCB *acb; 1364 1365 async_ret = NOT_DONE; 1366 acb = bdrv_aio_read(bs, sector_num, buf, nb_sectors, 1367 bdrv_rw_em_cb, &async_ret); 1368 if (acb == NULL) 1369 return -1; 1370 1371 while (async_ret == NOT_DONE) { 1372 qemu_aio_wait(); 1373 } 1374 1375 return async_ret; 1376 } 1377 1378 static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num, 1379 const uint8_t *buf, int nb_sectors) 1380 { 1381 int async_ret; 1382 BlockDriverAIOCB *acb; 1383 1384 async_ret = NOT_DONE; 1385 acb = bdrv_aio_write(bs, sector_num, buf, nb_sectors, 1386 bdrv_rw_em_cb, &async_ret); 1387 if (acb == NULL) 1388 return -1; 1389 while (async_ret == NOT_DONE) { 1390 qemu_aio_wait(); 1391 } 1392 return async_ret; 1393 } 1394 1395 void bdrv_init(void) 1396 { 1397 bdrv_register(&bdrv_raw); 1398 bdrv_register(&bdrv_host_device); 1399 #ifndef _WIN32 1400 bdrv_register(&bdrv_cow); 1401 #endif 1402 bdrv_register(&bdrv_qcow); 1403 bdrv_register(&bdrv_vmdk); 1404 bdrv_register(&bdrv_cloop); 1405 bdrv_register(&bdrv_dmg); 1406 bdrv_register(&bdrv_bochs); 1407 bdrv_register(&bdrv_vpc); 1408 bdrv_register(&bdrv_vvfat); 1409 bdrv_register(&bdrv_qcow2); 1410 bdrv_register(&bdrv_parallels); 1411 bdrv_register(&bdrv_nbd); 1412 } 1413 1414 void *qemu_aio_get(BlockDriverState *bs, BlockDriverCompletionFunc *cb, 1415 void *opaque) 1416 { 1417 BlockDriver *drv; 1418 BlockDriverAIOCB *acb; 1419 1420 drv = bs->drv; 1421 if (drv->free_aiocb) { 1422 acb = drv->free_aiocb; 1423 drv->free_aiocb = acb->next; 1424 } else { 1425 acb = qemu_mallocz(drv->aiocb_size); 1426 if (!acb) 1427 return NULL; 1428 } 1429 acb->bs = bs; 1430 acb->cb = cb; 1431 acb->opaque = opaque; 1432 return acb; 1433 } 1434 1435 void qemu_aio_release(void *p) 1436 { 1437 BlockDriverAIOCB *acb = p; 1438 BlockDriver *drv = acb->bs->drv; 1439 acb->next = drv->free_aiocb; 1440 drv->free_aiocb = acb; 1441 } 1442 1443 /**************************************************************/ 1444 /* removable device support */ 1445 1446 /** 1447 * Return TRUE if the media is present 1448 */ 1449 int bdrv_is_inserted(BlockDriverState *bs) 1450 { 1451 BlockDriver *drv = bs->drv; 1452 int ret; 1453 if (!drv) 1454 return 0; 1455 if (!drv->bdrv_is_inserted) 1456 return 1; 1457 ret = drv->bdrv_is_inserted(bs); 1458 return ret; 1459 } 1460 1461 /** 1462 * Return TRUE if the media changed since the last call to this 1463 * function. It is currently only used for floppy disks 1464 */ 1465 int bdrv_media_changed(BlockDriverState *bs) 1466 { 1467 BlockDriver *drv = bs->drv; 1468 int ret; 1469 1470 if (!drv || !drv->bdrv_media_changed) 1471 ret = -ENOTSUP; 1472 else 1473 ret = drv->bdrv_media_changed(bs); 1474 if (ret == -ENOTSUP) 1475 ret = bs->media_changed; 1476 bs->media_changed = 0; 1477 return ret; 1478 } 1479 1480 /** 1481 * If eject_flag is TRUE, eject the media. Otherwise, close the tray 1482 */ 1483 void bdrv_eject(BlockDriverState *bs, int eject_flag) 1484 { 1485 BlockDriver *drv = bs->drv; 1486 int ret; 1487 1488 if (!drv || !drv->bdrv_eject) { 1489 ret = -ENOTSUP; 1490 } else { 1491 ret = drv->bdrv_eject(bs, eject_flag); 1492 } 1493 if (ret == -ENOTSUP) { 1494 if (eject_flag) 1495 bdrv_close(bs); 1496 } 1497 } 1498 1499 int bdrv_is_locked(BlockDriverState *bs) 1500 { 1501 return bs->locked; 1502 } 1503 1504 /** 1505 * Lock or unlock the media (if it is locked, the user won't be able 1506 * to eject it manually). 1507 */ 1508 void bdrv_set_locked(BlockDriverState *bs, int locked) 1509 { 1510 BlockDriver *drv = bs->drv; 1511 1512 bs->locked = locked; 1513 if (drv && drv->bdrv_set_locked) { 1514 drv->bdrv_set_locked(bs, locked); 1515 } 1516 } 1517 1518 /* needed for generic scsi interface */ 1519 1520 int bdrv_ioctl(BlockDriverState *bs, unsigned long int req, void *buf) 1521 { 1522 BlockDriver *drv = bs->drv; 1523 1524 if (drv && drv->bdrv_ioctl) 1525 return drv->bdrv_ioctl(bs, req, buf); 1526 return -ENOTSUP; 1527 } 1528