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