1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* 2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Block driver for RAW files (posix) 3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * 4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Copyright (c) 2006 Fabrice Bellard 5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * 6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Permission is hereby granted, free of charge, to any person obtaining a copy 7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * of this software and associated documentation files (the "Software"), to deal 8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * in the Software without restriction, including without limitation the rights 9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * copies of the Software, and to permit persons to whom the Software is 11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * furnished to do so, subject to the following conditions: 12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * 13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * The above copyright notice and this permission notice shall be included in 14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * all copies or substantial portions of the Software. 15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * 16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * 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 "qemu-common.h" 25#include "qemu/timer.h" 26#include "sysemu/char.h" 27#include "qemu/log.h" 28#include "block/block_int.h" 29#include "qemu/module.h" 30#include "block/raw-posix-aio.h" 31 32#ifdef CONFIG_COCOA 33#include <paths.h> 34#include <sys/param.h> 35#include <IOKit/IOKitLib.h> 36#include <IOKit/IOBSD.h> 37#include <IOKit/storage/IOMediaBSDClient.h> 38#include <IOKit/storage/IOMedia.h> 39#include <IOKit/storage/IOCDMedia.h> 40//#include <IOKit/storage/IOCDTypes.h> 41#include <CoreFoundation/CoreFoundation.h> 42#endif 43 44#ifdef __sun__ 45#define _POSIX_PTHREAD_SEMANTICS 1 46#include <signal.h> 47#include <sys/dkio.h> 48#endif 49#ifdef __linux__ 50#include <sys/ioctl.h> 51#include <linux/cdrom.h> 52#include <linux/fd.h> 53#endif 54#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__) 55#include <signal.h> 56#include <sys/disk.h> 57#include <sys/cdio.h> 58#endif 59 60#ifdef __OpenBSD__ 61#include <sys/ioctl.h> 62#include <sys/disklabel.h> 63#include <sys/dkio.h> 64#endif 65 66#ifdef __DragonFly__ 67#include <sys/ioctl.h> 68#include <sys/diskslice.h> 69#endif 70 71//#define DEBUG_FLOPPY 72 73//#define DEBUG_BLOCK 74#if defined(DEBUG_BLOCK) 75#define DEBUG_BLOCK_PRINT(formatCstr, ...) do { if (qemu_log_enabled()) \ 76 { qemu_log(formatCstr, ## __VA_ARGS__); qemu_log_flush(); } } while (0) 77#else 78#define DEBUG_BLOCK_PRINT(formatCstr, ...) 79#endif 80 81/* OS X does not have O_DSYNC */ 82#ifndef O_DSYNC 83#ifdef O_SYNC 84#define O_DSYNC O_SYNC 85#elif defined(O_FSYNC) 86#define O_DSYNC O_FSYNC 87#endif 88#endif 89 90/* Approximate O_DIRECT with O_DSYNC if O_DIRECT isn't available */ 91#ifndef O_DIRECT 92#define O_DIRECT O_DSYNC 93#endif 94 95#define FTYPE_FILE 0 96#define FTYPE_CD 1 97#define FTYPE_FD 2 98 99#define ALIGNED_BUFFER_SIZE (32 * 512) 100 101/* if the FD is not accessed during that time (in ms), we try to 102 reopen it to see if the disk has been changed */ 103#define FD_OPEN_TIMEOUT 1000 104 105typedef struct BDRVRawState { 106 int fd; 107 int type; 108 int open_flags; 109#if defined(__linux__) 110 /* linux floppy specific */ 111 int64_t fd_open_time; 112 int64_t fd_error_time; 113 int fd_got_error; 114 int fd_media_changed; 115#endif 116#ifdef CONFIG_LINUX_AIO 117 int use_aio; 118 void *aio_ctx; 119#endif 120 uint8_t* aligned_buf; 121} BDRVRawState; 122 123static int fd_open(BlockDriverState *bs); 124static int64_t raw_getlength(BlockDriverState *bs); 125 126#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) 127static int cdrom_reopen(BlockDriverState *bs); 128#endif 129 130static int raw_open_common(BlockDriverState *bs, const char *filename, 131 int bdrv_flags, int open_flags) 132{ 133 BDRVRawState *s = bs->opaque; 134 int fd, ret; 135 136 s->open_flags = open_flags | O_BINARY; 137 s->open_flags &= ~O_ACCMODE; 138 if (bdrv_flags & BDRV_O_RDWR) { 139 s->open_flags |= O_RDWR; 140 } else { 141 s->open_flags |= O_RDONLY; 142 } 143 144 /* Use O_DSYNC for write-through caching, no flags for write-back caching, 145 * and O_DIRECT for no caching. */ 146 if ((bdrv_flags & BDRV_O_NOCACHE)) 147 s->open_flags |= O_DIRECT; 148 else if (!(bdrv_flags & BDRV_O_CACHE_WB)) 149 s->open_flags |= O_DSYNC; 150 151 s->fd = -1; 152 fd = qemu_open(filename, s->open_flags, 0644); 153 if (fd < 0) { 154 ret = -errno; 155 if (ret == -EROFS) 156 ret = -EACCES; 157 return ret; 158 } 159 s->fd = fd; 160 s->aligned_buf = NULL; 161 162 if ((bdrv_flags & BDRV_O_NOCACHE)) { 163 s->aligned_buf = qemu_blockalign(bs, ALIGNED_BUFFER_SIZE); 164 if (s->aligned_buf == NULL) { 165 goto out_close; 166 } 167 } 168 169#ifdef CONFIG_LINUX_AIO 170 if ((bdrv_flags & (BDRV_O_NOCACHE|BDRV_O_NATIVE_AIO)) == 171 (BDRV_O_NOCACHE|BDRV_O_NATIVE_AIO)) { 172 173 /* We're falling back to POSIX AIO in some cases */ 174 paio_init(); 175 176 s->aio_ctx = laio_init(); 177 if (!s->aio_ctx) { 178 goto out_free_buf; 179 } 180 s->use_aio = 1; 181 } else 182#endif 183 { 184 if (paio_init() < 0) { 185 goto out_free_buf; 186 } 187#ifdef CONFIG_LINUX_AIO 188 s->use_aio = 0; 189#endif 190 } 191 192 return 0; 193 194out_free_buf: 195 qemu_vfree(s->aligned_buf); 196out_close: 197 close(fd); 198 return -errno; 199} 200 201static int raw_open(BlockDriverState *bs, const char *filename, int flags) 202{ 203 BDRVRawState *s = bs->opaque; 204 205 s->type = FTYPE_FILE; 206 return raw_open_common(bs, filename, flags, 0); 207} 208 209/* XXX: use host sector size if necessary with: 210#ifdef DIOCGSECTORSIZE 211 { 212 unsigned int sectorsize = 512; 213 if (!ioctl(fd, DIOCGSECTORSIZE, §orsize) && 214 sectorsize > bufsize) 215 bufsize = sectorsize; 216 } 217#endif 218#ifdef CONFIG_COCOA 219 uint32_t blockSize = 512; 220 if ( !ioctl( fd, DKIOCGETBLOCKSIZE, &blockSize ) && blockSize > bufsize) { 221 bufsize = blockSize; 222 } 223#endif 224*/ 225 226/* 227 * offset and count are in bytes, but must be multiples of 512 for files 228 * opened with O_DIRECT. buf must be aligned to 512 bytes then. 229 * 230 * This function may be called without alignment if the caller ensures 231 * that O_DIRECT is not in effect. 232 */ 233static int raw_pread_aligned(BlockDriverState *bs, int64_t offset, 234 uint8_t *buf, int count) 235{ 236 BDRVRawState *s = bs->opaque; 237 int ret; 238 239 ret = fd_open(bs); 240 if (ret < 0) 241 return ret; 242 243 ret = pread(s->fd, buf, count, offset); 244 if (ret == count) 245 return ret; 246 247 /* Allow reads beyond the end (needed for pwrite) */ 248 if ((ret == 0) && bs->growable) { 249 int64_t size = raw_getlength(bs); 250 if (offset >= size) { 251 memset(buf, 0, count); 252 return count; 253 } 254 } 255 256 DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64 257 "] read failed %d : %d = %s\n", 258 s->fd, bs->filename, offset, buf, count, 259 bs->total_sectors, ret, errno, strerror(errno)); 260 261 /* Try harder for CDrom. */ 262 if (s->type != FTYPE_FILE) { 263 ret = pread(s->fd, buf, count, offset); 264 if (ret == count) 265 return ret; 266 ret = pread(s->fd, buf, count, offset); 267 if (ret == count) 268 return ret; 269 270 DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64 271 "] retry read failed %d : %d = %s\n", 272 s->fd, bs->filename, offset, buf, count, 273 bs->total_sectors, ret, errno, strerror(errno)); 274 } 275 276 return (ret < 0) ? -errno : ret; 277} 278 279/* 280 * offset and count are in bytes, but must be multiples of 512 for files 281 * opened with O_DIRECT. buf must be aligned to 512 bytes then. 282 * 283 * This function may be called without alignment if the caller ensures 284 * that O_DIRECT is not in effect. 285 */ 286static int raw_pwrite_aligned(BlockDriverState *bs, int64_t offset, 287 const uint8_t *buf, int count) 288{ 289 BDRVRawState *s = bs->opaque; 290 int ret; 291 292 ret = fd_open(bs); 293 if (ret < 0) 294 return -errno; 295 296 ret = pwrite(s->fd, buf, count, offset); 297 if (ret == count) 298 return ret; 299 300 DEBUG_BLOCK_PRINT("raw_pwrite(%d:%s, %" PRId64 ", %p, %d) [%" PRId64 301 "] write failed %d : %d = %s\n", 302 s->fd, bs->filename, offset, buf, count, 303 bs->total_sectors, ret, errno, strerror(errno)); 304 305 return (ret < 0) ? -errno : ret; 306} 307 308 309/* 310 * offset and count are in bytes and possibly not aligned. For files opened 311 * with O_DIRECT, necessary alignments are ensured before calling 312 * raw_pread_aligned to do the actual read. 313 */ 314static int raw_pread(BlockDriverState *bs, int64_t offset, 315 uint8_t *buf, int count) 316{ 317 BDRVRawState *s = bs->opaque; 318 int size, ret, shift, sum; 319 320 sum = 0; 321 322 if (s->aligned_buf != NULL) { 323 324 if (offset & 0x1ff) { 325 /* align offset on a 512 bytes boundary */ 326 327 shift = offset & 0x1ff; 328 size = (shift + count + 0x1ff) & ~0x1ff; 329 if (size > ALIGNED_BUFFER_SIZE) 330 size = ALIGNED_BUFFER_SIZE; 331 ret = raw_pread_aligned(bs, offset - shift, s->aligned_buf, size); 332 if (ret < 0) 333 return ret; 334 335 size = 512 - shift; 336 if (size > count) 337 size = count; 338 memcpy(buf, s->aligned_buf + shift, size); 339 340 buf += size; 341 offset += size; 342 count -= size; 343 sum += size; 344 345 if (count == 0) 346 return sum; 347 } 348 if (count & 0x1ff || (uintptr_t) buf & 0x1ff) { 349 350 /* read on aligned buffer */ 351 352 while (count) { 353 354 size = (count + 0x1ff) & ~0x1ff; 355 if (size > ALIGNED_BUFFER_SIZE) 356 size = ALIGNED_BUFFER_SIZE; 357 358 ret = raw_pread_aligned(bs, offset, s->aligned_buf, size); 359 if (ret < 0) { 360 return ret; 361 } else if (ret == 0) { 362 fprintf(stderr, "raw_pread: read beyond end of file\n"); 363 abort(); 364 } 365 366 size = ret; 367 if (size > count) 368 size = count; 369 370 memcpy(buf, s->aligned_buf, size); 371 372 buf += size; 373 offset += size; 374 count -= size; 375 sum += size; 376 } 377 378 return sum; 379 } 380 } 381 382 return raw_pread_aligned(bs, offset, buf, count) + sum; 383} 384 385static int raw_read(BlockDriverState *bs, int64_t sector_num, 386 uint8_t *buf, int nb_sectors) 387{ 388 int ret; 389 390 ret = raw_pread(bs, sector_num * BDRV_SECTOR_SIZE, buf, 391 nb_sectors * BDRV_SECTOR_SIZE); 392 if (ret == (nb_sectors * BDRV_SECTOR_SIZE)) 393 ret = 0; 394 return ret; 395} 396 397/* 398 * offset and count are in bytes and possibly not aligned. For files opened 399 * with O_DIRECT, necessary alignments are ensured before calling 400 * raw_pwrite_aligned to do the actual write. 401 */ 402static int raw_pwrite(BlockDriverState *bs, int64_t offset, 403 const uint8_t *buf, int count) 404{ 405 BDRVRawState *s = bs->opaque; 406 int size, ret, shift, sum; 407 408 sum = 0; 409 410 if (s->aligned_buf != NULL) { 411 412 if (offset & 0x1ff) { 413 /* align offset on a 512 bytes boundary */ 414 shift = offset & 0x1ff; 415 ret = raw_pread_aligned(bs, offset - shift, s->aligned_buf, 512); 416 if (ret < 0) 417 return ret; 418 419 size = 512 - shift; 420 if (size > count) 421 size = count; 422 memcpy(s->aligned_buf + shift, buf, size); 423 424 ret = raw_pwrite_aligned(bs, offset - shift, s->aligned_buf, 512); 425 if (ret < 0) 426 return ret; 427 428 buf += size; 429 offset += size; 430 count -= size; 431 sum += size; 432 433 if (count == 0) 434 return sum; 435 } 436 if (count & 0x1ff || (uintptr_t) buf & 0x1ff) { 437 438 while ((size = (count & ~0x1ff)) != 0) { 439 440 if (size > ALIGNED_BUFFER_SIZE) 441 size = ALIGNED_BUFFER_SIZE; 442 443 memcpy(s->aligned_buf, buf, size); 444 445 ret = raw_pwrite_aligned(bs, offset, s->aligned_buf, size); 446 if (ret < 0) 447 return ret; 448 449 buf += ret; 450 offset += ret; 451 count -= ret; 452 sum += ret; 453 } 454 /* here, count < 512 because (count & ~0x1ff) == 0 */ 455 if (count) { 456 ret = raw_pread_aligned(bs, offset, s->aligned_buf, 512); 457 if (ret < 0) 458 return ret; 459 memcpy(s->aligned_buf, buf, count); 460 461 ret = raw_pwrite_aligned(bs, offset, s->aligned_buf, 512); 462 if (ret < 0) 463 return ret; 464 if (count < ret) 465 ret = count; 466 467 sum += ret; 468 } 469 return sum; 470 } 471 } 472 return raw_pwrite_aligned(bs, offset, buf, count) + sum; 473} 474 475static int raw_write(BlockDriverState *bs, int64_t sector_num, 476 const uint8_t *buf, int nb_sectors) 477{ 478 int ret; 479 ret = raw_pwrite(bs, sector_num * BDRV_SECTOR_SIZE, buf, 480 nb_sectors * BDRV_SECTOR_SIZE); 481 if (ret == (nb_sectors * BDRV_SECTOR_SIZE)) 482 ret = 0; 483 return ret; 484} 485 486/* 487 * Check if all memory in this vector is sector aligned. 488 */ 489static int qiov_is_aligned(QEMUIOVector *qiov) 490{ 491 int i; 492 493 for (i = 0; i < qiov->niov; i++) { 494 if ((uintptr_t) qiov->iov[i].iov_base % BDRV_SECTOR_SIZE) { 495 return 0; 496 } 497 } 498 499 return 1; 500} 501 502static BlockDriverAIOCB *raw_aio_submit(BlockDriverState *bs, 503 int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, 504 BlockDriverCompletionFunc *cb, void *opaque, int type) 505{ 506 BDRVRawState *s = bs->opaque; 507 508 if (fd_open(bs) < 0) 509 return NULL; 510 511 /* 512 * If O_DIRECT is used the buffer needs to be aligned on a sector 513 * boundary. Check if this is the case or telll the low-level 514 * driver that it needs to copy the buffer. 515 */ 516 if (s->aligned_buf) { 517 if (!qiov_is_aligned(qiov)) { 518 type |= QEMU_AIO_MISALIGNED; 519#ifdef CONFIG_LINUX_AIO 520 } else if (s->use_aio) { 521 return laio_submit(bs, s->aio_ctx, s->fd, sector_num, qiov, 522 nb_sectors, cb, opaque, type); 523#endif 524 } 525 } 526 527 return paio_submit(bs, s->fd, sector_num, qiov, nb_sectors, 528 cb, opaque, type); 529} 530 531static BlockDriverAIOCB *raw_aio_readv(BlockDriverState *bs, 532 int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, 533 BlockDriverCompletionFunc *cb, void *opaque) 534{ 535 return raw_aio_submit(bs, sector_num, qiov, nb_sectors, 536 cb, opaque, QEMU_AIO_READ); 537} 538 539static BlockDriverAIOCB *raw_aio_writev(BlockDriverState *bs, 540 int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, 541 BlockDriverCompletionFunc *cb, void *opaque) 542{ 543 return raw_aio_submit(bs, sector_num, qiov, nb_sectors, 544 cb, opaque, QEMU_AIO_WRITE); 545} 546 547static BlockDriverAIOCB *raw_aio_flush(BlockDriverState *bs, 548 BlockDriverCompletionFunc *cb, void *opaque) 549{ 550 BDRVRawState *s = bs->opaque; 551 552 if (fd_open(bs) < 0) 553 return NULL; 554 555 return paio_submit(bs, s->fd, 0, NULL, 0, cb, opaque, QEMU_AIO_FLUSH); 556} 557 558static void raw_close(BlockDriverState *bs) 559{ 560 BDRVRawState *s = bs->opaque; 561 if (s->fd >= 0) { 562 close(s->fd); 563 s->fd = -1; 564 if (s->aligned_buf != NULL) 565 qemu_vfree(s->aligned_buf); 566 } 567} 568 569static int raw_truncate(BlockDriverState *bs, int64_t offset) 570{ 571 BDRVRawState *s = bs->opaque; 572 if (s->type != FTYPE_FILE) 573 return -ENOTSUP; 574 if (ftruncate(s->fd, offset) < 0) 575 return -errno; 576 return 0; 577} 578 579#ifdef __OpenBSD__ 580static int64_t raw_getlength(BlockDriverState *bs) 581{ 582 BDRVRawState *s = bs->opaque; 583 int fd = s->fd; 584 struct stat st; 585 586 if (fstat(fd, &st)) 587 return -1; 588 if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) { 589 struct disklabel dl; 590 591 if (ioctl(fd, DIOCGDINFO, &dl)) 592 return -1; 593 return (uint64_t)dl.d_secsize * 594 dl.d_partitions[DISKPART(st.st_rdev)].p_size; 595 } else 596 return st.st_size; 597} 598#elif defined(__sun__) 599static int64_t raw_getlength(BlockDriverState *bs) 600{ 601 BDRVRawState *s = bs->opaque; 602 struct dk_minfo minfo; 603 int ret; 604 605 ret = fd_open(bs); 606 if (ret < 0) { 607 return ret; 608 } 609 610 /* 611 * Use the DKIOCGMEDIAINFO ioctl to read the size. 612 */ 613 ret = ioctl(s->fd, DKIOCGMEDIAINFO, &minfo); 614 if (ret != -1) { 615 return minfo.dki_lbsize * minfo.dki_capacity; 616 } 617 618 /* 619 * There are reports that lseek on some devices fails, but 620 * irc discussion said that contingency on contingency was overkill. 621 */ 622 return lseek(s->fd, 0, SEEK_END); 623} 624#elif defined(CONFIG_BSD) 625static int64_t raw_getlength(BlockDriverState *bs) 626{ 627 BDRVRawState *s = bs->opaque; 628 int fd = s->fd; 629 int64_t size; 630 struct stat sb; 631#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__) 632 int reopened = 0; 633#endif 634 int ret; 635 636 ret = fd_open(bs); 637 if (ret < 0) 638 return ret; 639 640#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__) 641again: 642#endif 643 if (!fstat(fd, &sb) && (S_IFCHR & sb.st_mode)) { 644#ifdef DIOCGMEDIASIZE 645 if (ioctl(fd, DIOCGMEDIASIZE, (off_t *)&size)) 646#elif defined(DIOCGPART) 647 { 648 struct partinfo pi; 649 if (ioctl(fd, DIOCGPART, &pi) == 0) 650 size = pi.media_size; 651 else 652 size = 0; 653 } 654 if (size == 0) 655#endif 656#ifdef CONFIG_COCOA 657 size = LONG_LONG_MAX; 658#else 659 size = lseek(fd, 0LL, SEEK_END); 660#endif 661#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) 662 switch(s->type) { 663 case FTYPE_CD: 664 /* XXX FreeBSD acd returns UINT_MAX sectors for an empty drive */ 665 if (size == 2048LL * (unsigned)-1) 666 size = 0; 667 /* XXX no disc? maybe we need to reopen... */ 668 if (size <= 0 && !reopened && cdrom_reopen(bs) >= 0) { 669 reopened = 1; 670 goto again; 671 } 672 } 673#endif 674 } else { 675 size = lseek(fd, 0, SEEK_END); 676 } 677 return size; 678} 679#else 680static int64_t raw_getlength(BlockDriverState *bs) 681{ 682 BDRVRawState *s = bs->opaque; 683 int ret; 684 685 ret = fd_open(bs); 686 if (ret < 0) { 687 return ret; 688 } 689 690 return lseek(s->fd, 0, SEEK_END); 691} 692#endif 693 694static int raw_create(const char *filename, QEMUOptionParameter *options) 695{ 696 int fd; 697 int result = 0; 698 int64_t total_size = 0; 699 700 /* Read out options */ 701 while (options && options->name) { 702 if (!strcmp(options->name, BLOCK_OPT_SIZE)) { 703 total_size = options->value.n / BDRV_SECTOR_SIZE; 704 } 705 options++; 706 } 707 708 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 709 0644); 710 if (fd < 0) { 711 result = -errno; 712 } else { 713 if (ftruncate(fd, total_size * BDRV_SECTOR_SIZE) != 0) { 714 result = -errno; 715 } 716 if (close(fd) != 0) { 717 result = -errno; 718 } 719 } 720 return result; 721} 722 723static void raw_flush(BlockDriverState *bs) 724{ 725 BDRVRawState *s = bs->opaque; 726 qemu_fdatasync(s->fd); 727} 728 729 730static QEMUOptionParameter raw_create_options[] = { 731 { 732 .name = BLOCK_OPT_SIZE, 733 .type = OPT_SIZE, 734 .help = "Virtual disk size" 735 }, 736 { NULL } 737}; 738 739static BlockDriver bdrv_file = { 740 .format_name = "file", 741 .protocol_name = "file", 742 .instance_size = sizeof(BDRVRawState), 743 .bdrv_probe = NULL, /* no probe for protocols */ 744 .bdrv_file_open = raw_open, 745 .bdrv_read = raw_read, 746 .bdrv_write = raw_write, 747 .bdrv_close = raw_close, 748 .bdrv_create = raw_create, 749 .bdrv_flush = raw_flush, 750 751 .bdrv_aio_readv = raw_aio_readv, 752 .bdrv_aio_writev = raw_aio_writev, 753 .bdrv_aio_flush = raw_aio_flush, 754 755 .bdrv_truncate = raw_truncate, 756 .bdrv_getlength = raw_getlength, 757 758 .create_options = raw_create_options, 759}; 760 761/***********************************************/ 762/* host device */ 763 764#ifdef CONFIG_COCOA 765static kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator ); 766static kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex maxPathSize ); 767 768kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator ) 769{ 770 kern_return_t kernResult; 771 mach_port_t masterPort; 772 CFMutableDictionaryRef classesToMatch; 773 774 kernResult = IOMasterPort( MACH_PORT_NULL, &masterPort ); 775 if ( KERN_SUCCESS != kernResult ) { 776 printf( "IOMasterPort returned %d\n", kernResult ); 777 } 778 779 classesToMatch = IOServiceMatching( kIOCDMediaClass ); 780 if ( classesToMatch == NULL ) { 781 printf( "IOServiceMatching returned a NULL dictionary.\n" ); 782 } else { 783 CFDictionarySetValue( classesToMatch, CFSTR( kIOMediaEjectableKey ), kCFBooleanTrue ); 784 } 785 kernResult = IOServiceGetMatchingServices( masterPort, classesToMatch, mediaIterator ); 786 if ( KERN_SUCCESS != kernResult ) 787 { 788 printf( "IOServiceGetMatchingServices returned %d\n", kernResult ); 789 } 790 791 return kernResult; 792} 793 794kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex maxPathSize ) 795{ 796 io_object_t nextMedia; 797 kern_return_t kernResult = KERN_FAILURE; 798 *bsdPath = '\0'; 799 nextMedia = IOIteratorNext( mediaIterator ); 800 if ( nextMedia ) 801 { 802 CFTypeRef bsdPathAsCFString; 803 bsdPathAsCFString = IORegistryEntryCreateCFProperty( nextMedia, CFSTR( kIOBSDNameKey ), kCFAllocatorDefault, 0 ); 804 if ( bsdPathAsCFString ) { 805 size_t devPathLength; 806 strcpy( bsdPath, _PATH_DEV ); 807 strcat( bsdPath, "r" ); 808 devPathLength = strlen( bsdPath ); 809 if ( CFStringGetCString( bsdPathAsCFString, bsdPath + devPathLength, maxPathSize - devPathLength, kCFStringEncodingASCII ) ) { 810 kernResult = KERN_SUCCESS; 811 } 812 CFRelease( bsdPathAsCFString ); 813 } 814 IOObjectRelease( nextMedia ); 815 } 816 817 return kernResult; 818} 819 820#endif 821 822static int hdev_probe_device(const char *filename) 823{ 824 struct stat st; 825 826 /* allow a dedicated CD-ROM driver to match with a higher priority */ 827 if (strstart(filename, "/dev/cdrom", NULL)) 828 return 50; 829 830 if (stat(filename, &st) >= 0 && 831 (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode))) { 832 return 100; 833 } 834 835 return 0; 836} 837 838static int hdev_open(BlockDriverState *bs, const char *filename, int flags) 839{ 840 BDRVRawState *s = bs->opaque; 841 842#ifdef CONFIG_COCOA 843 if (strstart(filename, "/dev/cdrom", NULL)) { 844 kern_return_t kernResult; 845 io_iterator_t mediaIterator; 846 char bsdPath[ MAXPATHLEN ]; 847 int fd; 848 849 kernResult = FindEjectableCDMedia( &mediaIterator ); 850 kernResult = GetBSDPath( mediaIterator, bsdPath, sizeof( bsdPath ) ); 851 852 if ( bsdPath[ 0 ] != '\0' ) { 853 strcat(bsdPath,"s0"); 854 /* some CDs don't have a partition 0 */ 855 fd = open(bsdPath, O_RDONLY | O_BINARY | O_LARGEFILE); 856 if (fd < 0) { 857 bsdPath[strlen(bsdPath)-1] = '1'; 858 } else { 859 close(fd); 860 } 861 filename = bsdPath; 862 } 863 864 if ( mediaIterator ) 865 IOObjectRelease( mediaIterator ); 866 } 867#endif 868 869 s->type = FTYPE_FILE; 870#if defined(__linux__) 871 if (strstart(filename, "/dev/sg", NULL)) { 872 bs->sg = 1; 873 } 874#endif 875 876 return raw_open_common(bs, filename, flags, 0); 877} 878 879#if defined(__linux__) 880/* Note: we do not have a reliable method to detect if the floppy is 881 present. The current method is to try to open the floppy at every 882 I/O and to keep it opened during a few hundreds of ms. */ 883static int fd_open(BlockDriverState *bs) 884{ 885 BDRVRawState *s = bs->opaque; 886 int last_media_present; 887 888 if (s->type != FTYPE_FD) 889 return 0; 890 last_media_present = (s->fd >= 0); 891 if (s->fd >= 0 && 892 (qemu_clock_get_ms(QEMU_CLOCK_REALTIME) - s->fd_open_time) >= FD_OPEN_TIMEOUT) { 893 close(s->fd); 894 s->fd = -1; 895#ifdef DEBUG_FLOPPY 896 printf("Floppy closed\n"); 897#endif 898 } 899 if (s->fd < 0) { 900 if (s->fd_got_error && 901 (qemu_clock_get_ms(QEMU_CLOCK_REALTIME) - s->fd_error_time) < FD_OPEN_TIMEOUT) { 902#ifdef DEBUG_FLOPPY 903 printf("No floppy (open delayed)\n"); 904#endif 905 return -EIO; 906 } 907 s->fd = open(bs->filename, s->open_flags & ~O_NONBLOCK); 908 if (s->fd < 0) { 909 s->fd_error_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME); 910 s->fd_got_error = 1; 911 if (last_media_present) 912 s->fd_media_changed = 1; 913#ifdef DEBUG_FLOPPY 914 printf("No floppy\n"); 915#endif 916 return -EIO; 917 } 918#ifdef DEBUG_FLOPPY 919 printf("Floppy opened\n"); 920#endif 921 } 922 if (!last_media_present) 923 s->fd_media_changed = 1; 924 s->fd_open_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME); 925 s->fd_got_error = 0; 926 return 0; 927} 928 929static int hdev_ioctl(BlockDriverState *bs, unsigned long int req, void *buf) 930{ 931 BDRVRawState *s = bs->opaque; 932 933 return ioctl(s->fd, req, buf); 934} 935 936static BlockDriverAIOCB *hdev_aio_ioctl(BlockDriverState *bs, 937 unsigned long int req, void *buf, 938 BlockDriverCompletionFunc *cb, void *opaque) 939{ 940 BDRVRawState *s = bs->opaque; 941 942 if (fd_open(bs) < 0) 943 return NULL; 944 return paio_ioctl(bs, s->fd, req, buf, cb, opaque); 945} 946 947#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) 948static int fd_open(BlockDriverState *bs) 949{ 950 BDRVRawState *s = bs->opaque; 951 952 /* this is just to ensure s->fd is sane (its called by io ops) */ 953 if (s->fd >= 0) 954 return 0; 955 return -EIO; 956} 957#else /* !linux && !FreeBSD */ 958 959static int fd_open(BlockDriverState *bs) 960{ 961 return 0; 962} 963 964#endif /* !linux && !FreeBSD */ 965 966static int hdev_create(const char *filename, QEMUOptionParameter *options) 967{ 968 int fd; 969 int ret = 0; 970 struct stat stat_buf; 971 int64_t total_size = 0; 972 973 /* Read out options */ 974 while (options && options->name) { 975 if (!strcmp(options->name, "size")) { 976 total_size = options->value.n / BDRV_SECTOR_SIZE; 977 } 978 options++; 979 } 980 981 fd = open(filename, O_WRONLY | O_BINARY); 982 if (fd < 0) 983 return -errno; 984 985 if (fstat(fd, &stat_buf) < 0) 986 ret = -errno; 987 else if (!S_ISBLK(stat_buf.st_mode) && !S_ISCHR(stat_buf.st_mode)) 988 ret = -ENODEV; 989 else if (lseek(fd, 0, SEEK_END) < total_size * BDRV_SECTOR_SIZE) 990 ret = -ENOSPC; 991 992 close(fd); 993 return ret; 994} 995 996static int hdev_has_zero_init(BlockDriverState *bs) 997{ 998 return 0; 999} 1000 1001static BlockDriver bdrv_host_device = { 1002 .format_name = "host_device", 1003 .protocol_name = "host_device", 1004 .instance_size = sizeof(BDRVRawState), 1005 .bdrv_probe_device = hdev_probe_device, 1006 .bdrv_file_open = hdev_open, 1007 .bdrv_close = raw_close, 1008 .bdrv_create = hdev_create, 1009 .create_options = raw_create_options, 1010 .bdrv_has_zero_init = hdev_has_zero_init, 1011 .bdrv_flush = raw_flush, 1012 1013 .bdrv_aio_readv = raw_aio_readv, 1014 .bdrv_aio_writev = raw_aio_writev, 1015 .bdrv_aio_flush = raw_aio_flush, 1016 1017 .bdrv_read = raw_read, 1018 .bdrv_write = raw_write, 1019 .bdrv_getlength = raw_getlength, 1020 1021 /* generic scsi device */ 1022#ifdef __linux__ 1023 .bdrv_ioctl = hdev_ioctl, 1024 .bdrv_aio_ioctl = hdev_aio_ioctl, 1025#endif 1026}; 1027 1028#ifdef __linux__ 1029static int floppy_open(BlockDriverState *bs, const char *filename, int flags) 1030{ 1031 BDRVRawState *s = bs->opaque; 1032 int ret; 1033 1034 s->type = FTYPE_FD; 1035 1036 /* open will not fail even if no floppy is inserted, so add O_NONBLOCK */ 1037 ret = raw_open_common(bs, filename, flags, O_NONBLOCK); 1038 if (ret) 1039 return ret; 1040 1041 /* close fd so that we can reopen it as needed */ 1042 close(s->fd); 1043 s->fd = -1; 1044 s->fd_media_changed = 1; 1045 1046 return 0; 1047} 1048 1049static int floppy_probe_device(const char *filename) 1050{ 1051 int fd, ret; 1052 int prio = 0; 1053 struct floppy_struct fdparam; 1054 1055 if (strstart(filename, "/dev/fd", NULL)) 1056 prio = 50; 1057 1058 fd = open(filename, O_RDONLY | O_NONBLOCK); 1059 if (fd < 0) { 1060 goto out; 1061 } 1062 1063 /* Attempt to detect via a floppy specific ioctl */ 1064 ret = ioctl(fd, FDGETPRM, &fdparam); 1065 if (ret >= 0) 1066 prio = 100; 1067 1068 close(fd); 1069out: 1070 return prio; 1071} 1072 1073 1074static int floppy_is_inserted(BlockDriverState *bs) 1075{ 1076 return fd_open(bs) >= 0; 1077} 1078 1079static int floppy_media_changed(BlockDriverState *bs) 1080{ 1081 BDRVRawState *s = bs->opaque; 1082 int ret; 1083 1084 /* 1085 * XXX: we do not have a true media changed indication. 1086 * It does not work if the floppy is changed without trying to read it. 1087 */ 1088 fd_open(bs); 1089 ret = s->fd_media_changed; 1090 s->fd_media_changed = 0; 1091#ifdef DEBUG_FLOPPY 1092 printf("Floppy changed=%d\n", ret); 1093#endif 1094 return ret; 1095} 1096 1097static int floppy_eject(BlockDriverState *bs, int eject_flag) 1098{ 1099 BDRVRawState *s = bs->opaque; 1100 int fd; 1101 1102 if (s->fd >= 0) { 1103 close(s->fd); 1104 s->fd = -1; 1105 } 1106 fd = open(bs->filename, s->open_flags | O_NONBLOCK); 1107 if (fd >= 0) { 1108 if (ioctl(fd, FDEJECT, 0) < 0) 1109 perror("FDEJECT"); 1110 close(fd); 1111 } 1112 1113 return 0; 1114} 1115 1116static BlockDriver bdrv_host_floppy = { 1117 .format_name = "host_floppy", 1118 .protocol_name = "host_floppy", 1119 .instance_size = sizeof(BDRVRawState), 1120 .bdrv_probe_device = floppy_probe_device, 1121 .bdrv_file_open = floppy_open, 1122 .bdrv_close = raw_close, 1123 .bdrv_create = hdev_create, 1124 .create_options = raw_create_options, 1125 .bdrv_has_zero_init = hdev_has_zero_init, 1126 .bdrv_flush = raw_flush, 1127 1128 .bdrv_aio_readv = raw_aio_readv, 1129 .bdrv_aio_writev = raw_aio_writev, 1130 .bdrv_aio_flush = raw_aio_flush, 1131 1132 .bdrv_read = raw_read, 1133 .bdrv_write = raw_write, 1134 .bdrv_getlength = raw_getlength, 1135 1136 /* removable device support */ 1137 .bdrv_is_inserted = floppy_is_inserted, 1138 .bdrv_media_changed = floppy_media_changed, 1139 .bdrv_eject = floppy_eject, 1140}; 1141 1142static int cdrom_open(BlockDriverState *bs, const char *filename, int flags) 1143{ 1144 BDRVRawState *s = bs->opaque; 1145 1146 s->type = FTYPE_CD; 1147 1148 /* open will not fail even if no CD is inserted, so add O_NONBLOCK */ 1149 return raw_open_common(bs, filename, flags, O_NONBLOCK); 1150} 1151 1152static int cdrom_probe_device(const char *filename) 1153{ 1154 int fd, ret; 1155 int prio = 0; 1156 1157 if (strstart(filename, "/dev/cd", NULL)) 1158 prio = 50; 1159 1160 fd = open(filename, O_RDONLY | O_NONBLOCK); 1161 if (fd < 0) { 1162 goto out; 1163 } 1164 1165 /* Attempt to detect via a CDROM specific ioctl */ 1166 ret = ioctl(fd, CDROM_DRIVE_STATUS, CDSL_CURRENT); 1167 if (ret >= 0) 1168 prio = 100; 1169 1170 close(fd); 1171out: 1172 return prio; 1173} 1174 1175static int cdrom_is_inserted(BlockDriverState *bs) 1176{ 1177 BDRVRawState *s = bs->opaque; 1178 int ret; 1179 1180 ret = ioctl(s->fd, CDROM_DRIVE_STATUS, CDSL_CURRENT); 1181 if (ret == CDS_DISC_OK) 1182 return 1; 1183 return 0; 1184} 1185 1186static int cdrom_eject(BlockDriverState *bs, int eject_flag) 1187{ 1188 BDRVRawState *s = bs->opaque; 1189 1190 if (eject_flag) { 1191 if (ioctl(s->fd, CDROMEJECT, NULL) < 0) 1192 perror("CDROMEJECT"); 1193 } else { 1194 if (ioctl(s->fd, CDROMCLOSETRAY, NULL) < 0) 1195 perror("CDROMEJECT"); 1196 } 1197 1198 return 0; 1199} 1200 1201static int cdrom_set_locked(BlockDriverState *bs, int locked) 1202{ 1203 BDRVRawState *s = bs->opaque; 1204 1205 if (ioctl(s->fd, CDROM_LOCKDOOR, locked) < 0) { 1206 /* 1207 * Note: an error can happen if the distribution automatically 1208 * mounts the CD-ROM 1209 */ 1210 /* perror("CDROM_LOCKDOOR"); */ 1211 } 1212 1213 return 0; 1214} 1215 1216static BlockDriver bdrv_host_cdrom = { 1217 .format_name = "host_cdrom", 1218 .protocol_name = "host_cdrom", 1219 .instance_size = sizeof(BDRVRawState), 1220 .bdrv_probe_device = cdrom_probe_device, 1221 .bdrv_file_open = cdrom_open, 1222 .bdrv_close = raw_close, 1223 .bdrv_create = hdev_create, 1224 .create_options = raw_create_options, 1225 .bdrv_has_zero_init = hdev_has_zero_init, 1226 .bdrv_flush = raw_flush, 1227 1228 .bdrv_aio_readv = raw_aio_readv, 1229 .bdrv_aio_writev = raw_aio_writev, 1230 .bdrv_aio_flush = raw_aio_flush, 1231 1232 .bdrv_read = raw_read, 1233 .bdrv_write = raw_write, 1234 .bdrv_getlength = raw_getlength, 1235 1236 /* removable device support */ 1237 .bdrv_is_inserted = cdrom_is_inserted, 1238 .bdrv_eject = cdrom_eject, 1239 .bdrv_set_locked = cdrom_set_locked, 1240 1241 /* generic scsi device */ 1242 .bdrv_ioctl = hdev_ioctl, 1243 .bdrv_aio_ioctl = hdev_aio_ioctl, 1244}; 1245#endif /* __linux__ */ 1246 1247#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__) 1248static int cdrom_open(BlockDriverState *bs, const char *filename, int flags) 1249{ 1250 BDRVRawState *s = bs->opaque; 1251 int ret; 1252 1253 s->type = FTYPE_CD; 1254 1255 ret = raw_open_common(bs, filename, flags, 0); 1256 if (ret) 1257 return ret; 1258 1259 /* make sure the door isnt locked at this time */ 1260 ioctl(s->fd, CDIOCALLOW); 1261 return 0; 1262} 1263 1264static int cdrom_probe_device(const char *filename) 1265{ 1266 if (strstart(filename, "/dev/cd", NULL) || 1267 strstart(filename, "/dev/acd", NULL)) 1268 return 100; 1269 return 0; 1270} 1271 1272static int cdrom_reopen(BlockDriverState *bs) 1273{ 1274 BDRVRawState *s = bs->opaque; 1275 int fd; 1276 1277 /* 1278 * Force reread of possibly changed/newly loaded disc, 1279 * FreeBSD seems to not notice sometimes... 1280 */ 1281 if (s->fd >= 0) 1282 close(s->fd); 1283 fd = open(bs->filename, s->open_flags, 0644); 1284 if (fd < 0) { 1285 s->fd = -1; 1286 return -EIO; 1287 } 1288 s->fd = fd; 1289 1290 /* make sure the door isnt locked at this time */ 1291 ioctl(s->fd, CDIOCALLOW); 1292 return 0; 1293} 1294 1295static int cdrom_is_inserted(BlockDriverState *bs) 1296{ 1297 return raw_getlength(bs) > 0; 1298} 1299 1300static int cdrom_eject(BlockDriverState *bs, int eject_flag) 1301{ 1302 BDRVRawState *s = bs->opaque; 1303 1304 if (s->fd < 0) 1305 return -ENOTSUP; 1306 1307 (void) ioctl(s->fd, CDIOCALLOW); 1308 1309 if (eject_flag) { 1310 if (ioctl(s->fd, CDIOCEJECT) < 0) 1311 perror("CDIOCEJECT"); 1312 } else { 1313 if (ioctl(s->fd, CDIOCCLOSE) < 0) 1314 perror("CDIOCCLOSE"); 1315 } 1316 1317 if (cdrom_reopen(bs) < 0) 1318 return -ENOTSUP; 1319 return 0; 1320} 1321 1322static int cdrom_set_locked(BlockDriverState *bs, int locked) 1323{ 1324 BDRVRawState *s = bs->opaque; 1325 1326 if (s->fd < 0) 1327 return -ENOTSUP; 1328 if (ioctl(s->fd, (locked ? CDIOCPREVENT : CDIOCALLOW)) < 0) { 1329 /* 1330 * Note: an error can happen if the distribution automatically 1331 * mounts the CD-ROM 1332 */ 1333 /* perror("CDROM_LOCKDOOR"); */ 1334 } 1335 1336 return 0; 1337} 1338 1339static BlockDriver bdrv_host_cdrom = { 1340 .format_name = "host_cdrom", 1341 .protocol_name = "host_cdrom", 1342 .instance_size = sizeof(BDRVRawState), 1343 .bdrv_probe_device = cdrom_probe_device, 1344 .bdrv_file_open = cdrom_open, 1345 .bdrv_close = raw_close, 1346 .bdrv_create = hdev_create, 1347 .create_options = raw_create_options, 1348 .bdrv_has_zero_init = hdev_has_zero_init, 1349 .bdrv_flush = raw_flush, 1350 1351 .bdrv_aio_readv = raw_aio_readv, 1352 .bdrv_aio_writev = raw_aio_writev, 1353 .bdrv_aio_flush = raw_aio_flush, 1354 1355 .bdrv_read = raw_read, 1356 .bdrv_write = raw_write, 1357 .bdrv_getlength = raw_getlength, 1358 1359 /* removable device support */ 1360 .bdrv_is_inserted = cdrom_is_inserted, 1361 .bdrv_eject = cdrom_eject, 1362 .bdrv_set_locked = cdrom_set_locked, 1363}; 1364#endif /* __FreeBSD__ */ 1365 1366static void bdrv_file_init(void) 1367{ 1368 /* 1369 * Register all the drivers. Note that order is important, the driver 1370 * registered last will get probed first. 1371 */ 1372 bdrv_register(&bdrv_file); 1373 bdrv_register(&bdrv_host_device); 1374#ifdef __linux__ 1375 bdrv_register(&bdrv_host_floppy); 1376 bdrv_register(&bdrv_host_cdrom); 1377#endif 1378#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) 1379 bdrv_register(&bdrv_host_cdrom); 1380#endif 1381} 1382 1383block_init(bdrv_file_init); 1384