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" 26 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 34 35 static BlockDriverState *bdrv_first; 36 static BlockDriver *first_drv; 37 38 void bdrv_register(BlockDriver *bdrv) 39 { 40 bdrv->next = first_drv; 41 first_drv = bdrv; 42 } 43 44 /* create a new block device (by default it is empty) */ 45 BlockDriverState *bdrv_new(const char *device_name) 46 { 47 BlockDriverState **pbs, *bs; 48 49 bs = qemu_mallocz(sizeof(BlockDriverState)); 50 if(!bs) 51 return NULL; 52 pstrcpy(bs->device_name, sizeof(bs->device_name), device_name); 53 if (device_name[0] != '\0') { 54 /* insert at the end */ 55 pbs = &bdrv_first; 56 while (*pbs != NULL) 57 pbs = &(*pbs)->next; 58 *pbs = bs; 59 } 60 return bs; 61 } 62 63 BlockDriver *bdrv_find_format(const char *format_name) 64 { 65 BlockDriver *drv1; 66 for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) { 67 if (!strcmp(drv1->format_name, format_name)) 68 return drv1; 69 } 70 return NULL; 71 } 72 73 int bdrv_create(BlockDriver *drv, 74 const char *filename, int64_t size_in_sectors, 75 const char *backing_file, int flags) 76 { 77 if (!drv->bdrv_create) 78 return -ENOTSUP; 79 return drv->bdrv_create(filename, size_in_sectors, backing_file, flags); 80 } 81 82 #ifdef _WIN32 83 static void get_tmp_filename(char *filename, int size) 84 { 85 /* XXX: find a better function */ 86 tmpnam(filename); 87 } 88 #else 89 static void get_tmp_filename(char *filename, int size) 90 { 91 int fd; 92 /* XXX: race condition possible */ 93 pstrcpy(filename, size, "/tmp/vl.XXXXXX"); 94 fd = mkstemp(filename); 95 close(fd); 96 } 97 #endif 98 99 /* XXX: force raw format if block or character device ? It would 100 simplify the BSD case */ 101 static BlockDriver *find_image_format(const char *filename) 102 { 103 int fd, ret, score, score_max; 104 BlockDriver *drv1, *drv; 105 uint8_t *buf; 106 size_t bufsize = 1024; 107 108 fd = open(filename, O_RDONLY | O_BINARY | O_LARGEFILE); 109 if (fd < 0) 110 return NULL; 111 #ifdef DIOCGSECTORSIZE 112 { 113 unsigned int sectorsize = 512; 114 if (!ioctl(fd, DIOCGSECTORSIZE, §orsize) && 115 sectorsize > bufsize) 116 bufsize = sectorsize; 117 } 118 #endif 119 buf = malloc(bufsize); 120 if (!buf) 121 return NULL; 122 ret = read(fd, buf, bufsize); 123 if (ret < 0) { 124 close(fd); 125 free(buf); 126 return NULL; 127 } 128 close(fd); 129 130 drv = NULL; 131 score_max = 0; 132 for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) { 133 score = drv1->bdrv_probe(buf, ret, filename); 134 if (score > score_max) { 135 score_max = score; 136 drv = drv1; 137 } 138 } 139 free(buf); 140 return drv; 141 } 142 143 int bdrv_open(BlockDriverState *bs, const char *filename, int snapshot) 144 { 145 return bdrv_open2(bs, filename, snapshot, NULL); 146 } 147 148 int bdrv_open2(BlockDriverState *bs, const char *filename, int snapshot, 149 BlockDriver *drv) 150 { 151 int ret; 152 char tmp_filename[1024]; 153 154 bs->read_only = 0; 155 bs->is_temporary = 0; 156 bs->encrypted = 0; 157 158 if (snapshot) { 159 BlockDriverState *bs1; 160 int64_t total_size; 161 162 /* if snapshot, we create a temporary backing file and open it 163 instead of opening 'filename' directly */ 164 165 /* if there is a backing file, use it */ 166 bs1 = bdrv_new(""); 167 if (!bs1) { 168 return -1; 169 } 170 if (bdrv_open(bs1, filename, 0) < 0) { 171 bdrv_delete(bs1); 172 return -1; 173 } 174 total_size = bs1->total_sectors; 175 bdrv_delete(bs1); 176 177 get_tmp_filename(tmp_filename, sizeof(tmp_filename)); 178 /* XXX: use cow for linux as it is more efficient ? */ 179 if (bdrv_create(&bdrv_qcow, tmp_filename, 180 total_size, filename, 0) < 0) { 181 return -1; 182 } 183 filename = tmp_filename; 184 bs->is_temporary = 1; 185 } 186 187 pstrcpy(bs->filename, sizeof(bs->filename), filename); 188 if (!drv) { 189 drv = find_image_format(filename); 190 if (!drv) 191 return -1; 192 } 193 bs->drv = drv; 194 bs->opaque = qemu_mallocz(drv->instance_size); 195 if (bs->opaque == NULL && drv->instance_size > 0) 196 return -1; 197 198 ret = drv->bdrv_open(bs, filename); 199 if (ret < 0) { 200 qemu_free(bs->opaque); 201 return -1; 202 } 203 #ifndef _WIN32 204 if (bs->is_temporary) { 205 unlink(filename); 206 } 207 #endif 208 if (bs->backing_file[0] != '\0' && drv->bdrv_is_allocated) { 209 /* if there is a backing file, use it */ 210 bs->backing_hd = bdrv_new(""); 211 if (!bs->backing_hd) { 212 fail: 213 bdrv_close(bs); 214 return -1; 215 } 216 if (bdrv_open(bs->backing_hd, bs->backing_file, 0) < 0) 217 goto fail; 218 } 219 220 bs->inserted = 1; 221 222 /* call the change callback */ 223 if (bs->change_cb) 224 bs->change_cb(bs->change_opaque); 225 226 return 0; 227 } 228 229 void bdrv_close(BlockDriverState *bs) 230 { 231 if (bs->inserted) { 232 if (bs->backing_hd) 233 bdrv_delete(bs->backing_hd); 234 bs->drv->bdrv_close(bs); 235 qemu_free(bs->opaque); 236 #ifdef _WIN32 237 if (bs->is_temporary) { 238 unlink(bs->filename); 239 } 240 #endif 241 bs->opaque = NULL; 242 bs->drv = NULL; 243 bs->inserted = 0; 244 245 /* call the change callback */ 246 if (bs->change_cb) 247 bs->change_cb(bs->change_opaque); 248 } 249 } 250 251 void bdrv_delete(BlockDriverState *bs) 252 { 253 /* XXX: remove the driver list */ 254 bdrv_close(bs); 255 qemu_free(bs); 256 } 257 258 /* commit COW file into the raw image */ 259 int bdrv_commit(BlockDriverState *bs) 260 { 261 int64_t i; 262 int n, j; 263 unsigned char sector[512]; 264 265 if (!bs->inserted) 266 return -ENOENT; 267 268 if (bs->read_only) { 269 return -EACCES; 270 } 271 272 if (!bs->backing_hd) { 273 return -ENOTSUP; 274 } 275 276 for (i = 0; i < bs->total_sectors;) { 277 if (bs->drv->bdrv_is_allocated(bs, i, 65536, &n)) { 278 for(j = 0; j < n; j++) { 279 if (bdrv_read(bs, i, sector, 1) != 0) { 280 return -EIO; 281 } 282 283 if (bdrv_write(bs->backing_hd, i, sector, 1) != 0) { 284 return -EIO; 285 } 286 i++; 287 } 288 } else { 289 i += n; 290 } 291 } 292 return 0; 293 } 294 295 /* return -1 if error */ 296 int bdrv_read(BlockDriverState *bs, int64_t sector_num, 297 uint8_t *buf, int nb_sectors) 298 { 299 int ret, n; 300 BlockDriver *drv = bs->drv; 301 302 if (!bs->inserted) 303 return -1; 304 305 while (nb_sectors > 0) { 306 if (sector_num == 0 && bs->boot_sector_enabled) { 307 memcpy(buf, bs->boot_sector_data, 512); 308 n = 1; 309 } else if (bs->backing_hd) { 310 if (drv->bdrv_is_allocated(bs, sector_num, nb_sectors, &n)) { 311 ret = drv->bdrv_read(bs, sector_num, buf, n); 312 if (ret < 0) 313 return -1; 314 } else { 315 /* read from the base image */ 316 ret = bdrv_read(bs->backing_hd, sector_num, buf, n); 317 if (ret < 0) 318 return -1; 319 } 320 } else { 321 ret = drv->bdrv_read(bs, sector_num, buf, nb_sectors); 322 if (ret < 0) 323 return -1; 324 /* no need to loop */ 325 break; 326 } 327 nb_sectors -= n; 328 sector_num += n; 329 buf += n * 512; 330 } 331 return 0; 332 } 333 334 /* return -1 if error */ 335 int bdrv_write(BlockDriverState *bs, int64_t sector_num, 336 const uint8_t *buf, int nb_sectors) 337 { 338 if (!bs->inserted) 339 return -1; 340 if (bs->read_only) 341 return -1; 342 return bs->drv->bdrv_write(bs, sector_num, buf, nb_sectors); 343 } 344 345 void bdrv_get_geometry(BlockDriverState *bs, int64_t *nb_sectors_ptr) 346 { 347 *nb_sectors_ptr = bs->total_sectors; 348 } 349 350 /* force a given boot sector. */ 351 void bdrv_set_boot_sector(BlockDriverState *bs, const uint8_t *data, int size) 352 { 353 bs->boot_sector_enabled = 1; 354 if (size > 512) 355 size = 512; 356 memcpy(bs->boot_sector_data, data, size); 357 memset(bs->boot_sector_data + size, 0, 512 - size); 358 } 359 360 void bdrv_set_geometry_hint(BlockDriverState *bs, 361 int cyls, int heads, int secs) 362 { 363 bs->cyls = cyls; 364 bs->heads = heads; 365 bs->secs = secs; 366 } 367 368 void bdrv_set_type_hint(BlockDriverState *bs, int type) 369 { 370 bs->type = type; 371 bs->removable = ((type == BDRV_TYPE_CDROM || 372 type == BDRV_TYPE_FLOPPY)); 373 } 374 375 void bdrv_set_translation_hint(BlockDriverState *bs, int translation) 376 { 377 bs->translation = translation; 378 } 379 380 void bdrv_get_geometry_hint(BlockDriverState *bs, 381 int *pcyls, int *pheads, int *psecs) 382 { 383 *pcyls = bs->cyls; 384 *pheads = bs->heads; 385 *psecs = bs->secs; 386 } 387 388 int bdrv_get_type_hint(BlockDriverState *bs) 389 { 390 return bs->type; 391 } 392 393 int bdrv_get_translation_hint(BlockDriverState *bs) 394 { 395 return bs->translation; 396 } 397 398 int bdrv_is_removable(BlockDriverState *bs) 399 { 400 return bs->removable; 401 } 402 403 int bdrv_is_read_only(BlockDriverState *bs) 404 { 405 return bs->read_only; 406 } 407 408 int bdrv_is_inserted(BlockDriverState *bs) 409 { 410 return bs->inserted; 411 } 412 413 int bdrv_is_locked(BlockDriverState *bs) 414 { 415 return bs->locked; 416 } 417 418 void bdrv_set_locked(BlockDriverState *bs, int locked) 419 { 420 bs->locked = locked; 421 } 422 423 void bdrv_set_change_cb(BlockDriverState *bs, 424 void (*change_cb)(void *opaque), void *opaque) 425 { 426 bs->change_cb = change_cb; 427 bs->change_opaque = opaque; 428 } 429 430 int bdrv_is_encrypted(BlockDriverState *bs) 431 { 432 if (bs->backing_hd && bs->backing_hd->encrypted) 433 return 1; 434 return bs->encrypted; 435 } 436 437 int bdrv_set_key(BlockDriverState *bs, const char *key) 438 { 439 int ret; 440 if (bs->backing_hd && bs->backing_hd->encrypted) { 441 ret = bdrv_set_key(bs->backing_hd, key); 442 if (ret < 0) 443 return ret; 444 if (!bs->encrypted) 445 return 0; 446 } 447 if (!bs->encrypted || !bs->drv || !bs->drv->bdrv_set_key) 448 return -1; 449 return bs->drv->bdrv_set_key(bs, key); 450 } 451 452 void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size) 453 { 454 if (!bs->inserted || !bs->drv) { 455 buf[0] = '\0'; 456 } else { 457 pstrcpy(buf, buf_size, bs->drv->format_name); 458 } 459 } 460 461 void bdrv_iterate_format(void (*it)(void *opaque, const char *name), 462 void *opaque) 463 { 464 BlockDriver *drv; 465 466 for (drv = first_drv; drv != NULL; drv = drv->next) { 467 it(opaque, drv->format_name); 468 } 469 } 470 471 BlockDriverState *bdrv_find(const char *name) 472 { 473 BlockDriverState *bs; 474 475 for (bs = bdrv_first; bs != NULL; bs = bs->next) { 476 if (!strcmp(name, bs->device_name)) 477 return bs; 478 } 479 return NULL; 480 } 481 482 void bdrv_iterate(void (*it)(void *opaque, const char *name), void *opaque) 483 { 484 BlockDriverState *bs; 485 486 for (bs = bdrv_first; bs != NULL; bs = bs->next) { 487 it(opaque, bs->device_name); 488 } 489 } 490 491 const char *bdrv_get_device_name(BlockDriverState *bs) 492 { 493 return bs->device_name; 494 } 495 496 void bdrv_info(void) 497 { 498 BlockDriverState *bs; 499 500 for (bs = bdrv_first; bs != NULL; bs = bs->next) { 501 term_printf("%s:", bs->device_name); 502 term_printf(" type="); 503 switch(bs->type) { 504 case BDRV_TYPE_HD: 505 term_printf("hd"); 506 break; 507 case BDRV_TYPE_CDROM: 508 term_printf("cdrom"); 509 break; 510 case BDRV_TYPE_FLOPPY: 511 term_printf("floppy"); 512 break; 513 } 514 term_printf(" removable=%d", bs->removable); 515 if (bs->removable) { 516 term_printf(" locked=%d", bs->locked); 517 } 518 if (bs->inserted) { 519 term_printf(" file=%s", bs->filename); 520 if (bs->backing_file[0] != '\0') 521 term_printf(" backing_file=%s", bs->backing_file); 522 term_printf(" ro=%d", bs->read_only); 523 term_printf(" drv=%s", bs->drv->format_name); 524 if (bs->encrypted) 525 term_printf(" encrypted"); 526 } else { 527 term_printf(" [not inserted]"); 528 } 529 term_printf("\n"); 530 } 531 } 532 533 534 /**************************************************************/ 535 /* RAW block driver */ 536 537 typedef struct BDRVRawState { 538 int fd; 539 } BDRVRawState; 540 541 static int raw_probe(const uint8_t *buf, int buf_size, const char *filename) 542 { 543 return 1; /* maybe */ 544 } 545 546 static int raw_open(BlockDriverState *bs, const char *filename) 547 { 548 BDRVRawState *s = bs->opaque; 549 int fd; 550 int64_t size; 551 552 fd = open(filename, O_RDWR | O_BINARY | O_LARGEFILE); 553 if (fd < 0) { 554 fd = open(filename, O_RDONLY | O_BINARY | O_LARGEFILE); 555 if (fd < 0) 556 return -1; 557 bs->read_only = 1; 558 } 559 #ifdef _BSD 560 { 561 struct stat sb; 562 if (!fstat(fd, &sb) && (S_IFCHR & sb.st_mode)) { 563 #ifdef DIOCGMEDIASIZE 564 if (ioctl(fd, DIOCGMEDIASIZE, (off_t *)&size)) 565 #endif 566 size = lseek(fd, 0LL, SEEK_END); 567 } else 568 #endif 569 { 570 size = lseek(fd, 0, SEEK_END); 571 } 572 #ifdef _WIN32 573 /* On Windows hosts it can happen that we're unable to get file size 574 for CD-ROM raw device (it's inherent limitation of the CDFS driver). */ 575 if (size == -1) 576 size = LONG_LONG_MAX; 577 #endif 578 bs->total_sectors = size / 512; 579 s->fd = fd; 580 return 0; 581 } 582 583 static int raw_read(BlockDriverState *bs, int64_t sector_num, 584 uint8_t *buf, int nb_sectors) 585 { 586 BDRVRawState *s = bs->opaque; 587 int ret; 588 589 lseek(s->fd, sector_num * 512, SEEK_SET); 590 ret = read(s->fd, buf, nb_sectors * 512); 591 if (ret != nb_sectors * 512) 592 return -1; 593 return 0; 594 } 595 596 static int raw_write(BlockDriverState *bs, int64_t sector_num, 597 const uint8_t *buf, int nb_sectors) 598 { 599 BDRVRawState *s = bs->opaque; 600 int ret; 601 602 lseek(s->fd, sector_num * 512, SEEK_SET); 603 ret = write(s->fd, buf, nb_sectors * 512); 604 if (ret != nb_sectors * 512) 605 return -1; 606 return 0; 607 } 608 609 static void raw_close(BlockDriverState *bs) 610 { 611 BDRVRawState *s = bs->opaque; 612 close(s->fd); 613 } 614 615 static int raw_create(const char *filename, int64_t total_size, 616 const char *backing_file, int flags) 617 { 618 int fd; 619 620 if (flags || backing_file) 621 return -ENOTSUP; 622 623 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE, 624 0644); 625 if (fd < 0) 626 return -EIO; 627 ftruncate(fd, total_size * 512); 628 close(fd); 629 return 0; 630 } 631 632 BlockDriver bdrv_raw = { 633 "raw", 634 sizeof(BDRVRawState), 635 raw_probe, 636 raw_open, 637 raw_read, 638 raw_write, 639 raw_close, 640 raw_create, 641 }; 642 643 void bdrv_init(void) 644 { 645 bdrv_register(&bdrv_raw); 646 #ifndef _WIN32 647 bdrv_register(&bdrv_cow); 648 #endif 649 bdrv_register(&bdrv_qcow); 650 bdrv_register(&bdrv_vmdk); 651 bdrv_register(&bdrv_cloop); 652 bdrv_register(&bdrv_dmg); 653 bdrv_register(&bdrv_bochs); 654 } 655