Merge branch 'master' of git://git.sv.gnu.org/qemu
[qemu-kvm/markmc.git] / block / raw-posix.c
blobfdbf937dc8b77a5b4e7765f474075e15698e533b
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 "block_int.h"
28 #include "module.h"
29 #include "compatfd.h"
30 #include <assert.h>
31 #ifdef CONFIG_AIO
32 #include "posix-aio-compat.h"
33 #endif
35 #ifdef CONFIG_COCOA
36 #include <paths.h>
37 #include <sys/param.h>
38 #include <IOKit/IOKitLib.h>
39 #include <IOKit/IOBSD.h>
40 #include <IOKit/storage/IOMediaBSDClient.h>
41 #include <IOKit/storage/IOMedia.h>
42 #include <IOKit/storage/IOCDMedia.h>
43 //#include <IOKit/storage/IOCDTypes.h>
44 #include <CoreFoundation/CoreFoundation.h>
45 #endif
47 #ifdef __sun__
48 #define _POSIX_PTHREAD_SEMANTICS 1
49 #include <signal.h>
50 #include <sys/dkio.h>
51 #endif
52 #ifdef __linux__
53 #include <sys/ioctl.h>
54 #include <linux/cdrom.h>
55 #include <linux/fd.h>
56 #endif
57 #ifdef __FreeBSD__
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 //#define DEBUG_FLOPPY
76 //#define DEBUG_BLOCK
77 #if defined(DEBUG_BLOCK)
78 #define DEBUG_BLOCK_PRINT(formatCstr, ...) do { if (qemu_log_enabled()) \
79 { qemu_log(formatCstr, ## __VA_ARGS__); qemu_log_flush(); } } while (0)
80 #else
81 #define DEBUG_BLOCK_PRINT(formatCstr, ...)
82 #endif
84 /* OS X does not have O_DSYNC */
85 #ifndef O_DSYNC
86 #define O_DSYNC O_SYNC
87 #endif
89 /* Approximate O_DIRECT with O_DSYNC if O_DIRECT isn't available */
90 #ifndef O_DIRECT
91 #define O_DIRECT O_DSYNC
92 #endif
94 #define FTYPE_FILE 0
95 #define FTYPE_CD 1
96 #define FTYPE_FD 2
98 #define ALIGNED_BUFFER_SIZE (32 * 512)
100 /* if the FD is not accessed during that time (in ms), we try to
101 reopen it to see if the disk has been changed */
102 #define FD_OPEN_TIMEOUT 1000
104 typedef struct BDRVRawState {
105 int fd;
106 int type;
107 unsigned int lseek_err_cnt;
108 #if defined(__linux__)
109 /* linux floppy specific */
110 int fd_open_flags;
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 #if defined(__FreeBSD__)
117 int cd_open_flags;
118 #endif
119 uint8_t* aligned_buf;
120 } BDRVRawState;
122 static int posix_aio_init(void);
124 static int fd_open(BlockDriverState *bs);
126 #if defined(__FreeBSD__)
127 static int cd_open(BlockDriverState *bs);
128 #endif
130 static int raw_is_inserted(BlockDriverState *bs);
132 static int raw_open(BlockDriverState *bs, const char *filename, int flags)
134 BDRVRawState *s = bs->opaque;
135 int fd, open_flags, ret;
137 posix_aio_init();
139 s->lseek_err_cnt = 0;
141 open_flags = O_BINARY;
142 if ((flags & BDRV_O_ACCESS) == O_RDWR) {
143 open_flags |= O_RDWR;
144 } else {
145 open_flags |= O_RDONLY;
146 bs->read_only = 1;
148 if (flags & BDRV_O_CREAT)
149 open_flags |= O_CREAT | O_TRUNC;
151 /* Use O_DSYNC for write-through caching, no flags for write-back caching,
152 * and O_DIRECT for no caching. */
153 if ((flags & BDRV_O_NOCACHE))
154 open_flags |= O_DIRECT;
155 else if (!(flags & BDRV_O_CACHE_WB))
156 open_flags |= O_DSYNC;
158 s->type = FTYPE_FILE;
160 fd = open(filename, open_flags, 0644);
161 if (fd < 0) {
162 ret = -errno;
163 if (ret == -EROFS)
164 ret = -EACCES;
165 return ret;
167 s->fd = fd;
168 s->aligned_buf = NULL;
169 if ((flags & BDRV_O_NOCACHE)) {
170 s->aligned_buf = qemu_blockalign(bs, ALIGNED_BUFFER_SIZE);
171 if (s->aligned_buf == NULL) {
172 ret = -errno;
173 close(fd);
174 return ret;
177 return 0;
180 /* XXX: use host sector size if necessary with:
181 #ifdef DIOCGSECTORSIZE
183 unsigned int sectorsize = 512;
184 if (!ioctl(fd, DIOCGSECTORSIZE, &sectorsize) &&
185 sectorsize > bufsize)
186 bufsize = sectorsize;
188 #endif
189 #ifdef CONFIG_COCOA
190 u_int32_t blockSize = 512;
191 if ( !ioctl( fd, DKIOCGETBLOCKSIZE, &blockSize ) && blockSize > bufsize) {
192 bufsize = blockSize;
194 #endif
198 * offset and count are in bytes, but must be multiples of 512 for files
199 * opened with O_DIRECT. buf must be aligned to 512 bytes then.
201 * This function may be called without alignment if the caller ensures
202 * that O_DIRECT is not in effect.
204 static int raw_pread_aligned(BlockDriverState *bs, int64_t offset,
205 uint8_t *buf, int count)
207 BDRVRawState *s = bs->opaque;
208 int ret;
210 ret = fd_open(bs);
211 if (ret < 0)
212 return ret;
214 if (offset >= 0 && lseek(s->fd, offset, SEEK_SET) == (off_t)-1) {
215 ++(s->lseek_err_cnt);
216 if(s->lseek_err_cnt <= 10) {
217 DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
218 "] lseek failed : %d = %s\n",
219 s->fd, bs->filename, offset, buf, count,
220 bs->total_sectors, errno, strerror(errno));
222 return -1;
224 s->lseek_err_cnt=0;
226 ret = read(s->fd, buf, count);
227 if (ret == count)
228 goto label__raw_read__success;
230 DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
231 "] read failed %d : %d = %s\n",
232 s->fd, bs->filename, offset, buf, count,
233 bs->total_sectors, ret, errno, strerror(errno));
235 /* Try harder for CDrom. */
236 if (bs->type == BDRV_TYPE_CDROM) {
237 lseek(s->fd, offset, SEEK_SET);
238 ret = read(s->fd, buf, count);
239 if (ret == count)
240 goto label__raw_read__success;
241 lseek(s->fd, offset, SEEK_SET);
242 ret = read(s->fd, buf, count);
243 if (ret == count)
244 goto label__raw_read__success;
246 DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
247 "] retry read failed %d : %d = %s\n",
248 s->fd, bs->filename, offset, buf, count,
249 bs->total_sectors, ret, errno, strerror(errno));
252 label__raw_read__success:
254 return (ret < 0) ? -errno : ret;
258 * offset and count are in bytes, but must be multiples of 512 for files
259 * opened with O_DIRECT. buf must be aligned to 512 bytes then.
261 * This function may be called without alignment if the caller ensures
262 * that O_DIRECT is not in effect.
264 static int raw_pwrite_aligned(BlockDriverState *bs, int64_t offset,
265 const uint8_t *buf, int count)
267 BDRVRawState *s = bs->opaque;
268 int ret;
270 ret = fd_open(bs);
271 if (ret < 0)
272 return -errno;
274 if (offset >= 0 && lseek(s->fd, offset, SEEK_SET) == (off_t)-1) {
275 ++(s->lseek_err_cnt);
276 if(s->lseek_err_cnt) {
277 DEBUG_BLOCK_PRINT("raw_pwrite(%d:%s, %" PRId64 ", %p, %d) [%"
278 PRId64 "] lseek failed : %d = %s\n",
279 s->fd, bs->filename, offset, buf, count,
280 bs->total_sectors, errno, strerror(errno));
282 return -EIO;
284 s->lseek_err_cnt = 0;
286 ret = write(s->fd, buf, count);
287 if (ret == count)
288 goto label__raw_write__success;
290 DEBUG_BLOCK_PRINT("raw_pwrite(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
291 "] write failed %d : %d = %s\n",
292 s->fd, bs->filename, offset, buf, count,
293 bs->total_sectors, ret, errno, strerror(errno));
295 label__raw_write__success:
297 return (ret < 0) ? -errno : ret;
302 * offset and count are in bytes and possibly not aligned. For files opened
303 * with O_DIRECT, necessary alignments are ensured before calling
304 * raw_pread_aligned to do the actual read.
306 static int raw_pread(BlockDriverState *bs, int64_t offset,
307 uint8_t *buf, int count)
309 BDRVRawState *s = bs->opaque;
310 int size, ret, shift, sum;
312 sum = 0;
314 if (s->aligned_buf != NULL) {
316 if (offset & 0x1ff) {
317 /* align offset on a 512 bytes boundary */
319 shift = offset & 0x1ff;
320 size = (shift + count + 0x1ff) & ~0x1ff;
321 if (size > ALIGNED_BUFFER_SIZE)
322 size = ALIGNED_BUFFER_SIZE;
323 ret = raw_pread_aligned(bs, offset - shift, s->aligned_buf, size);
324 if (ret < 0)
325 return ret;
327 size = 512 - shift;
328 if (size > count)
329 size = count;
330 memcpy(buf, s->aligned_buf + shift, size);
332 buf += size;
333 offset += size;
334 count -= size;
335 sum += size;
337 if (count == 0)
338 return sum;
340 if (count & 0x1ff || (uintptr_t) buf & 0x1ff) {
342 /* read on aligned buffer */
344 while (count) {
346 size = (count + 0x1ff) & ~0x1ff;
347 if (size > ALIGNED_BUFFER_SIZE)
348 size = ALIGNED_BUFFER_SIZE;
350 ret = raw_pread_aligned(bs, offset, s->aligned_buf, size);
351 if (ret < 0)
352 return ret;
354 size = ret;
355 if (size > count)
356 size = count;
358 memcpy(buf, s->aligned_buf, size);
360 buf += size;
361 offset += size;
362 count -= size;
363 sum += size;
366 return sum;
370 return raw_pread_aligned(bs, offset, buf, count) + sum;
373 static int raw_read(BlockDriverState *bs, int64_t sector_num,
374 uint8_t *buf, int nb_sectors)
376 int ret;
378 ret = raw_pread(bs, sector_num * 512, buf, nb_sectors * 512);
379 if (ret == (nb_sectors * 512))
380 ret = 0;
381 return ret;
385 * offset and count are in bytes and possibly not aligned. For files opened
386 * with O_DIRECT, necessary alignments are ensured before calling
387 * raw_pwrite_aligned to do the actual write.
389 static int raw_pwrite(BlockDriverState *bs, int64_t offset,
390 const uint8_t *buf, int count)
392 BDRVRawState *s = bs->opaque;
393 int size, ret, shift, sum;
395 sum = 0;
397 if (s->aligned_buf != NULL) {
399 if (offset & 0x1ff) {
400 /* align offset on a 512 bytes boundary */
401 shift = offset & 0x1ff;
402 ret = raw_pread_aligned(bs, offset - shift, s->aligned_buf, 512);
403 if (ret < 0)
404 return ret;
406 size = 512 - shift;
407 if (size > count)
408 size = count;
409 memcpy(s->aligned_buf + shift, buf, size);
411 ret = raw_pwrite_aligned(bs, offset - shift, s->aligned_buf, 512);
412 if (ret < 0)
413 return ret;
415 buf += size;
416 offset += size;
417 count -= size;
418 sum += size;
420 if (count == 0)
421 return sum;
423 if (count & 0x1ff || (uintptr_t) buf & 0x1ff) {
425 while ((size = (count & ~0x1ff)) != 0) {
427 if (size > ALIGNED_BUFFER_SIZE)
428 size = ALIGNED_BUFFER_SIZE;
430 memcpy(s->aligned_buf, buf, size);
432 ret = raw_pwrite_aligned(bs, offset, s->aligned_buf, size);
433 if (ret < 0)
434 return ret;
436 buf += ret;
437 offset += ret;
438 count -= ret;
439 sum += ret;
441 /* here, count < 512 because (count & ~0x1ff) == 0 */
442 if (count) {
443 ret = raw_pread_aligned(bs, offset, s->aligned_buf, 512);
444 if (ret < 0)
445 return ret;
446 memcpy(s->aligned_buf, buf, count);
448 ret = raw_pwrite_aligned(bs, offset, s->aligned_buf, 512);
449 if (ret < 0)
450 return ret;
451 if (count < ret)
452 ret = count;
454 sum += ret;
456 return sum;
459 return raw_pwrite_aligned(bs, offset, buf, count) + sum;
462 static int raw_write(BlockDriverState *bs, int64_t sector_num,
463 const uint8_t *buf, int nb_sectors)
465 int ret;
466 ret = raw_pwrite(bs, sector_num * 512, buf, nb_sectors * 512);
467 if (ret == (nb_sectors * 512))
468 ret = 0;
469 return ret;
472 #ifdef CONFIG_AIO
473 /***********************************************************/
474 /* Unix AIO using POSIX AIO */
476 typedef struct RawAIOCB {
477 BlockDriverAIOCB common;
478 struct qemu_paiocb aiocb;
479 struct RawAIOCB *next;
480 int ret;
481 } RawAIOCB;
483 typedef struct PosixAioState
485 int fd;
486 RawAIOCB *first_aio;
487 } PosixAioState;
489 static void posix_aio_read(void *opaque)
491 PosixAioState *s = opaque;
492 RawAIOCB *acb, **pacb;
493 int ret;
494 size_t offset;
495 union {
496 struct qemu_signalfd_siginfo siginfo;
497 char buf[128];
498 } sig;
500 /* try to read from signalfd, don't freak out if we can't read anything */
501 offset = 0;
502 while (offset < 128) {
503 ssize_t len;
505 len = read(s->fd, sig.buf + offset, 128 - offset);
506 if (len == -1 && errno == EINTR)
507 continue;
508 if (len == -1 && errno == EAGAIN) {
509 /* there is no natural reason for this to happen,
510 * so we'll spin hard until we get everything just
511 * to be on the safe side. */
512 if (offset > 0)
513 continue;
516 offset += len;
519 for(;;) {
520 pacb = &s->first_aio;
521 for(;;) {
522 acb = *pacb;
523 if (!acb)
524 goto the_end;
525 ret = qemu_paio_error(&acb->aiocb);
526 if (ret == ECANCELED) {
527 /* remove the request */
528 *pacb = acb->next;
529 qemu_aio_release(acb);
530 } else if (ret != EINPROGRESS) {
531 /* end of aio */
532 if (ret == 0) {
533 ret = qemu_paio_return(&acb->aiocb);
534 if (ret == acb->aiocb.aio_nbytes)
535 ret = 0;
536 else
537 ret = -EINVAL;
538 } else {
539 ret = -ret;
541 /* remove the request */
542 *pacb = acb->next;
543 /* call the callback */
544 acb->common.cb(acb->common.opaque, ret);
545 qemu_aio_release(acb);
546 break;
547 } else {
548 pacb = &acb->next;
552 the_end: ;
555 static int posix_aio_flush(void *opaque)
557 PosixAioState *s = opaque;
558 return !!s->first_aio;
561 static PosixAioState *posix_aio_state;
563 static int posix_aio_init(void)
565 sigset_t mask;
566 PosixAioState *s;
567 struct qemu_paioinit ai;
569 if (posix_aio_state)
570 return 0;
572 s = qemu_malloc(sizeof(PosixAioState));
574 /* Make sure to block AIO signal */
575 sigemptyset(&mask);
576 sigaddset(&mask, SIGUSR2);
577 sigprocmask(SIG_BLOCK, &mask, NULL);
579 s->first_aio = NULL;
580 s->fd = qemu_signalfd(&mask);
581 if (s->fd == -1) {
582 fprintf(stderr, "failed to create signalfd\n");
583 return -errno;
586 fcntl(s->fd, F_SETFL, O_NONBLOCK);
588 qemu_aio_set_fd_handler(s->fd, posix_aio_read, NULL, posix_aio_flush, s);
590 memset(&ai, 0, sizeof(ai));
591 ai.aio_threads = 64;
592 ai.aio_num = 64;
593 qemu_paio_init(&ai);
595 posix_aio_state = s;
597 return 0;
600 static void raw_aio_remove(RawAIOCB *acb)
602 RawAIOCB **pacb;
604 /* remove the callback from the queue */
605 pacb = &posix_aio_state->first_aio;
606 for(;;) {
607 if (*pacb == NULL) {
608 fprintf(stderr, "raw_aio_remove: aio request not found!\n");
609 break;
610 } else if (*pacb == acb) {
611 *pacb = acb->next;
612 qemu_aio_release(acb);
613 break;
615 pacb = &(*pacb)->next;
619 static void raw_aio_cancel(BlockDriverAIOCB *blockacb)
621 int ret;
622 RawAIOCB *acb = (RawAIOCB *)blockacb;
624 ret = qemu_paio_cancel(acb->aiocb.aio_fildes, &acb->aiocb);
625 if (ret == QEMU_PAIO_NOTCANCELED) {
626 /* fail safe: if the aio could not be canceled, we wait for
627 it */
628 while (qemu_paio_error(&acb->aiocb) == EINPROGRESS);
631 raw_aio_remove(acb);
634 static AIOPool raw_aio_pool = {
635 .aiocb_size = sizeof(RawAIOCB),
636 .cancel = raw_aio_cancel,
639 static RawAIOCB *raw_aio_setup(BlockDriverState *bs, int64_t sector_num,
640 QEMUIOVector *qiov, int nb_sectors,
641 BlockDriverCompletionFunc *cb, void *opaque)
643 BDRVRawState *s = bs->opaque;
644 RawAIOCB *acb;
646 if (fd_open(bs) < 0)
647 return NULL;
649 acb = qemu_aio_get(&raw_aio_pool, bs, cb, opaque);
650 if (!acb)
651 return NULL;
652 acb->aiocb.aio_fildes = s->fd;
653 acb->aiocb.ev_signo = SIGUSR2;
654 acb->aiocb.aio_iov = qiov->iov;
655 acb->aiocb.aio_niov = qiov->niov;
656 acb->aiocb.aio_nbytes = nb_sectors * 512;
657 acb->aiocb.aio_offset = sector_num * 512;
658 acb->aiocb.aio_flags = 0;
661 * If O_DIRECT is used the buffer needs to be aligned on a sector
662 * boundary. Tell the low level code to ensure that in case it's
663 * not done yet.
665 if (s->aligned_buf)
666 acb->aiocb.aio_flags |= QEMU_AIO_SECTOR_ALIGNED;
668 acb->next = posix_aio_state->first_aio;
669 posix_aio_state->first_aio = acb;
670 return acb;
673 static BlockDriverAIOCB *raw_aio_readv(BlockDriverState *bs,
674 int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
675 BlockDriverCompletionFunc *cb, void *opaque)
677 RawAIOCB *acb;
679 acb = raw_aio_setup(bs, sector_num, qiov, nb_sectors, cb, opaque);
680 if (!acb)
681 return NULL;
682 if (qemu_paio_read(&acb->aiocb) < 0) {
683 raw_aio_remove(acb);
684 return NULL;
686 return &acb->common;
689 static BlockDriverAIOCB *raw_aio_writev(BlockDriverState *bs,
690 int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
691 BlockDriverCompletionFunc *cb, void *opaque)
693 RawAIOCB *acb;
695 acb = raw_aio_setup(bs, sector_num, qiov, nb_sectors, cb, opaque);
696 if (!acb)
697 return NULL;
698 if (qemu_paio_write(&acb->aiocb) < 0) {
699 raw_aio_remove(acb);
700 return NULL;
702 return &acb->common;
704 #else /* CONFIG_AIO */
705 static int posix_aio_init(void)
707 return 0;
709 #endif /* CONFIG_AIO */
712 static void raw_close(BlockDriverState *bs)
714 BDRVRawState *s = bs->opaque;
715 if (s->fd >= 0) {
716 close(s->fd);
717 s->fd = -1;
718 if (s->aligned_buf != NULL)
719 qemu_free(s->aligned_buf);
723 static int raw_truncate(BlockDriverState *bs, int64_t offset)
725 BDRVRawState *s = bs->opaque;
726 if (s->type != FTYPE_FILE)
727 return -ENOTSUP;
728 if (ftruncate(s->fd, offset) < 0)
729 return -errno;
730 return 0;
733 #ifdef __OpenBSD__
734 static int64_t raw_getlength(BlockDriverState *bs)
736 BDRVRawState *s = bs->opaque;
737 int fd = s->fd;
738 struct stat st;
740 if (fstat(fd, &st))
741 return -1;
742 if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) {
743 struct disklabel dl;
745 if (ioctl(fd, DIOCGDINFO, &dl))
746 return -1;
747 return (uint64_t)dl.d_secsize *
748 dl.d_partitions[DISKPART(st.st_rdev)].p_size;
749 } else
750 return st.st_size;
752 #else /* !__OpenBSD__ */
753 static int64_t raw_getlength(BlockDriverState *bs)
755 BDRVRawState *s = bs->opaque;
756 int fd = s->fd;
757 int64_t size;
758 #ifdef HOST_BSD
759 struct stat sb;
760 #ifdef __FreeBSD__
761 int reopened = 0;
762 #endif
763 #endif
764 #ifdef __sun__
765 struct dk_minfo minfo;
766 int rv;
767 #endif
768 int ret;
770 ret = fd_open(bs);
771 if (ret < 0)
772 return ret;
774 #ifdef HOST_BSD
775 #ifdef __FreeBSD__
776 again:
777 #endif
778 if (!fstat(fd, &sb) && (S_IFCHR & sb.st_mode)) {
779 #ifdef DIOCGMEDIASIZE
780 if (ioctl(fd, DIOCGMEDIASIZE, (off_t *)&size))
781 #elif defined(DIOCGPART)
783 struct partinfo pi;
784 if (ioctl(fd, DIOCGPART, &pi) == 0)
785 size = pi.media_size;
786 else
787 size = 0;
789 if (size == 0)
790 #endif
791 #ifdef CONFIG_COCOA
792 size = LONG_LONG_MAX;
793 #else
794 size = lseek(fd, 0LL, SEEK_END);
795 #endif
796 #ifdef __FreeBSD__
797 switch(s->type) {
798 case FTYPE_CD:
799 /* XXX FreeBSD acd returns UINT_MAX sectors for an empty drive */
800 if (size == 2048LL * (unsigned)-1)
801 size = 0;
802 /* XXX no disc? maybe we need to reopen... */
803 if (size <= 0 && !reopened && cd_open(bs) >= 0) {
804 reopened = 1;
805 goto again;
808 #endif
809 } else
810 #endif
811 #ifdef __sun__
813 * use the DKIOCGMEDIAINFO ioctl to read the size.
815 rv = ioctl ( fd, DKIOCGMEDIAINFO, &minfo );
816 if ( rv != -1 ) {
817 size = minfo.dki_lbsize * minfo.dki_capacity;
818 } else /* there are reports that lseek on some devices
819 fails, but irc discussion said that contingency
820 on contingency was overkill */
821 #endif
823 size = lseek(fd, 0, SEEK_END);
825 return size;
827 #endif
829 static int raw_create(const char *filename, QEMUOptionParameter *options)
831 int fd;
832 int64_t total_size = 0;
834 /* Read out options */
835 while (options && options->name) {
836 if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
837 total_size = options->value.n / 512;
839 options++;
842 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
843 0644);
844 if (fd < 0)
845 return -EIO;
846 ftruncate(fd, total_size * 512);
847 close(fd);
848 return 0;
851 static void raw_flush(BlockDriverState *bs)
853 BDRVRawState *s = bs->opaque;
854 fsync(s->fd);
858 static QEMUOptionParameter raw_create_options[] = {
859 { BLOCK_OPT_SIZE, OPT_SIZE },
860 { NULL }
863 static BlockDriver bdrv_raw = {
864 .format_name = "raw",
865 .instance_size = sizeof(BDRVRawState),
866 .bdrv_probe = NULL, /* no probe for protocols */
867 .bdrv_open = raw_open,
868 .bdrv_read = raw_read,
869 .bdrv_write = raw_write,
870 .bdrv_close = raw_close,
871 .bdrv_create = raw_create,
872 .bdrv_flush = raw_flush,
874 #ifdef CONFIG_AIO
875 .bdrv_aio_readv = raw_aio_readv,
876 .bdrv_aio_writev = raw_aio_writev,
877 #endif
879 .bdrv_truncate = raw_truncate,
880 .bdrv_getlength = raw_getlength,
882 .create_options = raw_create_options,
885 /***********************************************/
886 /* host device */
888 #ifdef CONFIG_COCOA
889 static kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator );
890 static kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex maxPathSize );
892 kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator )
894 kern_return_t kernResult;
895 mach_port_t masterPort;
896 CFMutableDictionaryRef classesToMatch;
898 kernResult = IOMasterPort( MACH_PORT_NULL, &masterPort );
899 if ( KERN_SUCCESS != kernResult ) {
900 printf( "IOMasterPort returned %d\n", kernResult );
903 classesToMatch = IOServiceMatching( kIOCDMediaClass );
904 if ( classesToMatch == NULL ) {
905 printf( "IOServiceMatching returned a NULL dictionary.\n" );
906 } else {
907 CFDictionarySetValue( classesToMatch, CFSTR( kIOMediaEjectableKey ), kCFBooleanTrue );
909 kernResult = IOServiceGetMatchingServices( masterPort, classesToMatch, mediaIterator );
910 if ( KERN_SUCCESS != kernResult )
912 printf( "IOServiceGetMatchingServices returned %d\n", kernResult );
915 return kernResult;
918 kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex maxPathSize )
920 io_object_t nextMedia;
921 kern_return_t kernResult = KERN_FAILURE;
922 *bsdPath = '\0';
923 nextMedia = IOIteratorNext( mediaIterator );
924 if ( nextMedia )
926 CFTypeRef bsdPathAsCFString;
927 bsdPathAsCFString = IORegistryEntryCreateCFProperty( nextMedia, CFSTR( kIOBSDNameKey ), kCFAllocatorDefault, 0 );
928 if ( bsdPathAsCFString ) {
929 size_t devPathLength;
930 strcpy( bsdPath, _PATH_DEV );
931 strcat( bsdPath, "r" );
932 devPathLength = strlen( bsdPath );
933 if ( CFStringGetCString( bsdPathAsCFString, bsdPath + devPathLength, maxPathSize - devPathLength, kCFStringEncodingASCII ) ) {
934 kernResult = KERN_SUCCESS;
936 CFRelease( bsdPathAsCFString );
938 IOObjectRelease( nextMedia );
941 return kernResult;
944 #endif
946 static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
948 BDRVRawState *s = bs->opaque;
949 int fd, open_flags, ret;
951 posix_aio_init();
953 #ifdef CONFIG_COCOA
954 if (strstart(filename, "/dev/cdrom", NULL)) {
955 kern_return_t kernResult;
956 io_iterator_t mediaIterator;
957 char bsdPath[ MAXPATHLEN ];
958 int fd;
960 kernResult = FindEjectableCDMedia( &mediaIterator );
961 kernResult = GetBSDPath( mediaIterator, bsdPath, sizeof( bsdPath ) );
963 if ( bsdPath[ 0 ] != '\0' ) {
964 strcat(bsdPath,"s0");
965 /* some CDs don't have a partition 0 */
966 fd = open(bsdPath, O_RDONLY | O_BINARY | O_LARGEFILE);
967 if (fd < 0) {
968 bsdPath[strlen(bsdPath)-1] = '1';
969 } else {
970 close(fd);
972 filename = bsdPath;
975 if ( mediaIterator )
976 IOObjectRelease( mediaIterator );
978 #endif
979 open_flags = O_BINARY;
980 if ((flags & BDRV_O_ACCESS) == O_RDWR) {
981 open_flags |= O_RDWR;
982 } else {
983 open_flags |= O_RDONLY;
984 bs->read_only = 1;
986 /* Use O_DSYNC for write-through caching, no flags for write-back caching,
987 * and O_DIRECT for no caching. */
988 if ((flags & BDRV_O_NOCACHE))
989 open_flags |= O_DIRECT;
990 else if (!(flags & BDRV_O_CACHE_WB))
991 open_flags |= O_DSYNC;
993 s->type = FTYPE_FILE;
994 #if defined(__linux__)
995 if (strstart(filename, "/dev/cd", NULL)) {
996 /* open will not fail even if no CD is inserted */
997 open_flags |= O_NONBLOCK;
998 s->type = FTYPE_CD;
999 } else if (strstart(filename, "/dev/fd", NULL)) {
1000 s->type = FTYPE_FD;
1001 s->fd_open_flags = open_flags;
1002 /* open will not fail even if no floppy is inserted */
1003 open_flags |= O_NONBLOCK;
1004 #ifdef CONFIG_AIO
1005 } else if (strstart(filename, "/dev/sg", NULL)) {
1006 bs->sg = 1;
1007 #endif
1009 #endif
1010 #if defined(__FreeBSD__)
1011 if (strstart(filename, "/dev/cd", NULL) ||
1012 strstart(filename, "/dev/acd", NULL)) {
1013 s->type = FTYPE_CD;
1014 s->cd_open_flags = open_flags;
1016 #endif
1017 s->fd = -1;
1018 fd = open(filename, open_flags, 0644);
1019 if (fd < 0) {
1020 ret = -errno;
1021 if (ret == -EROFS)
1022 ret = -EACCES;
1023 return ret;
1025 s->fd = fd;
1026 #if defined(__FreeBSD__)
1027 /* make sure the door isnt locked at this time */
1028 if (s->type == FTYPE_CD)
1029 ioctl (s->fd, CDIOCALLOW);
1030 #endif
1031 #if defined(__linux__)
1032 /* close fd so that we can reopen it as needed */
1033 if (s->type == FTYPE_FD) {
1034 close(s->fd);
1035 s->fd = -1;
1036 s->fd_media_changed = 1;
1038 #endif
1039 return 0;
1042 #if defined(__linux__)
1043 /* Note: we do not have a reliable method to detect if the floppy is
1044 present. The current method is to try to open the floppy at every
1045 I/O and to keep it opened during a few hundreds of ms. */
1046 static int fd_open(BlockDriverState *bs)
1048 BDRVRawState *s = bs->opaque;
1049 int last_media_present;
1051 if (s->type != FTYPE_FD)
1052 return 0;
1053 last_media_present = (s->fd >= 0);
1054 if (s->fd >= 0 &&
1055 (qemu_get_clock(rt_clock) - s->fd_open_time) >= FD_OPEN_TIMEOUT) {
1056 close(s->fd);
1057 s->fd = -1;
1058 #ifdef DEBUG_FLOPPY
1059 printf("Floppy closed\n");
1060 #endif
1062 if (s->fd < 0) {
1063 if (s->fd_got_error &&
1064 (qemu_get_clock(rt_clock) - s->fd_error_time) < FD_OPEN_TIMEOUT) {
1065 #ifdef DEBUG_FLOPPY
1066 printf("No floppy (open delayed)\n");
1067 #endif
1068 return -EIO;
1070 s->fd = open(bs->filename, s->fd_open_flags);
1071 if (s->fd < 0) {
1072 s->fd_error_time = qemu_get_clock(rt_clock);
1073 s->fd_got_error = 1;
1074 if (last_media_present)
1075 s->fd_media_changed = 1;
1076 #ifdef DEBUG_FLOPPY
1077 printf("No floppy\n");
1078 #endif
1079 return -EIO;
1081 #ifdef DEBUG_FLOPPY
1082 printf("Floppy opened\n");
1083 #endif
1085 if (!last_media_present)
1086 s->fd_media_changed = 1;
1087 s->fd_open_time = qemu_get_clock(rt_clock);
1088 s->fd_got_error = 0;
1089 return 0;
1092 static int raw_is_inserted(BlockDriverState *bs)
1094 BDRVRawState *s = bs->opaque;
1095 int ret;
1097 switch(s->type) {
1098 case FTYPE_CD:
1099 ret = ioctl(s->fd, CDROM_DRIVE_STATUS, CDSL_CURRENT);
1100 if (ret == CDS_DISC_OK)
1101 return 1;
1102 else
1103 return 0;
1104 break;
1105 case FTYPE_FD:
1106 ret = fd_open(bs);
1107 return (ret >= 0);
1108 default:
1109 return 1;
1113 /* currently only used by fdc.c, but a CD version would be good too */
1114 static int raw_media_changed(BlockDriverState *bs)
1116 BDRVRawState *s = bs->opaque;
1118 switch(s->type) {
1119 case FTYPE_FD:
1121 int ret;
1122 /* XXX: we do not have a true media changed indication. It
1123 does not work if the floppy is changed without trying
1124 to read it */
1125 fd_open(bs);
1126 ret = s->fd_media_changed;
1127 s->fd_media_changed = 0;
1128 #ifdef DEBUG_FLOPPY
1129 printf("Floppy changed=%d\n", ret);
1130 #endif
1131 return ret;
1133 default:
1134 return -ENOTSUP;
1138 static int raw_eject(BlockDriverState *bs, int eject_flag)
1140 BDRVRawState *s = bs->opaque;
1142 switch(s->type) {
1143 case FTYPE_CD:
1144 if (eject_flag) {
1145 if (ioctl (s->fd, CDROMEJECT, NULL) < 0)
1146 perror("CDROMEJECT");
1147 } else {
1148 if (ioctl (s->fd, CDROMCLOSETRAY, NULL) < 0)
1149 perror("CDROMEJECT");
1151 break;
1152 case FTYPE_FD:
1154 int fd;
1155 if (s->fd >= 0) {
1156 close(s->fd);
1157 s->fd = -1;
1159 fd = open(bs->filename, s->fd_open_flags | O_NONBLOCK);
1160 if (fd >= 0) {
1161 if (ioctl(fd, FDEJECT, 0) < 0)
1162 perror("FDEJECT");
1163 close(fd);
1166 break;
1167 default:
1168 return -ENOTSUP;
1170 return 0;
1173 static int raw_set_locked(BlockDriverState *bs, int locked)
1175 BDRVRawState *s = bs->opaque;
1177 switch(s->type) {
1178 case FTYPE_CD:
1179 if (ioctl (s->fd, CDROM_LOCKDOOR, locked) < 0) {
1180 /* Note: an error can happen if the distribution automatically
1181 mounts the CD-ROM */
1182 // perror("CDROM_LOCKDOOR");
1184 break;
1185 default:
1186 return -ENOTSUP;
1188 return 0;
1191 static int raw_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
1193 BDRVRawState *s = bs->opaque;
1195 return ioctl(s->fd, req, buf);
1198 #ifdef CONFIG_AIO
1199 static BlockDriverAIOCB *raw_aio_ioctl(BlockDriverState *bs,
1200 unsigned long int req, void *buf,
1201 BlockDriverCompletionFunc *cb, void *opaque)
1203 BDRVRawState *s = bs->opaque;
1204 RawAIOCB *acb;
1206 if (fd_open(bs) < 0)
1207 return NULL;
1209 acb = qemu_aio_get(&raw_aio_pool, bs, cb, opaque);
1210 if (!acb)
1211 return NULL;
1212 acb->aiocb.aio_fildes = s->fd;
1213 acb->aiocb.ev_signo = SIGUSR2;
1214 acb->aiocb.aio_offset = 0;
1215 acb->aiocb.aio_flags = 0;
1217 acb->next = posix_aio_state->first_aio;
1218 posix_aio_state->first_aio = acb;
1220 acb->aiocb.aio_ioctl_buf = buf;
1221 acb->aiocb.aio_ioctl_cmd = req;
1222 if (qemu_paio_ioctl(&acb->aiocb) < 0) {
1223 raw_aio_remove(acb);
1224 return NULL;
1227 return &acb->common;
1229 #endif
1231 #elif defined(__FreeBSD__)
1233 static int fd_open(BlockDriverState *bs)
1235 BDRVRawState *s = bs->opaque;
1237 /* this is just to ensure s->fd is sane (its called by io ops) */
1238 if (s->fd >= 0)
1239 return 0;
1240 return -EIO;
1243 static int cd_open(BlockDriverState *bs)
1245 #if defined(__FreeBSD__)
1246 BDRVRawState *s = bs->opaque;
1247 int fd;
1249 switch(s->type) {
1250 case FTYPE_CD:
1251 /* XXX force reread of possibly changed/newly loaded disc,
1252 * FreeBSD seems to not notice sometimes... */
1253 if (s->fd >= 0)
1254 close (s->fd);
1255 fd = open(bs->filename, s->cd_open_flags, 0644);
1256 if (fd < 0) {
1257 s->fd = -1;
1258 return -EIO;
1260 s->fd = fd;
1261 /* make sure the door isnt locked at this time */
1262 ioctl (s->fd, CDIOCALLOW);
1264 #endif
1265 return 0;
1268 static int raw_is_inserted(BlockDriverState *bs)
1270 BDRVRawState *s = bs->opaque;
1272 switch(s->type) {
1273 case FTYPE_CD:
1274 return (raw_getlength(bs) > 0);
1275 case FTYPE_FD:
1276 /* XXX handle this */
1277 /* FALLTHRU */
1278 default:
1279 return 1;
1283 static int raw_media_changed(BlockDriverState *bs)
1285 return -ENOTSUP;
1288 static int raw_eject(BlockDriverState *bs, int eject_flag)
1290 BDRVRawState *s = bs->opaque;
1292 switch(s->type) {
1293 case FTYPE_CD:
1294 if (s->fd < 0)
1295 return -ENOTSUP;
1296 (void) ioctl (s->fd, CDIOCALLOW);
1297 if (eject_flag) {
1298 if (ioctl (s->fd, CDIOCEJECT) < 0)
1299 perror("CDIOCEJECT");
1300 } else {
1301 if (ioctl (s->fd, CDIOCCLOSE) < 0)
1302 perror("CDIOCCLOSE");
1304 if (cd_open(bs) < 0)
1305 return -ENOTSUP;
1306 break;
1307 case FTYPE_FD:
1308 /* XXX handle this */
1309 /* FALLTHRU */
1310 default:
1311 return -ENOTSUP;
1313 return 0;
1316 static int raw_set_locked(BlockDriverState *bs, int locked)
1318 BDRVRawState *s = bs->opaque;
1320 switch(s->type) {
1321 case FTYPE_CD:
1322 if (s->fd < 0)
1323 return -ENOTSUP;
1324 if (ioctl (s->fd, (locked ? CDIOCPREVENT : CDIOCALLOW)) < 0) {
1325 /* Note: an error can happen if the distribution automatically
1326 mounts the CD-ROM */
1327 // perror("CDROM_LOCKDOOR");
1329 break;
1330 default:
1331 return -ENOTSUP;
1333 return 0;
1336 static int raw_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
1338 return -ENOTSUP;
1340 #else /* !linux && !FreeBSD */
1342 static int fd_open(BlockDriverState *bs)
1344 return 0;
1347 static int raw_is_inserted(BlockDriverState *bs)
1349 return 1;
1352 static int raw_media_changed(BlockDriverState *bs)
1354 return -ENOTSUP;
1357 static int raw_eject(BlockDriverState *bs, int eject_flag)
1359 return -ENOTSUP;
1362 static int raw_set_locked(BlockDriverState *bs, int locked)
1364 return -ENOTSUP;
1367 static int raw_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
1369 return -ENOTSUP;
1372 static BlockDriverAIOCB *raw_aio_ioctl(BlockDriverState *bs,
1373 unsigned long int req, void *buf,
1374 BlockDriverCompletionFunc *cb, void *opaque)
1376 return NULL;
1378 #endif /* !linux && !FreeBSD */
1380 static int hdev_create(const char *filename, QEMUOptionParameter *options)
1382 int fd;
1383 int ret = 0;
1384 struct stat stat_buf;
1385 int64_t total_size = 0;
1387 /* Read out options */
1388 while (options && options->name) {
1389 if (!strcmp(options->name, "size")) {
1390 total_size = options->value.n / 512;
1392 options++;
1395 fd = open(filename, O_WRONLY | O_BINARY);
1396 if (fd < 0)
1397 return -EIO;
1399 if (fstat(fd, &stat_buf) < 0)
1400 ret = -EIO;
1401 else if (!S_ISBLK(stat_buf.st_mode) && !S_ISCHR(stat_buf.st_mode))
1402 ret = -EIO;
1403 else if (lseek(fd, 0, SEEK_END) < total_size * 512)
1404 ret = -ENOSPC;
1406 close(fd);
1407 return ret;
1410 static BlockDriver bdrv_host_device = {
1411 .format_name = "host_device",
1412 .instance_size = sizeof(BDRVRawState),
1413 .bdrv_open = hdev_open,
1414 .bdrv_close = raw_close,
1415 .bdrv_create = hdev_create,
1416 .bdrv_flush = raw_flush,
1418 #ifdef CONFIG_AIO
1419 .bdrv_aio_readv = raw_aio_readv,
1420 .bdrv_aio_writev = raw_aio_writev,
1421 #endif
1423 .bdrv_read = raw_read,
1424 .bdrv_write = raw_write,
1425 .bdrv_getlength = raw_getlength,
1427 /* removable device support */
1428 .bdrv_is_inserted = raw_is_inserted,
1429 .bdrv_media_changed = raw_media_changed,
1430 .bdrv_eject = raw_eject,
1431 .bdrv_set_locked = raw_set_locked,
1432 /* generic scsi device */
1433 .bdrv_ioctl = raw_ioctl,
1434 #ifdef CONFIG_AIO
1435 .bdrv_aio_ioctl = raw_aio_ioctl,
1436 #endif
1439 static void bdrv_raw_init(void)
1441 bdrv_register(&bdrv_raw);
1442 bdrv_register(&bdrv_host_device);
1445 block_init(bdrv_raw_init);