• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #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 
105 typedef 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 
123 static int fd_open(BlockDriverState *bs);
124 static int64_t raw_getlength(BlockDriverState *bs);
125 
126 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
127 static int cdrom_reopen(BlockDriverState *bs);
128 #endif
129 
raw_open_common(BlockDriverState * bs,const char * filename,int bdrv_flags,int open_flags)130 static 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 
194 out_free_buf:
195     qemu_vfree(s->aligned_buf);
196 out_close:
197     close(fd);
198     return -errno;
199 }
200 
raw_open(BlockDriverState * bs,const char * filename,int flags)201 static 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  */
raw_pread_aligned(BlockDriverState * bs,int64_t offset,uint8_t * buf,int count)233 static 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  */
raw_pwrite_aligned(BlockDriverState * bs,int64_t offset,const uint8_t * buf,int count)286 static 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  */
raw_pread(BlockDriverState * bs,int64_t offset,uint8_t * buf,int count)314 static 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 
raw_read(BlockDriverState * bs,int64_t sector_num,uint8_t * buf,int nb_sectors)385 static 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  */
raw_pwrite(BlockDriverState * bs,int64_t offset,const uint8_t * buf,int count)402 static 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 
raw_write(BlockDriverState * bs,int64_t sector_num,const uint8_t * buf,int nb_sectors)475 static 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  */
qiov_is_aligned(QEMUIOVector * qiov)489 static 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 
raw_aio_submit(BlockDriverState * bs,int64_t sector_num,QEMUIOVector * qiov,int nb_sectors,BlockDriverCompletionFunc * cb,void * opaque,int type)502 static 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 
raw_aio_readv(BlockDriverState * bs,int64_t sector_num,QEMUIOVector * qiov,int nb_sectors,BlockDriverCompletionFunc * cb,void * opaque)531 static 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 
raw_aio_writev(BlockDriverState * bs,int64_t sector_num,QEMUIOVector * qiov,int nb_sectors,BlockDriverCompletionFunc * cb,void * opaque)539 static 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 
raw_aio_flush(BlockDriverState * bs,BlockDriverCompletionFunc * cb,void * opaque)547 static 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 
raw_close(BlockDriverState * bs)558 static 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 
raw_truncate(BlockDriverState * bs,int64_t offset)569 static 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__
raw_getlength(BlockDriverState * bs)580 static 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__)
raw_getlength(BlockDriverState * bs)599 static 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)
raw_getlength(BlockDriverState * bs)625 static 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__)
641 again:
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
raw_getlength(BlockDriverState * bs)680 static 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 
raw_create(const char * filename,QEMUOptionParameter * options)694 static 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 
raw_flush(BlockDriverState * bs)723 static void raw_flush(BlockDriverState *bs)
724 {
725     BDRVRawState *s = bs->opaque;
726     qemu_fdatasync(s->fd);
727 }
728 
729 
730 static QEMUOptionParameter raw_create_options[] = {
731     {
732         .name = BLOCK_OPT_SIZE,
733         .type = OPT_SIZE,
734         .help = "Virtual disk size"
735     },
736     { NULL }
737 };
738 
739 static 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
765 static kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator );
766 static kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex maxPathSize );
767 
FindEjectableCDMedia(io_iterator_t * mediaIterator)768 kern_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 
GetBSDPath(io_iterator_t mediaIterator,char * bsdPath,CFIndex maxPathSize)794 kern_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 
hdev_probe_device(const char * filename)822 static 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 
hdev_open(BlockDriverState * bs,const char * filename,int flags)838 static 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. */
fd_open(BlockDriverState * bs)883 static 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_get_clock(rt_clock) - 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_get_clock(rt_clock) - 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_get_clock(rt_clock);
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_get_clock(rt_clock);
925     s->fd_got_error = 0;
926     return 0;
927 }
928 
hdev_ioctl(BlockDriverState * bs,unsigned long int req,void * buf)929 static 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 
hdev_aio_ioctl(BlockDriverState * bs,unsigned long int req,void * buf,BlockDriverCompletionFunc * cb,void * opaque)936 static 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__)
fd_open(BlockDriverState * bs)948 static 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 
fd_open(BlockDriverState * bs)959 static int fd_open(BlockDriverState *bs)
960 {
961     return 0;
962 }
963 
964 #endif /* !linux && !FreeBSD */
965 
hdev_create(const char * filename,QEMUOptionParameter * options)966 static 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 
hdev_has_zero_init(BlockDriverState * bs)996 static int hdev_has_zero_init(BlockDriverState *bs)
997 {
998     return 0;
999 }
1000 
1001 static 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__
floppy_open(BlockDriverState * bs,const char * filename,int flags)1029 static 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 
floppy_probe_device(const char * filename)1049 static 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);
1069 out:
1070     return prio;
1071 }
1072 
1073 
floppy_is_inserted(BlockDriverState * bs)1074 static int floppy_is_inserted(BlockDriverState *bs)
1075 {
1076     return fd_open(bs) >= 0;
1077 }
1078 
floppy_media_changed(BlockDriverState * bs)1079 static 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 
floppy_eject(BlockDriverState * bs,int eject_flag)1097 static 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 
1116 static 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 
cdrom_open(BlockDriverState * bs,const char * filename,int flags)1142 static 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 
cdrom_probe_device(const char * filename)1152 static 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);
1171 out:
1172     return prio;
1173 }
1174 
cdrom_is_inserted(BlockDriverState * bs)1175 static 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 
cdrom_eject(BlockDriverState * bs,int eject_flag)1186 static 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 
cdrom_set_locked(BlockDriverState * bs,int locked)1201 static 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 
1216 static 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__)
cdrom_open(BlockDriverState * bs,const char * filename,int flags)1248 static 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 
cdrom_probe_device(const char * filename)1264 static 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 
cdrom_reopen(BlockDriverState * bs)1272 static 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 
cdrom_is_inserted(BlockDriverState * bs)1295 static int cdrom_is_inserted(BlockDriverState *bs)
1296 {
1297     return raw_getlength(bs) > 0;
1298 }
1299 
cdrom_eject(BlockDriverState * bs,int eject_flag)1300 static 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 
cdrom_set_locked(BlockDriverState * bs,int locked)1322 static 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 
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     .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 
bdrv_file_init(void)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);
1384