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
24 #include "qemu-common.h"
25 #include "qemu-timer.h"
26 #include "qemu-char.h"
28 #include "block_int.h"
30 #include "block/raw-posix-aio.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>
45 #define _POSIX_PTHREAD_SEMANTICS 1
49 #include <sys/types.h>
51 #include <sys/ioctl.h>
52 #include <sys/param.h>
53 #include <linux/cdrom.h>
56 #if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
62 #include <sys/ioctl.h>
63 #include <sys/disklabel.h>
68 #include <sys/ioctl.h>
69 #include <sys/disklabel.h>
75 #include <sys/ioctl.h>
76 #include <sys/diskslice.h>
83 #include "block/add-cow.h"
85 //#define DEBUG_FLOPPY
88 #if defined(DEBUG_BLOCK)
89 #define DEBUG_BLOCK_PRINT(formatCstr, ...) do { if (qemu_log_enabled()) \
90 { qemu_log(formatCstr, ## __VA_ARGS__); qemu_log_flush(); } } while (0)
92 #define DEBUG_BLOCK_PRINT(formatCstr, ...)
95 /* OS X does not have O_DSYNC */
98 #define O_DSYNC O_SYNC
99 #elif defined(O_FSYNC)
100 #define O_DSYNC O_FSYNC
104 /* Approximate O_DIRECT with O_DSYNC if O_DIRECT isn't available */
106 #define O_DIRECT O_DSYNC
113 /* if the FD is not accessed during that time (in ns), we try to
114 reopen it to see if the disk has been changed */
115 #define FD_OPEN_TIMEOUT (1000000000)
117 #define MAX_BLOCKSIZE 4096
119 typedef struct BDRVRawState
{
123 #if defined(__linux__)
124 /* linux floppy specific */
125 int64_t fd_open_time
;
126 int64_t fd_error_time
;
128 int fd_media_changed
;
130 #ifdef CONFIG_LINUX_AIO
134 uint8_t *aligned_buf
;
135 unsigned aligned_buf_size
;
141 static int fd_open(BlockDriverState
*bs
);
142 static int64_t raw_getlength(BlockDriverState
*bs
);
144 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
145 static int cdrom_reopen(BlockDriverState
*bs
);
148 #if defined(__NetBSD__)
149 static int raw_normalize_devicepath(const char **filename
)
151 static char namebuf
[PATH_MAX
];
152 const char *dp
, *fname
;
156 dp
= strrchr(fname
, '/');
157 if (lstat(fname
, &sb
) < 0) {
158 fprintf(stderr
, "%s: stat failed: %s\n",
159 fname
, strerror(errno
));
163 if (!S_ISBLK(sb
.st_mode
)) {
168 snprintf(namebuf
, PATH_MAX
, "r%s", fname
);
170 snprintf(namebuf
, PATH_MAX
, "%.*s/r%s",
171 (int)(dp
- fname
), fname
, dp
+ 1);
173 fprintf(stderr
, "%s is a block device", fname
);
175 fprintf(stderr
, ", using %s\n", *filename
);
180 static int raw_normalize_devicepath(const char **filename
)
186 static int raw_open_common(BlockDriverState
*bs
, const char *filename
,
187 int bdrv_flags
, int open_flags
)
189 BDRVRawState
*s
= bs
->opaque
;
192 ret
= raw_normalize_devicepath(&filename
);
197 s
->open_flags
= open_flags
| O_BINARY
;
198 s
->open_flags
&= ~O_ACCMODE
;
199 if (bdrv_flags
& BDRV_O_RDWR
) {
200 s
->open_flags
|= O_RDWR
;
202 s
->open_flags
|= O_RDONLY
;
205 /* Use O_DSYNC for write-through caching, no flags for write-back caching,
206 * and O_DIRECT for no caching. */
207 if ((bdrv_flags
& BDRV_O_NOCACHE
))
208 s
->open_flags
|= O_DIRECT
;
209 if (!(bdrv_flags
& BDRV_O_CACHE_WB
))
210 s
->open_flags
|= O_DSYNC
;
213 fd
= qemu_open(filename
, s
->open_flags
, 0644);
221 s
->aligned_buf
= NULL
;
223 if ((bdrv_flags
& BDRV_O_NOCACHE
)) {
225 * Allocate a buffer for read/modify/write cycles. Chose the size
226 * pessimistically as we don't know the block size yet.
228 s
->aligned_buf_size
= 32 * MAX_BLOCKSIZE
;
229 s
->aligned_buf
= qemu_memalign(MAX_BLOCKSIZE
, s
->aligned_buf_size
);
230 if (s
->aligned_buf
== NULL
) {
235 /* We're falling back to POSIX AIO in some cases so init always */
236 if (paio_init() < 0) {
240 #ifdef CONFIG_LINUX_AIO
241 if ((bdrv_flags
& (BDRV_O_NOCACHE
|BDRV_O_NATIVE_AIO
)) ==
242 (BDRV_O_NOCACHE
|BDRV_O_NATIVE_AIO
)) {
244 s
->aio_ctx
= laio_init();
252 #ifdef CONFIG_LINUX_AIO
258 if (platform_test_xfs_fd(s
->fd
)) {
266 qemu_vfree(s
->aligned_buf
);
272 static int raw_open(BlockDriverState
*bs
, const char *filename
, int flags
)
274 BDRVRawState
*s
= bs
->opaque
;
275 struct add_cow_head cow_header
;
277 if(bs
->cow_file
[0] && (get_add_cow_head(bs
->cow_file
,&cow_header
) <0 )) {
278 DEBUG_BLOCK_PRINT("get_add_cow_head() failed: %d = %s\n",
279 errno
, strerror(errno
));
282 s
->type
= FTYPE_FILE
;
283 return raw_open_common(bs
, filename
, flags
, 0);
286 /* XXX: use host sector size if necessary with:
287 #ifdef DIOCGSECTORSIZE
289 unsigned int sectorsize = 512;
290 if (!ioctl(fd, DIOCGSECTORSIZE, §orsize) &&
291 sectorsize > bufsize)
292 bufsize = sectorsize;
296 uint32_t blockSize = 512;
297 if ( !ioctl( fd, DKIOCGETBLOCKSIZE, &blockSize ) && blockSize > bufsize) {
304 * offset and count are in bytes, but must be multiples of 512 for files
305 * opened with O_DIRECT. buf must be aligned to 512 bytes then.
307 * This function may be called without alignment if the caller ensures
308 * that O_DIRECT is not in effect.
310 static int raw_pread_aligned(BlockDriverState
*bs
, int64_t offset
,
311 uint8_t *buf
, int count
)
313 BDRVRawState
*s
= bs
->opaque
;
320 ret
= pread(s
->fd
, buf
, count
, offset
);
324 /* Allow reads beyond the end (needed for pwrite) */
325 if ((ret
== 0) && bs
->growable
) {
326 int64_t size
= raw_getlength(bs
);
327 if (offset
>= size
) {
328 memset(buf
, 0, count
);
333 DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64
", %p, %d) [%" PRId64
334 "] read failed %d : %d = %s\n",
335 s
->fd
, bs
->filename
, offset
, buf
, count
,
336 bs
->total_sectors
, ret
, errno
, strerror(errno
));
338 /* Try harder for CDrom. */
339 if (s
->type
!= FTYPE_FILE
) {
340 ret
= pread(s
->fd
, buf
, count
, offset
);
343 ret
= pread(s
->fd
, buf
, count
, offset
);
347 DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64
", %p, %d) [%" PRId64
348 "] retry read failed %d : %d = %s\n",
349 s
->fd
, bs
->filename
, offset
, buf
, count
,
350 bs
->total_sectors
, ret
, errno
, strerror(errno
));
353 return (ret
< 0) ? -errno
: ret
;
357 * offset and count are in bytes, but must be multiples of the sector size
358 * for files opened with O_DIRECT. buf must be aligned to sector size bytes
361 * This function may be called without alignment if the caller ensures
362 * that O_DIRECT is not in effect.
364 static int raw_pwrite_aligned(BlockDriverState
*bs
, int64_t offset
,
365 const uint8_t *buf
, int count
)
367 BDRVRawState
*s
= bs
->opaque
;
374 ret
= pwrite(s
->fd
, buf
, count
, offset
);
378 DEBUG_BLOCK_PRINT("raw_pwrite(%d:%s, %" PRId64
", %p, %d) [%" PRId64
379 "] write failed %d : %d = %s\n",
380 s
->fd
, bs
->filename
, offset
, buf
, count
,
381 bs
->total_sectors
, ret
, errno
, strerror(errno
));
383 return (ret
< 0) ? -errno
: ret
;
388 * offset and count are in bytes and possibly not aligned. For files opened
389 * with O_DIRECT, necessary alignments are ensured before calling
390 * raw_pread_aligned to do the actual read.
392 static int raw_pread(BlockDriverState
*bs
, int64_t offset
,
393 uint8_t *buf
, int count
)
395 BDRVRawState
*s
= bs
->opaque
;
396 unsigned sector_mask
= bs
->buffer_alignment
- 1;
397 int size
, ret
, shift
, sum
;
401 if (s
->aligned_buf
!= NULL
) {
403 if (offset
& sector_mask
) {
404 /* align offset on a sector size bytes boundary */
406 shift
= offset
& sector_mask
;
407 size
= (shift
+ count
+ sector_mask
) & ~sector_mask
;
408 if (size
> s
->aligned_buf_size
)
409 size
= s
->aligned_buf_size
;
410 ret
= raw_pread_aligned(bs
, offset
- shift
, s
->aligned_buf
, size
);
414 size
= bs
->buffer_alignment
- shift
;
417 memcpy(buf
, s
->aligned_buf
+ shift
, size
);
427 if (count
& sector_mask
|| (uintptr_t) buf
& sector_mask
) {
429 /* read on aligned buffer */
433 size
= (count
+ sector_mask
) & ~sector_mask
;
434 if (size
> s
->aligned_buf_size
)
435 size
= s
->aligned_buf_size
;
437 ret
= raw_pread_aligned(bs
, offset
, s
->aligned_buf
, size
);
440 } else if (ret
== 0) {
441 fprintf(stderr
, "raw_pread: read beyond end of file\n");
449 memcpy(buf
, s
->aligned_buf
, size
);
461 return raw_pread_aligned(bs
, offset
, buf
, count
) + sum
;
464 static int raw_read(BlockDriverState
*bs
, int64_t sector_num
,
465 uint8_t *buf
, int nb_sectors
)
469 ret
= raw_pread(bs
, sector_num
* BDRV_SECTOR_SIZE
, buf
,
470 nb_sectors
* BDRV_SECTOR_SIZE
);
471 if (ret
== (nb_sectors
* BDRV_SECTOR_SIZE
))
477 * offset and count are in bytes and possibly not aligned. For files opened
478 * with O_DIRECT, necessary alignments are ensured before calling
479 * raw_pwrite_aligned to do the actual write.
481 static int raw_pwrite(BlockDriverState
*bs
, int64_t offset
,
482 const uint8_t *buf
, int count
)
484 BDRVRawState
*s
= bs
->opaque
;
485 unsigned sector_mask
= bs
->buffer_alignment
- 1;
486 int size
, ret
, shift
, sum
;
490 if (s
->aligned_buf
!= NULL
) {
492 if (offset
& sector_mask
) {
493 /* align offset on a sector size bytes boundary */
494 shift
= offset
& sector_mask
;
495 ret
= raw_pread_aligned(bs
, offset
- shift
, s
->aligned_buf
,
496 bs
->buffer_alignment
);
500 size
= bs
->buffer_alignment
- shift
;
503 memcpy(s
->aligned_buf
+ shift
, buf
, size
);
505 ret
= raw_pwrite_aligned(bs
, offset
- shift
, s
->aligned_buf
,
506 bs
->buffer_alignment
);
518 if (count
& sector_mask
|| (uintptr_t) buf
& sector_mask
) {
520 while ((size
= (count
& ~sector_mask
)) != 0) {
522 if (size
> s
->aligned_buf_size
)
523 size
= s
->aligned_buf_size
;
525 memcpy(s
->aligned_buf
, buf
, size
);
527 ret
= raw_pwrite_aligned(bs
, offset
, s
->aligned_buf
, size
);
536 /* here, count < sector_size because (count & ~sector_mask) == 0 */
538 ret
= raw_pread_aligned(bs
, offset
, s
->aligned_buf
,
539 bs
->buffer_alignment
);
542 memcpy(s
->aligned_buf
, buf
, count
);
544 ret
= raw_pwrite_aligned(bs
, offset
, s
->aligned_buf
,
545 bs
->buffer_alignment
);
556 return raw_pwrite_aligned(bs
, offset
, buf
, count
) + sum
;
559 static int raw_write(BlockDriverState
*bs
, int64_t sector_num
,
560 const uint8_t *buf
, int nb_sectors
)
563 ret
= raw_pwrite(bs
, sector_num
* BDRV_SECTOR_SIZE
, buf
,
564 nb_sectors
* BDRV_SECTOR_SIZE
);
565 if (ret
== (nb_sectors
* BDRV_SECTOR_SIZE
))
571 * Check if all memory in this vector is sector aligned.
573 static int qiov_is_aligned(BlockDriverState
*bs
, QEMUIOVector
*qiov
)
577 for (i
= 0; i
< qiov
->niov
; i
++) {
578 if ((uintptr_t) qiov
->iov
[i
].iov_base
% bs
->buffer_alignment
) {
586 static BlockDriverAIOCB
*raw_aio_submit(BlockDriverState
*bs
,
587 int64_t sector_num
, QEMUIOVector
*qiov
, int nb_sectors
,
588 BlockDriverCompletionFunc
*cb
, void *opaque
, int type
)
590 BDRVRawState
*s
= bs
->opaque
;
596 * If O_DIRECT is used the buffer needs to be aligned on a sector
597 * boundary. Check if this is the case or tell the low-level
598 * driver that it needs to copy the buffer.
600 if (s
->aligned_buf
) {
601 if (!qiov_is_aligned(bs
, qiov
)) {
602 type
|= QEMU_AIO_MISALIGNED
;
603 #ifdef CONFIG_LINUX_AIO
604 } else if (s
->use_aio
) {
605 return laio_submit(bs
, s
->aio_ctx
, s
->fd
, sector_num
, qiov
,
606 nb_sectors
, cb
, opaque
, type
);
611 return paio_submit(bs
, s
->fd
, sector_num
, qiov
, nb_sectors
,
615 static BlockDriverAIOCB
*raw_aio_readv(BlockDriverState
*bs
,
616 int64_t sector_num
, QEMUIOVector
*qiov
, int nb_sectors
,
617 BlockDriverCompletionFunc
*cb
, void *opaque
)
619 return raw_aio_submit(bs
, sector_num
, qiov
, nb_sectors
,
620 cb
, opaque
, QEMU_AIO_READ
);
623 static BlockDriverAIOCB
*raw_aio_writev(BlockDriverState
*bs
,
624 int64_t sector_num
, QEMUIOVector
*qiov
, int nb_sectors
,
625 BlockDriverCompletionFunc
*cb
, void *opaque
)
627 return raw_aio_submit(bs
, sector_num
, qiov
, nb_sectors
,
628 cb
, opaque
, QEMU_AIO_WRITE
);
631 static BlockDriverAIOCB
*raw_aio_flush(BlockDriverState
*bs
,
632 BlockDriverCompletionFunc
*cb
, void *opaque
)
634 BDRVRawState
*s
= bs
->opaque
;
639 return paio_submit(bs
, s
->fd
, 0, NULL
, 0, cb
, opaque
, QEMU_AIO_FLUSH
);
642 static void raw_close(BlockDriverState
*bs
)
644 BDRVRawState
*s
= bs
->opaque
;
648 if (s
->aligned_buf
!= NULL
)
649 qemu_vfree(s
->aligned_buf
);
653 static int raw_truncate(BlockDriverState
*bs
, int64_t offset
)
655 BDRVRawState
*s
= bs
->opaque
;
656 if (s
->type
!= FTYPE_FILE
)
658 if (ftruncate(s
->fd
, offset
) < 0)
664 static int64_t raw_getlength(BlockDriverState
*bs
)
666 BDRVRawState
*s
= bs
->opaque
;
672 if (S_ISCHR(st
.st_mode
) || S_ISBLK(st
.st_mode
)) {
675 if (ioctl(fd
, DIOCGDINFO
, &dl
))
677 return (uint64_t)dl
.d_secsize
*
678 dl
.d_partitions
[DISKPART(st
.st_rdev
)].p_size
;
682 #elif defined(__NetBSD__)
683 static int64_t raw_getlength(BlockDriverState
*bs
)
685 BDRVRawState
*s
= bs
->opaque
;
691 if (S_ISCHR(st
.st_mode
) || S_ISBLK(st
.st_mode
)) {
692 struct dkwedge_info dkw
;
694 if (ioctl(fd
, DIOCGWEDGEINFO
, &dkw
) != -1) {
695 return dkw
.dkw_size
* 512;
699 if (ioctl(fd
, DIOCGDINFO
, &dl
))
701 return (uint64_t)dl
.d_secsize
*
702 dl
.d_partitions
[DISKPART(st
.st_rdev
)].p_size
;
707 #elif defined(__sun__)
708 static int64_t raw_getlength(BlockDriverState
*bs
)
710 BDRVRawState
*s
= bs
->opaque
;
711 struct dk_minfo minfo
;
720 * Use the DKIOCGMEDIAINFO ioctl to read the size.
722 ret
= ioctl(s
->fd
, DKIOCGMEDIAINFO
, &minfo
);
724 return minfo
.dki_lbsize
* minfo
.dki_capacity
;
728 * There are reports that lseek on some devices fails, but
729 * irc discussion said that contingency on contingency was overkill.
731 return lseek(s
->fd
, 0, SEEK_END
);
733 #elif defined(CONFIG_BSD)
734 static int64_t raw_getlength(BlockDriverState
*bs
)
736 BDRVRawState
*s
= bs
->opaque
;
740 #if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
749 #if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
752 if (!fstat(fd
, &sb
) && (S_IFCHR
& sb
.st_mode
)) {
753 #ifdef DIOCGMEDIASIZE
754 if (ioctl(fd
, DIOCGMEDIASIZE
, (off_t
*)&size
))
755 #elif defined(DIOCGPART)
758 if (ioctl(fd
, DIOCGPART
, &pi
) == 0)
759 size
= pi
.media_size
;
766 size
= LONG_LONG_MAX
;
768 size
= lseek(fd
, 0LL, SEEK_END
);
770 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
773 /* XXX FreeBSD acd returns UINT_MAX sectors for an empty drive */
774 if (size
== 2048LL * (unsigned)-1)
776 /* XXX no disc? maybe we need to reopen... */
777 if (size
<= 0 && !reopened
&& cdrom_reopen(bs
) >= 0) {
784 size
= lseek(fd
, 0, SEEK_END
);
789 static int64_t raw_getlength(BlockDriverState
*bs
)
791 BDRVRawState
*s
= bs
->opaque
;
799 return lseek(s
->fd
, 0, SEEK_END
);
803 static int64_t raw_get_allocated_file_size(BlockDriverState
*bs
)
806 BDRVRawState
*s
= bs
->opaque
;
808 if (fstat(s
->fd
, &st
) < 0) {
811 return (int64_t)st
.st_blocks
* 512;
814 static int raw_create(const char *filename
, QEMUOptionParameter
*options
)
818 int64_t total_size
= 0;
819 char *backing_file
= NULL
;
820 char *backing_fmt
= NULL
;
821 char *cow_file
= NULL
;
823 /* Read out options */
824 while (options
&& options
->name
) {
825 if (!strcmp(options
->name
, BLOCK_OPT_SIZE
)) {
826 total_size
= options
->value
.n
/ BDRV_SECTOR_SIZE
;
828 else if(!strcmp(options
->name
, BLOCK_OPT_BACKING_FILE
)) {
829 backing_file
= options
->value
.s
;
831 else if(!strcmp(options
->name
, BLOCK_OPT_BACKING_FMT
)) {
832 backing_fmt
= options
->value
.s
;
834 else if(!strcmp(options
->name
, BLOCK_OPT_COW_FILE
)) {
835 cow_file
= options
->value
.s
;
841 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
| O_BINARY
,
846 if (ftruncate(fd
, total_size
* BDRV_SECTOR_SIZE
) != 0) {
849 if (close(fd
) != 0) {
854 create_cow_file(backing_file
,backing_fmt
,cow_file
,total_size
);
858 static int raw_flush(BlockDriverState
*bs
)
860 BDRVRawState
*s
= bs
->opaque
;
861 return qemu_fdatasync(s
->fd
);
865 static int xfs_discard(BDRVRawState
*s
, int64_t sector_num
, int nb_sectors
)
867 struct xfs_flock64 fl
;
869 memset(&fl
, 0, sizeof(fl
));
870 fl
.l_whence
= SEEK_SET
;
871 fl
.l_start
= sector_num
<< 9;
872 fl
.l_len
= (int64_t)nb_sectors
<< 9;
874 if (xfsctl(NULL
, s
->fd
, XFS_IOC_UNRESVSP64
, &fl
) < 0) {
875 DEBUG_BLOCK_PRINT("cannot punch hole (%s)\n", strerror(errno
));
883 static int raw_discard(BlockDriverState
*bs
, int64_t sector_num
, int nb_sectors
)
886 BDRVRawState
*s
= bs
->opaque
;
889 return xfs_discard(s
, sector_num
, nb_sectors
);
896 static QEMUOptionParameter raw_create_options
[] = {
898 .name
= BLOCK_OPT_SIZE
,
900 .help
= "Virtual disk size"
905 static BlockDriver bdrv_file
= {
906 .format_name
= "file",
907 .protocol_name
= "file",
908 .instance_size
= sizeof(BDRVRawState
),
909 .bdrv_probe
= NULL
, /* no probe for protocols */
910 .bdrv_file_open
= raw_open
,
911 .bdrv_read
= raw_read
,
912 .bdrv_write
= raw_write
,
913 .bdrv_close
= raw_close
,
914 .bdrv_create
= raw_create
,
915 .bdrv_flush
= raw_flush
,
916 .bdrv_discard
= raw_discard
,
918 .bdrv_aio_readv
= raw_aio_readv
,
919 .bdrv_aio_writev
= raw_aio_writev
,
920 .bdrv_aio_flush
= raw_aio_flush
,
922 .bdrv_truncate
= raw_truncate
,
923 .bdrv_getlength
= raw_getlength
,
924 .bdrv_get_allocated_file_size
925 = raw_get_allocated_file_size
,
927 .create_options
= raw_create_options
,
930 /***********************************************/
934 static kern_return_t
FindEjectableCDMedia( io_iterator_t
*mediaIterator
);
935 static kern_return_t
GetBSDPath( io_iterator_t mediaIterator
, char *bsdPath
, CFIndex maxPathSize
);
937 kern_return_t
FindEjectableCDMedia( io_iterator_t
*mediaIterator
)
939 kern_return_t kernResult
;
940 mach_port_t masterPort
;
941 CFMutableDictionaryRef classesToMatch
;
943 kernResult
= IOMasterPort( MACH_PORT_NULL
, &masterPort
);
944 if ( KERN_SUCCESS
!= kernResult
) {
945 printf( "IOMasterPort returned %d\n", kernResult
);
948 classesToMatch
= IOServiceMatching( kIOCDMediaClass
);
949 if ( classesToMatch
== NULL
) {
950 printf( "IOServiceMatching returned a NULL dictionary.\n" );
952 CFDictionarySetValue( classesToMatch
, CFSTR( kIOMediaEjectableKey
), kCFBooleanTrue
);
954 kernResult
= IOServiceGetMatchingServices( masterPort
, classesToMatch
, mediaIterator
);
955 if ( KERN_SUCCESS
!= kernResult
)
957 printf( "IOServiceGetMatchingServices returned %d\n", kernResult
);
963 kern_return_t
GetBSDPath( io_iterator_t mediaIterator
, char *bsdPath
, CFIndex maxPathSize
)
965 io_object_t nextMedia
;
966 kern_return_t kernResult
= KERN_FAILURE
;
968 nextMedia
= IOIteratorNext( mediaIterator
);
971 CFTypeRef bsdPathAsCFString
;
972 bsdPathAsCFString
= IORegistryEntryCreateCFProperty( nextMedia
, CFSTR( kIOBSDNameKey
), kCFAllocatorDefault
, 0 );
973 if ( bsdPathAsCFString
) {
974 size_t devPathLength
;
975 strcpy( bsdPath
, _PATH_DEV
);
976 strcat( bsdPath
, "r" );
977 devPathLength
= strlen( bsdPath
);
978 if ( CFStringGetCString( bsdPathAsCFString
, bsdPath
+ devPathLength
, maxPathSize
- devPathLength
, kCFStringEncodingASCII
) ) {
979 kernResult
= KERN_SUCCESS
;
981 CFRelease( bsdPathAsCFString
);
983 IOObjectRelease( nextMedia
);
991 static int hdev_probe_device(const char *filename
)
995 /* allow a dedicated CD-ROM driver to match with a higher priority */
996 if (strstart(filename
, "/dev/cdrom", NULL
))
999 if (stat(filename
, &st
) >= 0 &&
1000 (S_ISCHR(st
.st_mode
) || S_ISBLK(st
.st_mode
))) {
1007 static int hdev_open(BlockDriverState
*bs
, const char *filename
, int flags
)
1009 BDRVRawState
*s
= bs
->opaque
;
1012 if (strstart(filename
, "/dev/cdrom", NULL
)) {
1013 kern_return_t kernResult
;
1014 io_iterator_t mediaIterator
;
1015 char bsdPath
[ MAXPATHLEN
];
1018 kernResult
= FindEjectableCDMedia( &mediaIterator
);
1019 kernResult
= GetBSDPath( mediaIterator
, bsdPath
, sizeof( bsdPath
) );
1021 if ( bsdPath
[ 0 ] != '\0' ) {
1022 strcat(bsdPath
,"s0");
1023 /* some CDs don't have a partition 0 */
1024 fd
= open(bsdPath
, O_RDONLY
| O_BINARY
| O_LARGEFILE
);
1026 bsdPath
[strlen(bsdPath
)-1] = '1';
1033 if ( mediaIterator
)
1034 IOObjectRelease( mediaIterator
);
1038 s
->type
= FTYPE_FILE
;
1039 #if defined(__linux__)
1041 char resolved_path
[ MAXPATHLEN
], *temp
;
1043 temp
= realpath(filename
, resolved_path
);
1044 if (temp
&& strstart(temp
, "/dev/sg", NULL
)) {
1050 return raw_open_common(bs
, filename
, flags
, 0);
1053 #if defined(__linux__)
1054 /* Note: we do not have a reliable method to detect if the floppy is
1055 present. The current method is to try to open the floppy at every
1056 I/O and to keep it opened during a few hundreds of ms. */
1057 static int fd_open(BlockDriverState
*bs
)
1059 BDRVRawState
*s
= bs
->opaque
;
1060 int last_media_present
;
1062 if (s
->type
!= FTYPE_FD
)
1064 last_media_present
= (s
->fd
>= 0);
1066 (get_clock() - s
->fd_open_time
) >= FD_OPEN_TIMEOUT
) {
1070 printf("Floppy closed\n");
1074 if (s
->fd_got_error
&&
1075 (get_clock() - s
->fd_error_time
) < FD_OPEN_TIMEOUT
) {
1077 printf("No floppy (open delayed)\n");
1081 s
->fd
= open(bs
->filename
, s
->open_flags
& ~O_NONBLOCK
);
1083 s
->fd_error_time
= get_clock();
1084 s
->fd_got_error
= 1;
1085 if (last_media_present
)
1086 s
->fd_media_changed
= 1;
1088 printf("No floppy\n");
1093 printf("Floppy opened\n");
1096 if (!last_media_present
)
1097 s
->fd_media_changed
= 1;
1098 s
->fd_open_time
= get_clock();
1099 s
->fd_got_error
= 0;
1103 static int hdev_ioctl(BlockDriverState
*bs
, unsigned long int req
, void *buf
)
1105 BDRVRawState
*s
= bs
->opaque
;
1107 return ioctl(s
->fd
, req
, buf
);
1110 static BlockDriverAIOCB
*hdev_aio_ioctl(BlockDriverState
*bs
,
1111 unsigned long int req
, void *buf
,
1112 BlockDriverCompletionFunc
*cb
, void *opaque
)
1114 BDRVRawState
*s
= bs
->opaque
;
1116 if (fd_open(bs
) < 0)
1118 return paio_ioctl(bs
, s
->fd
, req
, buf
, cb
, opaque
);
1121 #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1122 static int fd_open(BlockDriverState
*bs
)
1124 BDRVRawState
*s
= bs
->opaque
;
1126 /* this is just to ensure s->fd is sane (its called by io ops) */
1131 #else /* !linux && !FreeBSD */
1133 static int fd_open(BlockDriverState
*bs
)
1138 #endif /* !linux && !FreeBSD */
1140 static int hdev_create(const char *filename
, QEMUOptionParameter
*options
)
1144 struct stat stat_buf
;
1145 int64_t total_size
= 0;
1147 /* Read out options */
1148 while (options
&& options
->name
) {
1149 if (!strcmp(options
->name
, "size")) {
1150 total_size
= options
->value
.n
/ BDRV_SECTOR_SIZE
;
1155 fd
= open(filename
, O_WRONLY
| O_BINARY
);
1159 if (fstat(fd
, &stat_buf
) < 0)
1161 else if (!S_ISBLK(stat_buf
.st_mode
) && !S_ISCHR(stat_buf
.st_mode
))
1163 else if (lseek(fd
, 0, SEEK_END
) < total_size
* BDRV_SECTOR_SIZE
)
1170 static int hdev_has_zero_init(BlockDriverState
*bs
)
1175 static BlockDriver bdrv_host_device
= {
1176 .format_name
= "host_device",
1177 .protocol_name
= "host_device",
1178 .instance_size
= sizeof(BDRVRawState
),
1179 .bdrv_probe_device
= hdev_probe_device
,
1180 .bdrv_file_open
= hdev_open
,
1181 .bdrv_close
= raw_close
,
1182 .bdrv_create
= hdev_create
,
1183 .create_options
= raw_create_options
,
1184 .bdrv_has_zero_init
= hdev_has_zero_init
,
1185 .bdrv_flush
= raw_flush
,
1187 .bdrv_aio_readv
= raw_aio_readv
,
1188 .bdrv_aio_writev
= raw_aio_writev
,
1189 .bdrv_aio_flush
= raw_aio_flush
,
1191 .bdrv_read
= raw_read
,
1192 .bdrv_write
= raw_write
,
1193 .bdrv_getlength
= raw_getlength
,
1194 .bdrv_get_allocated_file_size
1195 = raw_get_allocated_file_size
,
1197 /* generic scsi device */
1199 .bdrv_ioctl
= hdev_ioctl
,
1200 .bdrv_aio_ioctl
= hdev_aio_ioctl
,
1205 static int floppy_open(BlockDriverState
*bs
, const char *filename
, int flags
)
1207 BDRVRawState
*s
= bs
->opaque
;
1212 /* open will not fail even if no floppy is inserted, so add O_NONBLOCK */
1213 ret
= raw_open_common(bs
, filename
, flags
, O_NONBLOCK
);
1217 /* close fd so that we can reopen it as needed */
1220 s
->fd_media_changed
= 1;
1225 static int floppy_probe_device(const char *filename
)
1229 struct floppy_struct fdparam
;
1232 if (strstart(filename
, "/dev/fd", NULL
))
1235 fd
= open(filename
, O_RDONLY
| O_NONBLOCK
);
1239 ret
= fstat(fd
, &st
);
1240 if (ret
== -1 || !S_ISBLK(st
.st_mode
)) {
1244 /* Attempt to detect via a floppy specific ioctl */
1245 ret
= ioctl(fd
, FDGETPRM
, &fdparam
);
1256 static int floppy_is_inserted(BlockDriverState
*bs
)
1258 return fd_open(bs
) >= 0;
1261 static int floppy_media_changed(BlockDriverState
*bs
)
1263 BDRVRawState
*s
= bs
->opaque
;
1267 * XXX: we do not have a true media changed indication.
1268 * It does not work if the floppy is changed without trying to read it.
1271 ret
= s
->fd_media_changed
;
1272 s
->fd_media_changed
= 0;
1274 printf("Floppy changed=%d\n", ret
);
1279 static void floppy_eject(BlockDriverState
*bs
, int eject_flag
)
1281 BDRVRawState
*s
= bs
->opaque
;
1288 fd
= open(bs
->filename
, s
->open_flags
| O_NONBLOCK
);
1290 if (ioctl(fd
, FDEJECT
, 0) < 0)
1296 static BlockDriver bdrv_host_floppy
= {
1297 .format_name
= "host_floppy",
1298 .protocol_name
= "host_floppy",
1299 .instance_size
= sizeof(BDRVRawState
),
1300 .bdrv_probe_device
= floppy_probe_device
,
1301 .bdrv_file_open
= floppy_open
,
1302 .bdrv_close
= raw_close
,
1303 .bdrv_create
= hdev_create
,
1304 .create_options
= raw_create_options
,
1305 .bdrv_has_zero_init
= hdev_has_zero_init
,
1306 .bdrv_flush
= raw_flush
,
1308 .bdrv_aio_readv
= raw_aio_readv
,
1309 .bdrv_aio_writev
= raw_aio_writev
,
1310 .bdrv_aio_flush
= raw_aio_flush
,
1312 .bdrv_read
= raw_read
,
1313 .bdrv_write
= raw_write
,
1314 .bdrv_getlength
= raw_getlength
,
1315 .bdrv_get_allocated_file_size
1316 = raw_get_allocated_file_size
,
1318 /* removable device support */
1319 .bdrv_is_inserted
= floppy_is_inserted
,
1320 .bdrv_media_changed
= floppy_media_changed
,
1321 .bdrv_eject
= floppy_eject
,
1324 static int cdrom_open(BlockDriverState
*bs
, const char *filename
, int flags
)
1326 BDRVRawState
*s
= bs
->opaque
;
1330 /* open will not fail even if no CD is inserted, so add O_NONBLOCK */
1331 return raw_open_common(bs
, filename
, flags
, O_NONBLOCK
);
1334 static int cdrom_probe_device(const char *filename
)
1340 fd
= open(filename
, O_RDONLY
| O_NONBLOCK
);
1344 ret
= fstat(fd
, &st
);
1345 if (ret
== -1 || !S_ISBLK(st
.st_mode
)) {
1349 /* Attempt to detect via a CDROM specific ioctl */
1350 ret
= ioctl(fd
, CDROM_DRIVE_STATUS
, CDSL_CURRENT
);
1360 static int cdrom_is_inserted(BlockDriverState
*bs
)
1362 BDRVRawState
*s
= bs
->opaque
;
1365 ret
= ioctl(s
->fd
, CDROM_DRIVE_STATUS
, CDSL_CURRENT
);
1366 if (ret
== CDS_DISC_OK
)
1371 static void cdrom_eject(BlockDriverState
*bs
, int eject_flag
)
1373 BDRVRawState
*s
= bs
->opaque
;
1376 if (ioctl(s
->fd
, CDROMEJECT
, NULL
) < 0)
1377 perror("CDROMEJECT");
1379 if (ioctl(s
->fd
, CDROMCLOSETRAY
, NULL
) < 0)
1380 perror("CDROMEJECT");
1384 static void cdrom_set_locked(BlockDriverState
*bs
, int locked
)
1386 BDRVRawState
*s
= bs
->opaque
;
1388 if (ioctl(s
->fd
, CDROM_LOCKDOOR
, locked
) < 0) {
1390 * Note: an error can happen if the distribution automatically
1393 /* perror("CDROM_LOCKDOOR"); */
1397 static BlockDriver bdrv_host_cdrom
= {
1398 .format_name
= "host_cdrom",
1399 .protocol_name
= "host_cdrom",
1400 .instance_size
= sizeof(BDRVRawState
),
1401 .bdrv_probe_device
= cdrom_probe_device
,
1402 .bdrv_file_open
= cdrom_open
,
1403 .bdrv_close
= raw_close
,
1404 .bdrv_create
= hdev_create
,
1405 .create_options
= raw_create_options
,
1406 .bdrv_has_zero_init
= hdev_has_zero_init
,
1407 .bdrv_flush
= raw_flush
,
1409 .bdrv_aio_readv
= raw_aio_readv
,
1410 .bdrv_aio_writev
= raw_aio_writev
,
1411 .bdrv_aio_flush
= raw_aio_flush
,
1413 .bdrv_read
= raw_read
,
1414 .bdrv_write
= raw_write
,
1415 .bdrv_getlength
= raw_getlength
,
1416 .bdrv_get_allocated_file_size
1417 = raw_get_allocated_file_size
,
1419 /* removable device support */
1420 .bdrv_is_inserted
= cdrom_is_inserted
,
1421 .bdrv_eject
= cdrom_eject
,
1422 .bdrv_set_locked
= cdrom_set_locked
,
1424 /* generic scsi device */
1425 .bdrv_ioctl
= hdev_ioctl
,
1426 .bdrv_aio_ioctl
= hdev_aio_ioctl
,
1428 #endif /* __linux__ */
1430 #if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
1431 static int cdrom_open(BlockDriverState
*bs
, const char *filename
, int flags
)
1433 BDRVRawState
*s
= bs
->opaque
;
1438 ret
= raw_open_common(bs
, filename
, flags
, 0);
1442 /* make sure the door isnt locked at this time */
1443 ioctl(s
->fd
, CDIOCALLOW
);
1447 static int cdrom_probe_device(const char *filename
)
1449 if (strstart(filename
, "/dev/cd", NULL
) ||
1450 strstart(filename
, "/dev/acd", NULL
))
1455 static int cdrom_reopen(BlockDriverState
*bs
)
1457 BDRVRawState
*s
= bs
->opaque
;
1461 * Force reread of possibly changed/newly loaded disc,
1462 * FreeBSD seems to not notice sometimes...
1466 fd
= open(bs
->filename
, s
->open_flags
, 0644);
1473 /* make sure the door isnt locked at this time */
1474 ioctl(s
->fd
, CDIOCALLOW
);
1478 static int cdrom_is_inserted(BlockDriverState
*bs
)
1480 return raw_getlength(bs
) > 0;
1483 static void cdrom_eject(BlockDriverState
*bs
, int eject_flag
)
1485 BDRVRawState
*s
= bs
->opaque
;
1490 (void) ioctl(s
->fd
, CDIOCALLOW
);
1493 if (ioctl(s
->fd
, CDIOCEJECT
) < 0)
1494 perror("CDIOCEJECT");
1496 if (ioctl(s
->fd
, CDIOCCLOSE
) < 0)
1497 perror("CDIOCCLOSE");
1503 static void cdrom_set_locked(BlockDriverState
*bs
, int locked
)
1505 BDRVRawState
*s
= bs
->opaque
;
1509 if (ioctl(s
->fd
, (locked
? CDIOCPREVENT
: CDIOCALLOW
)) < 0) {
1511 * Note: an error can happen if the distribution automatically
1514 /* perror("CDROM_LOCKDOOR"); */
1518 static BlockDriver bdrv_host_cdrom
= {
1519 .format_name
= "host_cdrom",
1520 .protocol_name
= "host_cdrom",
1521 .instance_size
= sizeof(BDRVRawState
),
1522 .bdrv_probe_device
= cdrom_probe_device
,
1523 .bdrv_file_open
= cdrom_open
,
1524 .bdrv_close
= raw_close
,
1525 .bdrv_create
= hdev_create
,
1526 .create_options
= raw_create_options
,
1527 .bdrv_has_zero_init
= hdev_has_zero_init
,
1528 .bdrv_flush
= raw_flush
,
1530 .bdrv_aio_readv
= raw_aio_readv
,
1531 .bdrv_aio_writev
= raw_aio_writev
,
1532 .bdrv_aio_flush
= raw_aio_flush
,
1534 .bdrv_read
= raw_read
,
1535 .bdrv_write
= raw_write
,
1536 .bdrv_getlength
= raw_getlength
,
1537 .bdrv_get_allocated_file_size
1538 = raw_get_allocated_file_size
,
1540 /* removable device support */
1541 .bdrv_is_inserted
= cdrom_is_inserted
,
1542 .bdrv_eject
= cdrom_eject
,
1543 .bdrv_set_locked
= cdrom_set_locked
,
1545 #endif /* __FreeBSD__ */
1547 static void bdrv_file_init(void)
1550 * Register all the drivers. Note that order is important, the driver
1551 * registered last will get probed first.
1553 bdrv_register(&bdrv_file
);
1554 bdrv_register(&bdrv_host_device
);
1556 bdrv_register(&bdrv_host_floppy
);
1557 bdrv_register(&bdrv_host_cdrom
);
1559 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1560 bdrv_register(&bdrv_host_cdrom
);
1564 block_init(bdrv_file_init
);