Merge commit '60e0df25e415b00cf35c4d214eaba9dc19aaa9e6' into upstream-merge
[qemu/qemu-dev-zwu.git] / block / raw-posix.c
bloba95c8d41645efb3e451afda667b4e9ed57184c3f
1 /*
2 * Block driver for RAW files (posix)
4 * Copyright (c) 2006 Fabrice Bellard
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
24 #include "qemu-common.h"
25 #include "qemu-timer.h"
26 #include "qemu-char.h"
27 #include "qemu-log.h"
28 #include "block_int.h"
29 #include "module.h"
30 #include "compatfd.h"
31 #include <assert.h>
32 #include "block/raw-posix-aio.h"
34 #ifdef CONFIG_COCOA
35 #include <paths.h>
36 #include <sys/param.h>
37 #include <IOKit/IOKitLib.h>
38 #include <IOKit/IOBSD.h>
39 #include <IOKit/storage/IOMediaBSDClient.h>
40 #include <IOKit/storage/IOMedia.h>
41 #include <IOKit/storage/IOCDMedia.h>
42 //#include <IOKit/storage/IOCDTypes.h>
43 #include <CoreFoundation/CoreFoundation.h>
44 #endif
46 #ifdef __sun__
47 #define _POSIX_PTHREAD_SEMANTICS 1
48 #include <signal.h>
49 #include <sys/dkio.h>
50 #endif
51 #ifdef __linux__
52 #include <sys/ioctl.h>
53 #include <sys/param.h>
54 #include <linux/cdrom.h>
55 #include <linux/fd.h>
56 #endif
57 #if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
58 #include <signal.h>
59 #include <sys/disk.h>
60 #include <sys/cdio.h>
61 #endif
63 #ifdef __OpenBSD__
64 #include <sys/ioctl.h>
65 #include <sys/disklabel.h>
66 #include <sys/dkio.h>
67 #endif
69 #ifdef __DragonFly__
70 #include <sys/ioctl.h>
71 #include <sys/diskslice.h>
72 #endif
74 #ifdef CONFIG_XFS
75 #include <xfs/xfs.h>
76 #endif
78 //#define DEBUG_FLOPPY
80 //#define DEBUG_BLOCK
81 #if defined(DEBUG_BLOCK)
82 #define DEBUG_BLOCK_PRINT(formatCstr, ...) do { if (qemu_log_enabled()) \
83 { qemu_log(formatCstr, ## __VA_ARGS__); qemu_log_flush(); } } while (0)
84 #else
85 #define DEBUG_BLOCK_PRINT(formatCstr, ...)
86 #endif
88 /* OS X does not have O_DSYNC */
89 #ifndef O_DSYNC
90 #ifdef O_SYNC
91 #define O_DSYNC O_SYNC
92 #elif defined(O_FSYNC)
93 #define O_DSYNC O_FSYNC
94 #endif
95 #endif
97 /* Approximate O_DIRECT with O_DSYNC if O_DIRECT isn't available */
98 #ifndef O_DIRECT
99 #define O_DIRECT O_DSYNC
100 #endif
102 #define FTYPE_FILE 0
103 #define FTYPE_CD 1
104 #define FTYPE_FD 2
106 /* if the FD is not accessed during that time (in ns), we try to
107 reopen it to see if the disk has been changed */
108 #define FD_OPEN_TIMEOUT (1000000000)
110 #define MAX_BLOCKSIZE 4096
112 typedef struct BDRVRawState {
113 int fd;
114 int type;
115 int open_flags;
116 #if defined(__linux__)
117 /* linux floppy specific */
118 int64_t fd_open_time;
119 int64_t fd_error_time;
120 int fd_got_error;
121 int fd_media_changed;
122 #endif
123 #ifdef CONFIG_LINUX_AIO
124 int use_aio;
125 void *aio_ctx;
126 #endif
127 uint8_t *aligned_buf;
128 unsigned aligned_buf_size;
129 #ifdef CONFIG_XFS
130 bool is_xfs : 1;
131 #endif
132 } BDRVRawState;
134 static int fd_open(BlockDriverState *bs);
135 static int64_t raw_getlength(BlockDriverState *bs);
137 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
138 static int cdrom_reopen(BlockDriverState *bs);
139 #endif
141 static int raw_open_common(BlockDriverState *bs, const char *filename,
142 int bdrv_flags, int open_flags)
144 BDRVRawState *s = bs->opaque;
145 int fd, ret;
147 s->open_flags = open_flags | O_BINARY;
148 s->open_flags &= ~O_ACCMODE;
149 if (bdrv_flags & BDRV_O_RDWR) {
150 s->open_flags |= O_RDWR;
151 } else {
152 s->open_flags |= O_RDONLY;
155 /* Use O_DSYNC for write-through caching, no flags for write-back caching,
156 * and O_DIRECT for no caching. */
157 if ((bdrv_flags & BDRV_O_NOCACHE))
158 s->open_flags |= O_DIRECT;
159 else if (!(bdrv_flags & BDRV_O_CACHE_WB))
160 s->open_flags |= O_DSYNC;
162 s->fd = -1;
163 fd = qemu_open(filename, s->open_flags, 0644);
164 if (fd < 0) {
165 ret = -errno;
166 if (ret == -EROFS)
167 ret = -EACCES;
168 return ret;
170 s->fd = fd;
171 s->aligned_buf = NULL;
173 if ((bdrv_flags & BDRV_O_NOCACHE)) {
175 * Allocate a buffer for read/modify/write cycles. Chose the size
176 * pessimistically as we don't know the block size yet.
178 s->aligned_buf_size = 32 * MAX_BLOCKSIZE;
179 s->aligned_buf = qemu_memalign(MAX_BLOCKSIZE, s->aligned_buf_size);
180 if (s->aligned_buf == NULL) {
181 goto out_close;
185 #ifdef CONFIG_LINUX_AIO
186 if ((bdrv_flags & (BDRV_O_NOCACHE|BDRV_O_NATIVE_AIO)) ==
187 (BDRV_O_NOCACHE|BDRV_O_NATIVE_AIO)) {
189 /* We're falling back to POSIX AIO in some cases */
190 paio_init();
192 s->aio_ctx = laio_init();
193 if (!s->aio_ctx) {
194 goto out_free_buf;
196 s->use_aio = 1;
197 } else
198 #endif
200 if (paio_init() < 0) {
201 goto out_free_buf;
203 #ifdef CONFIG_LINUX_AIO
204 s->use_aio = 0;
205 #endif
208 #ifdef CONFIG_XFS
209 if (platform_test_xfs_fd(s->fd)) {
210 s->is_xfs = 1;
212 #endif
214 return 0;
216 out_free_buf:
217 qemu_vfree(s->aligned_buf);
218 out_close:
219 close(fd);
220 return -errno;
223 static int raw_open(BlockDriverState *bs, const char *filename, int flags)
225 BDRVRawState *s = bs->opaque;
227 s->type = FTYPE_FILE;
228 return raw_open_common(bs, filename, flags, 0);
231 /* XXX: use host sector size if necessary with:
232 #ifdef DIOCGSECTORSIZE
234 unsigned int sectorsize = 512;
235 if (!ioctl(fd, DIOCGSECTORSIZE, &sectorsize) &&
236 sectorsize > bufsize)
237 bufsize = sectorsize;
239 #endif
240 #ifdef CONFIG_COCOA
241 uint32_t blockSize = 512;
242 if ( !ioctl( fd, DKIOCGETBLOCKSIZE, &blockSize ) && blockSize > bufsize) {
243 bufsize = blockSize;
245 #endif
249 * offset and count are in bytes, but must be multiples of 512 for files
250 * opened with O_DIRECT. buf must be aligned to 512 bytes then.
252 * This function may be called without alignment if the caller ensures
253 * that O_DIRECT is not in effect.
255 static int raw_pread_aligned(BlockDriverState *bs, int64_t offset,
256 uint8_t *buf, int count)
258 BDRVRawState *s = bs->opaque;
259 int ret;
261 ret = fd_open(bs);
262 if (ret < 0)
263 return ret;
265 ret = pread(s->fd, buf, count, offset);
266 if (ret == count)
267 return ret;
269 /* Allow reads beyond the end (needed for pwrite) */
270 if ((ret == 0) && bs->growable) {
271 int64_t size = raw_getlength(bs);
272 if (offset >= size) {
273 memset(buf, 0, count);
274 return count;
278 DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
279 "] read failed %d : %d = %s\n",
280 s->fd, bs->filename, offset, buf, count,
281 bs->total_sectors, ret, errno, strerror(errno));
283 /* Try harder for CDrom. */
284 if (s->type != FTYPE_FILE) {
285 ret = pread(s->fd, buf, count, offset);
286 if (ret == count)
287 return ret;
288 ret = pread(s->fd, buf, count, offset);
289 if (ret == count)
290 return ret;
292 DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
293 "] retry read failed %d : %d = %s\n",
294 s->fd, bs->filename, offset, buf, count,
295 bs->total_sectors, ret, errno, strerror(errno));
298 return (ret < 0) ? -errno : ret;
302 * offset and count are in bytes, but must be multiples of the sector size
303 * for files opened with O_DIRECT. buf must be aligned to sector size bytes
304 * then.
306 * This function may be called without alignment if the caller ensures
307 * that O_DIRECT is not in effect.
309 static int raw_pwrite_aligned(BlockDriverState *bs, int64_t offset,
310 const uint8_t *buf, int count)
312 BDRVRawState *s = bs->opaque;
313 int ret;
315 ret = fd_open(bs);
316 if (ret < 0)
317 return -errno;
319 ret = pwrite(s->fd, buf, count, offset);
320 if (ret == count)
321 return ret;
323 DEBUG_BLOCK_PRINT("raw_pwrite(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
324 "] write failed %d : %d = %s\n",
325 s->fd, bs->filename, offset, buf, count,
326 bs->total_sectors, ret, errno, strerror(errno));
328 return (ret < 0) ? -errno : ret;
333 * offset and count are in bytes and possibly not aligned. For files opened
334 * with O_DIRECT, necessary alignments are ensured before calling
335 * raw_pread_aligned to do the actual read.
337 static int raw_pread(BlockDriverState *bs, int64_t offset,
338 uint8_t *buf, int count)
340 BDRVRawState *s = bs->opaque;
341 unsigned sector_mask = bs->buffer_alignment - 1;
342 int size, ret, shift, sum;
344 sum = 0;
346 if (s->aligned_buf != NULL) {
348 if (offset & sector_mask) {
349 /* align offset on a sector size bytes boundary */
351 shift = offset & sector_mask;
352 size = (shift + count + sector_mask) & ~sector_mask;
353 if (size > s->aligned_buf_size)
354 size = s->aligned_buf_size;
355 ret = raw_pread_aligned(bs, offset - shift, s->aligned_buf, size);
356 if (ret < 0)
357 return ret;
359 size = bs->buffer_alignment - shift;
360 if (size > count)
361 size = count;
362 memcpy(buf, s->aligned_buf + shift, size);
364 buf += size;
365 offset += size;
366 count -= size;
367 sum += size;
369 if (count == 0)
370 return sum;
372 if (count & sector_mask || (uintptr_t) buf & sector_mask) {
374 /* read on aligned buffer */
376 while (count) {
378 size = (count + sector_mask) & ~sector_mask;
379 if (size > s->aligned_buf_size)
380 size = s->aligned_buf_size;
382 ret = raw_pread_aligned(bs, offset, s->aligned_buf, size);
383 if (ret < 0) {
384 return ret;
385 } else if (ret == 0) {
386 fprintf(stderr, "raw_pread: read beyond end of file\n");
387 abort();
390 size = ret;
391 if (size > count)
392 size = count;
394 memcpy(buf, s->aligned_buf, size);
396 buf += size;
397 offset += size;
398 count -= size;
399 sum += size;
402 return sum;
406 return raw_pread_aligned(bs, offset, buf, count) + sum;
409 static int raw_read(BlockDriverState *bs, int64_t sector_num,
410 uint8_t *buf, int nb_sectors)
412 int ret;
414 ret = raw_pread(bs, sector_num * BDRV_SECTOR_SIZE, buf,
415 nb_sectors * BDRV_SECTOR_SIZE);
416 if (ret == (nb_sectors * BDRV_SECTOR_SIZE))
417 ret = 0;
418 return ret;
422 * offset and count are in bytes and possibly not aligned. For files opened
423 * with O_DIRECT, necessary alignments are ensured before calling
424 * raw_pwrite_aligned to do the actual write.
426 static int raw_pwrite(BlockDriverState *bs, int64_t offset,
427 const uint8_t *buf, int count)
429 BDRVRawState *s = bs->opaque;
430 unsigned sector_mask = bs->buffer_alignment - 1;
431 int size, ret, shift, sum;
433 sum = 0;
435 if (s->aligned_buf != NULL) {
437 if (offset & sector_mask) {
438 /* align offset on a sector size bytes boundary */
439 shift = offset & sector_mask;
440 ret = raw_pread_aligned(bs, offset - shift, s->aligned_buf,
441 bs->buffer_alignment);
442 if (ret < 0)
443 return ret;
445 size = bs->buffer_alignment - shift;
446 if (size > count)
447 size = count;
448 memcpy(s->aligned_buf + shift, buf, size);
450 ret = raw_pwrite_aligned(bs, offset - shift, s->aligned_buf,
451 bs->buffer_alignment);
452 if (ret < 0)
453 return ret;
455 buf += size;
456 offset += size;
457 count -= size;
458 sum += size;
460 if (count == 0)
461 return sum;
463 if (count & sector_mask || (uintptr_t) buf & sector_mask) {
465 while ((size = (count & ~sector_mask)) != 0) {
467 if (size > s->aligned_buf_size)
468 size = s->aligned_buf_size;
470 memcpy(s->aligned_buf, buf, size);
472 ret = raw_pwrite_aligned(bs, offset, s->aligned_buf, size);
473 if (ret < 0)
474 return ret;
476 buf += ret;
477 offset += ret;
478 count -= ret;
479 sum += ret;
481 /* here, count < sector_size because (count & ~sector_mask) == 0 */
482 if (count) {
483 ret = raw_pread_aligned(bs, offset, s->aligned_buf,
484 bs->buffer_alignment);
485 if (ret < 0)
486 return ret;
487 memcpy(s->aligned_buf, buf, count);
489 ret = raw_pwrite_aligned(bs, offset, s->aligned_buf,
490 bs->buffer_alignment);
491 if (ret < 0)
492 return ret;
493 if (count < ret)
494 ret = count;
496 sum += ret;
498 return sum;
501 return raw_pwrite_aligned(bs, offset, buf, count) + sum;
504 static int raw_write(BlockDriverState *bs, int64_t sector_num,
505 const uint8_t *buf, int nb_sectors)
507 int ret;
508 ret = raw_pwrite(bs, sector_num * BDRV_SECTOR_SIZE, buf,
509 nb_sectors * BDRV_SECTOR_SIZE);
510 if (ret == (nb_sectors * BDRV_SECTOR_SIZE))
511 ret = 0;
512 return ret;
516 * Check if all memory in this vector is sector aligned.
518 static int qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov)
520 int i;
522 for (i = 0; i < qiov->niov; i++) {
523 if ((uintptr_t) qiov->iov[i].iov_base % bs->buffer_alignment) {
524 return 0;
528 return 1;
531 static BlockDriverAIOCB *raw_aio_submit(BlockDriverState *bs,
532 int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
533 BlockDriverCompletionFunc *cb, void *opaque, int type)
535 BDRVRawState *s = bs->opaque;
537 if (fd_open(bs) < 0)
538 return NULL;
541 * If O_DIRECT is used the buffer needs to be aligned on a sector
542 * boundary. Check if this is the case or telll the low-level
543 * driver that it needs to copy the buffer.
545 if (s->aligned_buf) {
546 if (!qiov_is_aligned(bs, qiov)) {
547 type |= QEMU_AIO_MISALIGNED;
548 #ifdef CONFIG_LINUX_AIO
549 } else if (s->use_aio) {
550 return laio_submit(bs, s->aio_ctx, s->fd, sector_num, qiov,
551 nb_sectors, cb, opaque, type);
552 #endif
556 return paio_submit(bs, s->fd, sector_num, qiov, nb_sectors,
557 cb, opaque, type);
560 static BlockDriverAIOCB *raw_aio_readv(BlockDriverState *bs,
561 int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
562 BlockDriverCompletionFunc *cb, void *opaque)
564 return raw_aio_submit(bs, sector_num, qiov, nb_sectors,
565 cb, opaque, QEMU_AIO_READ);
568 static BlockDriverAIOCB *raw_aio_writev(BlockDriverState *bs,
569 int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
570 BlockDriverCompletionFunc *cb, void *opaque)
572 return raw_aio_submit(bs, sector_num, qiov, nb_sectors,
573 cb, opaque, QEMU_AIO_WRITE);
576 static BlockDriverAIOCB *raw_aio_flush(BlockDriverState *bs,
577 BlockDriverCompletionFunc *cb, void *opaque)
579 BDRVRawState *s = bs->opaque;
581 if (fd_open(bs) < 0)
582 return NULL;
584 return paio_submit(bs, s->fd, 0, NULL, 0, cb, opaque, QEMU_AIO_FLUSH);
587 static void raw_close(BlockDriverState *bs)
589 BDRVRawState *s = bs->opaque;
590 if (s->fd >= 0) {
591 close(s->fd);
592 s->fd = -1;
593 if (s->aligned_buf != NULL)
594 qemu_vfree(s->aligned_buf);
598 static int raw_truncate(BlockDriverState *bs, int64_t offset)
600 BDRVRawState *s = bs->opaque;
601 if (s->type != FTYPE_FILE)
602 return -ENOTSUP;
603 if (ftruncate(s->fd, offset) < 0)
604 return -errno;
605 return 0;
608 #ifdef __OpenBSD__
609 static int64_t raw_getlength(BlockDriverState *bs)
611 BDRVRawState *s = bs->opaque;
612 int fd = s->fd;
613 struct stat st;
615 if (fstat(fd, &st))
616 return -1;
617 if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) {
618 struct disklabel dl;
620 if (ioctl(fd, DIOCGDINFO, &dl))
621 return -1;
622 return (uint64_t)dl.d_secsize *
623 dl.d_partitions[DISKPART(st.st_rdev)].p_size;
624 } else
625 return st.st_size;
627 #elif defined(__sun__)
628 static int64_t raw_getlength(BlockDriverState *bs)
630 BDRVRawState *s = bs->opaque;
631 struct dk_minfo minfo;
632 int ret;
634 ret = fd_open(bs);
635 if (ret < 0) {
636 return ret;
640 * Use the DKIOCGMEDIAINFO ioctl to read the size.
642 ret = ioctl(s->fd, DKIOCGMEDIAINFO, &minfo);
643 if (ret != -1) {
644 return minfo.dki_lbsize * minfo.dki_capacity;
648 * There are reports that lseek on some devices fails, but
649 * irc discussion said that contingency on contingency was overkill.
651 return lseek(s->fd, 0, SEEK_END);
653 #elif defined(CONFIG_BSD)
654 static int64_t raw_getlength(BlockDriverState *bs)
656 BDRVRawState *s = bs->opaque;
657 int fd = s->fd;
658 int64_t size;
659 struct stat sb;
660 #if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
661 int reopened = 0;
662 #endif
663 int ret;
665 ret = fd_open(bs);
666 if (ret < 0)
667 return ret;
669 #if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
670 again:
671 #endif
672 if (!fstat(fd, &sb) && (S_IFCHR & sb.st_mode)) {
673 #ifdef DIOCGMEDIASIZE
674 if (ioctl(fd, DIOCGMEDIASIZE, (off_t *)&size))
675 #elif defined(DIOCGPART)
677 struct partinfo pi;
678 if (ioctl(fd, DIOCGPART, &pi) == 0)
679 size = pi.media_size;
680 else
681 size = 0;
683 if (size == 0)
684 #endif
685 #ifdef CONFIG_COCOA
686 size = LONG_LONG_MAX;
687 #else
688 size = lseek(fd, 0LL, SEEK_END);
689 #endif
690 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
691 switch(s->type) {
692 case FTYPE_CD:
693 /* XXX FreeBSD acd returns UINT_MAX sectors for an empty drive */
694 if (size == 2048LL * (unsigned)-1)
695 size = 0;
696 /* XXX no disc? maybe we need to reopen... */
697 if (size <= 0 && !reopened && cdrom_reopen(bs) >= 0) {
698 reopened = 1;
699 goto again;
702 #endif
703 } else {
704 size = lseek(fd, 0, SEEK_END);
706 return size;
708 #else
709 static int64_t raw_getlength(BlockDriverState *bs)
711 BDRVRawState *s = bs->opaque;
712 int ret;
714 ret = fd_open(bs);
715 if (ret < 0) {
716 return ret;
719 return lseek(s->fd, 0, SEEK_END);
721 #endif
723 static int raw_create(const char *filename, QEMUOptionParameter *options)
725 int fd;
726 int result = 0;
727 int64_t total_size = 0;
729 /* Read out options */
730 while (options && options->name) {
731 if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
732 total_size = options->value.n / BDRV_SECTOR_SIZE;
734 options++;
737 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
738 0644);
739 if (fd < 0) {
740 result = -errno;
741 } else {
742 if (ftruncate(fd, total_size * BDRV_SECTOR_SIZE) != 0) {
743 result = -errno;
745 if (close(fd) != 0) {
746 result = -errno;
749 return result;
752 static int raw_flush(BlockDriverState *bs)
754 BDRVRawState *s = bs->opaque;
755 return qemu_fdatasync(s->fd);
758 #ifdef CONFIG_XFS
759 static int xfs_discard(BDRVRawState *s, int64_t sector_num, int nb_sectors)
761 struct xfs_flock64 fl;
763 memset(&fl, 0, sizeof(fl));
764 fl.l_whence = SEEK_SET;
765 fl.l_start = sector_num << 9;
766 fl.l_len = (int64_t)nb_sectors << 9;
768 if (xfsctl(NULL, s->fd, XFS_IOC_UNRESVSP64, &fl) < 0) {
769 DEBUG_BLOCK_PRINT("cannot punch hole (%s)\n", strerror(errno));
770 return -errno;
773 return 0;
775 #endif
777 static int raw_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors)
779 #ifdef CONFIG_XFS
780 BDRVRawState *s = bs->opaque;
782 if (s->is_xfs) {
783 return xfs_discard(s, sector_num, nb_sectors);
785 #endif
787 return 0;
790 static QEMUOptionParameter raw_create_options[] = {
792 .name = BLOCK_OPT_SIZE,
793 .type = OPT_SIZE,
794 .help = "Virtual disk size"
796 { NULL }
799 static BlockDriver bdrv_file = {
800 .format_name = "file",
801 .protocol_name = "file",
802 .instance_size = sizeof(BDRVRawState),
803 .bdrv_probe = NULL, /* no probe for protocols */
804 .bdrv_file_open = raw_open,
805 .bdrv_read = raw_read,
806 .bdrv_write = raw_write,
807 .bdrv_close = raw_close,
808 .bdrv_create = raw_create,
809 .bdrv_flush = raw_flush,
810 .bdrv_discard = raw_discard,
812 .bdrv_aio_readv = raw_aio_readv,
813 .bdrv_aio_writev = raw_aio_writev,
814 .bdrv_aio_flush = raw_aio_flush,
816 .bdrv_truncate = raw_truncate,
817 .bdrv_getlength = raw_getlength,
819 .create_options = raw_create_options,
822 /***********************************************/
823 /* host device */
825 #ifdef CONFIG_COCOA
826 static kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator );
827 static kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex maxPathSize );
829 kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator )
831 kern_return_t kernResult;
832 mach_port_t masterPort;
833 CFMutableDictionaryRef classesToMatch;
835 kernResult = IOMasterPort( MACH_PORT_NULL, &masterPort );
836 if ( KERN_SUCCESS != kernResult ) {
837 printf( "IOMasterPort returned %d\n", kernResult );
840 classesToMatch = IOServiceMatching( kIOCDMediaClass );
841 if ( classesToMatch == NULL ) {
842 printf( "IOServiceMatching returned a NULL dictionary.\n" );
843 } else {
844 CFDictionarySetValue( classesToMatch, CFSTR( kIOMediaEjectableKey ), kCFBooleanTrue );
846 kernResult = IOServiceGetMatchingServices( masterPort, classesToMatch, mediaIterator );
847 if ( KERN_SUCCESS != kernResult )
849 printf( "IOServiceGetMatchingServices returned %d\n", kernResult );
852 return kernResult;
855 kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex maxPathSize )
857 io_object_t nextMedia;
858 kern_return_t kernResult = KERN_FAILURE;
859 *bsdPath = '\0';
860 nextMedia = IOIteratorNext( mediaIterator );
861 if ( nextMedia )
863 CFTypeRef bsdPathAsCFString;
864 bsdPathAsCFString = IORegistryEntryCreateCFProperty( nextMedia, CFSTR( kIOBSDNameKey ), kCFAllocatorDefault, 0 );
865 if ( bsdPathAsCFString ) {
866 size_t devPathLength;
867 strcpy( bsdPath, _PATH_DEV );
868 strcat( bsdPath, "r" );
869 devPathLength = strlen( bsdPath );
870 if ( CFStringGetCString( bsdPathAsCFString, bsdPath + devPathLength, maxPathSize - devPathLength, kCFStringEncodingASCII ) ) {
871 kernResult = KERN_SUCCESS;
873 CFRelease( bsdPathAsCFString );
875 IOObjectRelease( nextMedia );
878 return kernResult;
881 #endif
883 static int hdev_probe_device(const char *filename)
885 struct stat st;
887 /* allow a dedicated CD-ROM driver to match with a higher priority */
888 if (strstart(filename, "/dev/cdrom", NULL))
889 return 50;
891 if (stat(filename, &st) >= 0 &&
892 (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode))) {
893 return 100;
896 return 0;
899 static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
901 BDRVRawState *s = bs->opaque;
903 #ifdef CONFIG_COCOA
904 if (strstart(filename, "/dev/cdrom", NULL)) {
905 kern_return_t kernResult;
906 io_iterator_t mediaIterator;
907 char bsdPath[ MAXPATHLEN ];
908 int fd;
910 kernResult = FindEjectableCDMedia( &mediaIterator );
911 kernResult = GetBSDPath( mediaIterator, bsdPath, sizeof( bsdPath ) );
913 if ( bsdPath[ 0 ] != '\0' ) {
914 strcat(bsdPath,"s0");
915 /* some CDs don't have a partition 0 */
916 fd = open(bsdPath, O_RDONLY | O_BINARY | O_LARGEFILE);
917 if (fd < 0) {
918 bsdPath[strlen(bsdPath)-1] = '1';
919 } else {
920 close(fd);
922 filename = bsdPath;
925 if ( mediaIterator )
926 IOObjectRelease( mediaIterator );
928 #endif
930 s->type = FTYPE_FILE;
931 #if defined(__linux__)
933 char resolved_path[ MAXPATHLEN ], *temp;
935 temp = realpath(filename, resolved_path);
936 if (temp && strstart(temp, "/dev/sg", NULL)) {
937 bs->sg = 1;
940 #endif
942 return raw_open_common(bs, filename, flags, 0);
945 #if defined(__linux__)
946 /* Note: we do not have a reliable method to detect if the floppy is
947 present. The current method is to try to open the floppy at every
948 I/O and to keep it opened during a few hundreds of ms. */
949 static int fd_open(BlockDriverState *bs)
951 BDRVRawState *s = bs->opaque;
952 int last_media_present;
954 if (s->type != FTYPE_FD)
955 return 0;
956 last_media_present = (s->fd >= 0);
957 if (s->fd >= 0 &&
958 (get_clock() - s->fd_open_time) >= FD_OPEN_TIMEOUT) {
959 close(s->fd);
960 s->fd = -1;
961 #ifdef DEBUG_FLOPPY
962 printf("Floppy closed\n");
963 #endif
965 if (s->fd < 0) {
966 if (s->fd_got_error &&
967 (get_clock() - s->fd_error_time) < FD_OPEN_TIMEOUT) {
968 #ifdef DEBUG_FLOPPY
969 printf("No floppy (open delayed)\n");
970 #endif
971 return -EIO;
973 s->fd = open(bs->filename, s->open_flags & ~O_NONBLOCK);
974 if (s->fd < 0) {
975 s->fd_error_time = get_clock();
976 s->fd_got_error = 1;
977 if (last_media_present)
978 s->fd_media_changed = 1;
979 #ifdef DEBUG_FLOPPY
980 printf("No floppy\n");
981 #endif
982 return -EIO;
984 #ifdef DEBUG_FLOPPY
985 printf("Floppy opened\n");
986 #endif
988 if (!last_media_present)
989 s->fd_media_changed = 1;
990 s->fd_open_time = get_clock();
991 s->fd_got_error = 0;
992 return 0;
995 static int hdev_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
997 BDRVRawState *s = bs->opaque;
999 return ioctl(s->fd, req, buf);
1002 static BlockDriverAIOCB *hdev_aio_ioctl(BlockDriverState *bs,
1003 unsigned long int req, void *buf,
1004 BlockDriverCompletionFunc *cb, void *opaque)
1006 BDRVRawState *s = bs->opaque;
1008 if (fd_open(bs) < 0)
1009 return NULL;
1010 return paio_ioctl(bs, s->fd, req, buf, cb, opaque);
1013 #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1014 static int fd_open(BlockDriverState *bs)
1016 BDRVRawState *s = bs->opaque;
1018 /* this is just to ensure s->fd is sane (its called by io ops) */
1019 if (s->fd >= 0)
1020 return 0;
1021 return -EIO;
1023 #else /* !linux && !FreeBSD */
1025 static int fd_open(BlockDriverState *bs)
1027 return 0;
1030 #endif /* !linux && !FreeBSD */
1032 static int hdev_create(const char *filename, QEMUOptionParameter *options)
1034 int fd;
1035 int ret = 0;
1036 struct stat stat_buf;
1037 int64_t total_size = 0;
1039 /* Read out options */
1040 while (options && options->name) {
1041 if (!strcmp(options->name, "size")) {
1042 total_size = options->value.n / BDRV_SECTOR_SIZE;
1044 options++;
1047 fd = open(filename, O_WRONLY | O_BINARY);
1048 if (fd < 0)
1049 return -errno;
1051 if (fstat(fd, &stat_buf) < 0)
1052 ret = -errno;
1053 else if (!S_ISBLK(stat_buf.st_mode) && !S_ISCHR(stat_buf.st_mode))
1054 ret = -ENODEV;
1055 else if (lseek(fd, 0, SEEK_END) < total_size * BDRV_SECTOR_SIZE)
1056 ret = -ENOSPC;
1058 close(fd);
1059 return ret;
1062 static int hdev_has_zero_init(BlockDriverState *bs)
1064 return 0;
1067 static BlockDriver bdrv_host_device = {
1068 .format_name = "host_device",
1069 .protocol_name = "host_device",
1070 .instance_size = sizeof(BDRVRawState),
1071 .bdrv_probe_device = hdev_probe_device,
1072 .bdrv_file_open = hdev_open,
1073 .bdrv_close = raw_close,
1074 .bdrv_create = hdev_create,
1075 .create_options = raw_create_options,
1076 .bdrv_has_zero_init = hdev_has_zero_init,
1077 .bdrv_flush = raw_flush,
1079 .bdrv_aio_readv = raw_aio_readv,
1080 .bdrv_aio_writev = raw_aio_writev,
1081 .bdrv_aio_flush = raw_aio_flush,
1083 .bdrv_read = raw_read,
1084 .bdrv_write = raw_write,
1085 .bdrv_getlength = raw_getlength,
1087 /* generic scsi device */
1088 #ifdef __linux__
1089 .bdrv_ioctl = hdev_ioctl,
1090 .bdrv_aio_ioctl = hdev_aio_ioctl,
1091 #endif
1094 #ifdef __linux__
1095 static int floppy_open(BlockDriverState *bs, const char *filename, int flags)
1097 BDRVRawState *s = bs->opaque;
1098 int ret;
1100 s->type = FTYPE_FD;
1102 /* open will not fail even if no floppy is inserted, so add O_NONBLOCK */
1103 ret = raw_open_common(bs, filename, flags, O_NONBLOCK);
1104 if (ret)
1105 return ret;
1107 /* close fd so that we can reopen it as needed */
1108 close(s->fd);
1109 s->fd = -1;
1110 s->fd_media_changed = 1;
1112 return 0;
1115 static int floppy_probe_device(const char *filename)
1117 int fd, ret;
1118 int prio = 0;
1119 struct floppy_struct fdparam;
1121 if (strstart(filename, "/dev/fd", NULL))
1122 prio = 50;
1124 fd = open(filename, O_RDONLY | O_NONBLOCK);
1125 if (fd < 0) {
1126 goto out;
1129 /* Attempt to detect via a floppy specific ioctl */
1130 ret = ioctl(fd, FDGETPRM, &fdparam);
1131 if (ret >= 0)
1132 prio = 100;
1134 close(fd);
1135 out:
1136 return prio;
1140 static int floppy_is_inserted(BlockDriverState *bs)
1142 return fd_open(bs) >= 0;
1145 static int floppy_media_changed(BlockDriverState *bs)
1147 BDRVRawState *s = bs->opaque;
1148 int ret;
1151 * XXX: we do not have a true media changed indication.
1152 * It does not work if the floppy is changed without trying to read it.
1154 fd_open(bs);
1155 ret = s->fd_media_changed;
1156 s->fd_media_changed = 0;
1157 #ifdef DEBUG_FLOPPY
1158 printf("Floppy changed=%d\n", ret);
1159 #endif
1160 return ret;
1163 static int floppy_eject(BlockDriverState *bs, int eject_flag)
1165 BDRVRawState *s = bs->opaque;
1166 int fd;
1168 if (s->fd >= 0) {
1169 close(s->fd);
1170 s->fd = -1;
1172 fd = open(bs->filename, s->open_flags | O_NONBLOCK);
1173 if (fd >= 0) {
1174 if (ioctl(fd, FDEJECT, 0) < 0)
1175 perror("FDEJECT");
1176 close(fd);
1179 return 0;
1182 static BlockDriver bdrv_host_floppy = {
1183 .format_name = "host_floppy",
1184 .protocol_name = "host_floppy",
1185 .instance_size = sizeof(BDRVRawState),
1186 .bdrv_probe_device = floppy_probe_device,
1187 .bdrv_file_open = floppy_open,
1188 .bdrv_close = raw_close,
1189 .bdrv_create = hdev_create,
1190 .create_options = raw_create_options,
1191 .bdrv_has_zero_init = hdev_has_zero_init,
1192 .bdrv_flush = raw_flush,
1194 .bdrv_aio_readv = raw_aio_readv,
1195 .bdrv_aio_writev = raw_aio_writev,
1196 .bdrv_aio_flush = raw_aio_flush,
1198 .bdrv_read = raw_read,
1199 .bdrv_write = raw_write,
1200 .bdrv_getlength = raw_getlength,
1202 /* removable device support */
1203 .bdrv_is_inserted = floppy_is_inserted,
1204 .bdrv_media_changed = floppy_media_changed,
1205 .bdrv_eject = floppy_eject,
1208 static int cdrom_open(BlockDriverState *bs, const char *filename, int flags)
1210 BDRVRawState *s = bs->opaque;
1212 s->type = FTYPE_CD;
1214 /* open will not fail even if no CD is inserted, so add O_NONBLOCK */
1215 return raw_open_common(bs, filename, flags, O_NONBLOCK);
1218 static int cdrom_probe_device(const char *filename)
1220 int fd, ret;
1221 int prio = 0;
1223 fd = open(filename, O_RDONLY | O_NONBLOCK);
1224 if (fd < 0) {
1225 goto out;
1228 /* Attempt to detect via a CDROM specific ioctl */
1229 ret = ioctl(fd, CDROM_DRIVE_STATUS, CDSL_CURRENT);
1230 if (ret >= 0)
1231 prio = 100;
1233 close(fd);
1234 out:
1235 return prio;
1238 static int cdrom_is_inserted(BlockDriverState *bs)
1240 BDRVRawState *s = bs->opaque;
1241 int ret;
1243 ret = ioctl(s->fd, CDROM_DRIVE_STATUS, CDSL_CURRENT);
1244 if (ret == CDS_DISC_OK)
1245 return 1;
1246 return 0;
1249 static int cdrom_eject(BlockDriverState *bs, int eject_flag)
1251 BDRVRawState *s = bs->opaque;
1253 if (eject_flag) {
1254 if (ioctl(s->fd, CDROMEJECT, NULL) < 0)
1255 perror("CDROMEJECT");
1256 } else {
1257 if (ioctl(s->fd, CDROMCLOSETRAY, NULL) < 0)
1258 perror("CDROMEJECT");
1261 return 0;
1264 static int cdrom_set_locked(BlockDriverState *bs, int locked)
1266 BDRVRawState *s = bs->opaque;
1268 if (ioctl(s->fd, CDROM_LOCKDOOR, locked) < 0) {
1270 * Note: an error can happen if the distribution automatically
1271 * mounts the CD-ROM
1273 /* perror("CDROM_LOCKDOOR"); */
1276 return 0;
1279 static BlockDriver bdrv_host_cdrom = {
1280 .format_name = "host_cdrom",
1281 .protocol_name = "host_cdrom",
1282 .instance_size = sizeof(BDRVRawState),
1283 .bdrv_probe_device = cdrom_probe_device,
1284 .bdrv_file_open = cdrom_open,
1285 .bdrv_close = raw_close,
1286 .bdrv_create = hdev_create,
1287 .create_options = raw_create_options,
1288 .bdrv_has_zero_init = hdev_has_zero_init,
1289 .bdrv_flush = raw_flush,
1291 .bdrv_aio_readv = raw_aio_readv,
1292 .bdrv_aio_writev = raw_aio_writev,
1293 .bdrv_aio_flush = raw_aio_flush,
1295 .bdrv_read = raw_read,
1296 .bdrv_write = raw_write,
1297 .bdrv_getlength = raw_getlength,
1299 /* removable device support */
1300 .bdrv_is_inserted = cdrom_is_inserted,
1301 .bdrv_eject = cdrom_eject,
1302 .bdrv_set_locked = cdrom_set_locked,
1304 /* generic scsi device */
1305 .bdrv_ioctl = hdev_ioctl,
1306 .bdrv_aio_ioctl = hdev_aio_ioctl,
1308 #endif /* __linux__ */
1310 #if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
1311 static int cdrom_open(BlockDriverState *bs, const char *filename, int flags)
1313 BDRVRawState *s = bs->opaque;
1314 int ret;
1316 s->type = FTYPE_CD;
1318 ret = raw_open_common(bs, filename, flags, 0);
1319 if (ret)
1320 return ret;
1322 /* make sure the door isnt locked at this time */
1323 ioctl(s->fd, CDIOCALLOW);
1324 return 0;
1327 static int cdrom_probe_device(const char *filename)
1329 if (strstart(filename, "/dev/cd", NULL) ||
1330 strstart(filename, "/dev/acd", NULL))
1331 return 100;
1332 return 0;
1335 static int cdrom_reopen(BlockDriverState *bs)
1337 BDRVRawState *s = bs->opaque;
1338 int fd;
1341 * Force reread of possibly changed/newly loaded disc,
1342 * FreeBSD seems to not notice sometimes...
1344 if (s->fd >= 0)
1345 close(s->fd);
1346 fd = open(bs->filename, s->open_flags, 0644);
1347 if (fd < 0) {
1348 s->fd = -1;
1349 return -EIO;
1351 s->fd = fd;
1353 /* make sure the door isnt locked at this time */
1354 ioctl(s->fd, CDIOCALLOW);
1355 return 0;
1358 static int cdrom_is_inserted(BlockDriverState *bs)
1360 return raw_getlength(bs) > 0;
1363 static int cdrom_eject(BlockDriverState *bs, int eject_flag)
1365 BDRVRawState *s = bs->opaque;
1367 if (s->fd < 0)
1368 return -ENOTSUP;
1370 (void) ioctl(s->fd, CDIOCALLOW);
1372 if (eject_flag) {
1373 if (ioctl(s->fd, CDIOCEJECT) < 0)
1374 perror("CDIOCEJECT");
1375 } else {
1376 if (ioctl(s->fd, CDIOCCLOSE) < 0)
1377 perror("CDIOCCLOSE");
1380 if (cdrom_reopen(bs) < 0)
1381 return -ENOTSUP;
1382 return 0;
1385 static int cdrom_set_locked(BlockDriverState *bs, int locked)
1387 BDRVRawState *s = bs->opaque;
1389 if (s->fd < 0)
1390 return -ENOTSUP;
1391 if (ioctl(s->fd, (locked ? CDIOCPREVENT : CDIOCALLOW)) < 0) {
1393 * Note: an error can happen if the distribution automatically
1394 * mounts the CD-ROM
1396 /* perror("CDROM_LOCKDOOR"); */
1399 return 0;
1402 static BlockDriver bdrv_host_cdrom = {
1403 .format_name = "host_cdrom",
1404 .protocol_name = "host_cdrom",
1405 .instance_size = sizeof(BDRVRawState),
1406 .bdrv_probe_device = cdrom_probe_device,
1407 .bdrv_file_open = cdrom_open,
1408 .bdrv_close = raw_close,
1409 .bdrv_create = hdev_create,
1410 .create_options = raw_create_options,
1411 .bdrv_has_zero_init = hdev_has_zero_init,
1412 .bdrv_flush = raw_flush,
1414 .bdrv_aio_readv = raw_aio_readv,
1415 .bdrv_aio_writev = raw_aio_writev,
1416 .bdrv_aio_flush = raw_aio_flush,
1418 .bdrv_read = raw_read,
1419 .bdrv_write = raw_write,
1420 .bdrv_getlength = raw_getlength,
1422 /* removable device support */
1423 .bdrv_is_inserted = cdrom_is_inserted,
1424 .bdrv_eject = cdrom_eject,
1425 .bdrv_set_locked = cdrom_set_locked,
1427 #endif /* __FreeBSD__ */
1429 static void bdrv_file_init(void)
1432 * Register all the drivers. Note that order is important, the driver
1433 * registered last will get probed first.
1435 bdrv_register(&bdrv_file);
1436 bdrv_register(&bdrv_host_device);
1437 #ifdef __linux__
1438 bdrv_register(&bdrv_host_floppy);
1439 bdrv_register(&bdrv_host_cdrom);
1440 #endif
1441 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1442 bdrv_register(&bdrv_host_cdrom);
1443 #endif
1446 block_init(bdrv_file_init);