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