1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24: #include "qemu-common.h"
25: #ifndef QEMU_IMG
26: #include "qemu-timer.h"
27: #include "exec-all.h"
28: #endif
29: #include "block_int.h"
30: #include <assert.h>
31: #include <aio.h>
32:
33: #ifdef CONFIG_COCOA
34: #include <paths.h>
35: #include <sys/param.h>
36: #include <IOKit/IOKitLib.h>
37: #include <IOKit/IOBSD.h>
38: #include <IOKit/storage/IOMediaBSDClient.h>
39: #include <IOKit/storage/IOMedia.h>
40: #include <IOKit/storage/IOCDMedia.h>
41:
42: #include <CoreFoundation/CoreFoundation.h>
43: #endif
44:
45: #ifdef __sun__
46: #define _POSIX_PTHREAD_SEMANTICS 1
47: #include <signal.h>
48: #include <sys/dkio.h>
49: #endif
50: #ifdef __linux__
51: #include <sys/ioctl.h>
52: #include <linux/cdrom.h>
53: #include <linux/fd.h>
54: #endif
55: #ifdef __FreeBSD__
56: #include <sys/disk.h>
57: #endif
58:
59:
60:
61:
62: #if defined(DEBUG_BLOCK) && !defined(QEMU_IMG)
63: #define DEBUG_BLOCK_PRINT(formatCstr, args...) do { if (loglevel != 0) \
64: { fprintf(logfile, formatCstr, ##args); fflush(logfile); } } while (0)
65: #else
66: #define DEBUG_BLOCK_PRINT(formatCstr, args...)
67: #endif
68:
69: #define FTYPE_FILE 0
70: #define FTYPE_CD 1
71: #define FTYPE_FD 2
72:
73:
74:
75: #define FD_OPEN_TIMEOUT 1000
76:
77: typedef struct BDRVRawState {
78: int fd;
79: int type;
80: unsigned int lseek_err_cnt;
81: #if defined(__linux__)
82:
83: int fd_open_flags;
84: int64_t fd_open_time;
85: int64_t fd_error_time;
86: int fd_got_error;
87: int fd_media_changed;
88: #endif
89: } BDRVRawState;
90:
91: static int fd_open(BlockDriverState *bs);
92:
93: static int raw_open(BlockDriverState *bs, const char *filename, int flags)
94: {
95: BDRVRawState *s = bs->opaque;
96: int fd, open_flags, ret;
97:
98: s->lseek_err_cnt = 0;
99:
100: open_flags = O_BINARY;
101: if ((flags & BDRV_O_ACCESS) == O_RDWR) {
102: open_flags |= O_RDWR;
103: } else {
104: open_flags |= O_RDONLY;
105: bs->read_only = 1;
106: }
107: if (flags & BDRV_O_CREAT)
108: open_flags |= O_CREAT | O_TRUNC;
109: #ifdef O_DIRECT
110: if (flags & BDRV_O_DIRECT)
111: open_flags |= O_DIRECT;
112: #endif
113:
114: s->type = FTYPE_FILE;
115:
116: fd = open(filename, open_flags, 0644);
117: if (fd < 0) {
118: ret = -errno;
119: if (ret == -EROFS)
120: ret = -EACCES;
121: return ret;
122: }
123: s->fd = fd;
124: return 0;
125: }
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144: static int raw_pread(BlockDriverState *bs, int64_t offset,
145: uint8_t *buf, int count)
146: {
147: BDRVRawState *s = bs->opaque;
148: int ret;
149:
150: ret = fd_open(bs);
151: if (ret < 0)
152: return ret;
153:
154: if (offset >= 0 && lseek(s->fd, offset, SEEK_SET) == (off_t)-1) {
155: ++(s->lseek_err_cnt);
156: if(s->lseek_err_cnt <= 10) {
157: DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
158: "] lseek failed : %d = %s\n",
159: s->fd, bs->filename, offset, buf, count,
160: bs->total_sectors, errno, strerror(errno));
161: }
162: return -1;
163: }
164: s->lseek_err_cnt=0;
165:
166: ret = read(s->fd, buf, count);
167: if (ret == count)
168: goto label__raw_read__success;
169:
170: DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
171: "] read failed %d : %d = %s\n",
172: s->fd, bs->filename, offset, buf, count,
173: bs->total_sectors, ret, errno, strerror(errno));
174:
175:
176: if (bs->type == BDRV_TYPE_CDROM) {
177: lseek(s->fd, offset, SEEK_SET);
178: ret = read(s->fd, buf, count);
179: if (ret == count)
180: goto label__raw_read__success;
181: lseek(s->fd, offset, SEEK_SET);
182: ret = read(s->fd, buf, count);
183: if (ret == count)
184: goto label__raw_read__success;
185:
186: DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
187: "] retry read failed %d : %d = %s\n",
188: s->fd, bs->filename, offset, buf, count,
189: bs->total_sectors, ret, errno, strerror(errno));
190: }
191:
192: label__raw_read__success:
193:
194: return ret;
195: }
196:
197: static int raw_pwrite(BlockDriverState *bs, int64_t offset,
198: const uint8_t *buf, int count)
199: {
200: BDRVRawState *s = bs->opaque;
201: int ret;
202:
203: ret = fd_open(bs);
204: if (ret < 0)
205: return ret;
206:
207: if (offset >= 0 && lseek(s->fd, offset, SEEK_SET) == (off_t)-1) {
208: ++(s->lseek_err_cnt);
209: if(s->lseek_err_cnt) {
210: DEBUG_BLOCK_PRINT("raw_pwrite(%d:%s, %" PRId64 ", %p, %d) [%"
211: PRId64 "] lseek failed : %d = %s\n",
212: s->fd, bs->filename, offset, buf, count,
213: bs->total_sectors, errno, strerror(errno));
214: }
215: return -1;
216: }
217: s->lseek_err_cnt = 0;
218:
219: ret = write(s->fd, buf, count);
220: if (ret == count)
221: goto label__raw_write__success;
222:
223: DEBUG_BLOCK_PRINT("raw_pwrite(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
224: "] write failed %d : %d = %s\n",
225: s->fd, bs->filename, offset, buf, count,
226: bs->total_sectors, ret, errno, strerror(errno));
227:
228: label__raw_write__success:
229:
230: return ret;
231: }
232:
233:
234:
235:
236: typedef struct RawAIOCB {
237: BlockDriverAIOCB common;
238: struct aiocb aiocb;
239: struct RawAIOCB *next;
240: } RawAIOCB;
241:
242: static int aio_sig_num = SIGUSR2;
243: static RawAIOCB *first_aio;
244: static int aio_initialized = 0;
245:
246: static void aio_signal_handler(int signum)
247: {
248: #ifndef QEMU_IMG
249: CPUState *env = cpu_single_env;
250: if (env) {
251:
252: cpu_interrupt(env, CPU_INTERRUPT_EXIT);
253: #ifdef USE_KQEMU
254: if (env->kqemu_enabled) {
255: kqemu_cpu_interrupt(env);
256: }
257: #endif
258: }
259: #endif
260: }
261:
262: void qemu_aio_init(void)
263: {
264: struct sigaction act;
265:
266: aio_initialized = 1;
267:
268: sigfillset(&act.sa_mask);
269: act.sa_flags = 0;
270: act.sa_handler = aio_signal_handler;
271: sigaction(aio_sig_num, &act, NULL);
272:
273: #if defined(__GLIBC__) && defined(__linux__)
274: {
275:
276:
277: struct aioinit ai;
278: memset(&ai, 0, sizeof(ai));
279: ai.aio_threads = 1;
280: ai.aio_num = 1;
281: ai.aio_idle_time = 365 * 100000;
282: aio_init(&ai);
283: }
284: #endif
285: }
286:
287: void qemu_aio_poll(void)
288: {
289: RawAIOCB *acb, **pacb;
290: int ret;
291:
292: for(;;) {
293: pacb = &first_aio;
294: for(;;) {
295: acb = *pacb;
296: if (!acb)
297: goto the_end;
298: ret = aio_error(&acb->aiocb);
299: if (ret == ECANCELED) {
300:
301: *pacb = acb->next;
302: qemu_aio_release(acb);
303: } else if (ret != EINPROGRESS) {
304:
305: if (ret == 0) {
306: ret = aio_return(&acb->aiocb);
307: if (ret == acb->aiocb.aio_nbytes)
308: ret = 0;
309: else
310: ret = -EINVAL;
311: } else {
312: ret = -ret;
313: }
314:
315: *pacb = acb->next;
316:
317: acb->common.cb(acb->common.opaque, ret);
318: qemu_aio_release(acb);
319: break;
320: } else {
321: pacb = &acb->next;
322: }
323: }
324: }
325: the_end: ;
326: }
327:
328:
329: void qemu_aio_flush(void)
330: {
331: qemu_aio_wait_start();
332: qemu_aio_poll();
333: while (first_aio) {
334: qemu_aio_wait();
335: }
336: qemu_aio_wait_end();
337: }
338:
339:
340: static sigset_t wait_oset;
341:
342: void qemu_aio_wait_start(void)
343: {
344: sigset_t set;
345:
346: if (!aio_initialized)
347: qemu_aio_init();
348: sigemptyset(&set);
349: sigaddset(&set, aio_sig_num);
350: sigprocmask(SIG_BLOCK, &set, &wait_oset);
351: }
352:
353: void qemu_aio_wait(void)
354: {
355: sigset_t set;
356: int nb_sigs;
357:
358: #ifndef QEMU_IMG
359: if (qemu_bh_poll())
360: return;
361: #endif
362: sigemptyset(&set);
363: sigaddset(&set, aio_sig_num);
364: sigwait(&set, &nb_sigs);
365: qemu_aio_poll();
366: }
367:
368: void qemu_aio_wait_end(void)
369: {
370: sigprocmask(SIG_SETMASK, &wait_oset, NULL);
371: }
372:
373: static RawAIOCB *raw_aio_setup(BlockDriverState *bs,
374: int64_t sector_num, uint8_t *buf, int nb_sectors,
375: BlockDriverCompletionFunc *cb, void *opaque)
376: {
377: BDRVRawState *s = bs->opaque;
378: RawAIOCB *acb;
379:
380: if (fd_open(bs) < 0)
381: return NULL;
382:
383: acb = qemu_aio_get(bs, cb, opaque);
384: if (!acb)
385: return NULL;
386: acb->aiocb.aio_fildes = s->fd;
387: acb->aiocb.aio_sigevent.sigev_signo = aio_sig_num;
388: acb->aiocb.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
389: acb->aiocb.aio_buf = buf;
390: if (nb_sectors < 0)
391: acb->aiocb.aio_nbytes = -nb_sectors;
392: else
393: acb->aiocb.aio_nbytes = nb_sectors * 512;
394: acb->aiocb.aio_offset = sector_num * 512;
395: acb->next = first_aio;
396: first_aio = acb;
397: return acb;
398: }
399:
400: static BlockDriverAIOCB *raw_aio_read(BlockDriverState *bs,
401: int64_t sector_num, uint8_t *buf, int nb_sectors,
402: BlockDriverCompletionFunc *cb, void *opaque)
403: {
404: RawAIOCB *acb;
405:
406: acb = raw_aio_setup(bs, sector_num, buf, nb_sectors, cb, opaque);
407: if (!acb)
408: return NULL;
409: if (aio_read(&acb->aiocb) < 0) {
410: qemu_aio_release(acb);
411: return NULL;
412: }
413: return &acb->common;
414: }
415:
416: static BlockDriverAIOCB *raw_aio_write(BlockDriverState *bs,
417: int64_t sector_num, const uint8_t *buf, int nb_sectors,
418: BlockDriverCompletionFunc *cb, void *opaque)
419: {
420: RawAIOCB *acb;
421:
422: acb = raw_aio_setup(bs, sector_num, (uint8_t*)buf, nb_sectors, cb, opaque);
423: if (!acb)
424: return NULL;
425: if (aio_write(&acb->aiocb) < 0) {
426: qemu_aio_release(acb);
427: return NULL;
428: }
429: return &acb->common;
430: }
431:
432: static void raw_aio_cancel(BlockDriverAIOCB *blockacb)
433: {
434: int ret;
435: RawAIOCB *acb = (RawAIOCB *)blockacb;
436: RawAIOCB **pacb;
437:
438: ret = aio_cancel(acb->aiocb.aio_fildes, &acb->aiocb);
439: if (ret == AIO_NOTCANCELED) {
440:
441:
442: while (aio_error(&acb->aiocb) == EINPROGRESS);
443: }
444:
445:
446: pacb = &first_aio;
447: for(;;) {
448: if (*pacb == NULL) {
449: break;
450: } else if (*pacb == acb) {
451: *pacb = acb->next;
452: qemu_aio_release(acb);
453: break;
454: }
455: pacb = &acb->next;
456: }
457: }
458:
459: static void raw_close(BlockDriverState *bs)
460: {
461: BDRVRawState *s = bs->opaque;
462: if (s->fd >= 0) {
463: close(s->fd);
464: s->fd = -1;
465: }
466: }
467:
468: static int raw_truncate(BlockDriverState *bs, int64_t offset)
469: {
470: BDRVRawState *s = bs->opaque;
471: if (s->type != FTYPE_FILE)
472: return -ENOTSUP;
473: if (ftruncate(s->fd, offset) < 0)
474: return -errno;
475: return 0;
476: }
477:
478: static int64_t raw_getlength(BlockDriverState *bs)
479: {
480: BDRVRawState *s = bs->opaque;
481: int fd = s->fd;
482: int64_t size;
483: #ifdef _BSD
484: struct stat sb;
485: #endif
486: #ifdef __sun__
487: struct dk_minfo minfo;
488: int rv;
489: #endif
490: int ret;
491:
492: ret = fd_open(bs);
493: if (ret < 0)
494: return ret;
495:
496: #ifdef _BSD
497: if (!fstat(fd, &sb) && (S_IFCHR & sb.st_mode)) {
498: #ifdef DIOCGMEDIASIZE
499: if (ioctl(fd, DIOCGMEDIASIZE, (off_t *)&size))
500: #endif
501: #ifdef CONFIG_COCOA
502: size = LONG_LONG_MAX;
503: #else
504: size = lseek(fd, 0LL, SEEK_END);
505: #endif
506: } else
507: #endif
508: #ifdef __sun__
509:
510:
511:
512: rv = ioctl ( fd, DKIOCGMEDIAINFO, &minfo );
513: if ( rv != -1 ) {
514: size = minfo.dki_lbsize * minfo.dki_capacity;
515: } else
516:
517:
518: #endif
519: {
520: size = lseek(fd, 0, SEEK_END);
521: }
522: return size;
523: }
524:
525: static int raw_create(const char *filename, int64_t total_size,
526: const char *backing_file, int flags)
527: {
528: int fd;
529:
530: if (flags || backing_file)
531: return -ENOTSUP;
532:
533: fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
534: 0644);
535: if (fd < 0)
536: return -EIO;
537: ftruncate(fd, total_size * 512);
538: close(fd);
539: return 0;
540: }
541:
542: static void raw_flush(BlockDriverState *bs)
543: {
544: BDRVRawState *s = bs->opaque;
545: fsync(s->fd);
546: }
547:
548: BlockDriver bdrv_raw = {
549: "raw",
550: sizeof(BDRVRawState),
551: NULL,
552: raw_open,
553: NULL,
554: NULL,
555: raw_close,
556: raw_create,
557: raw_flush,
558:
559: .bdrv_aio_read = raw_aio_read,
560: .bdrv_aio_write = raw_aio_write,
561: .bdrv_aio_cancel = raw_aio_cancel,
562: .aiocb_size = sizeof(RawAIOCB),
563: .protocol_name = "file",
564: .bdrv_pread = raw_pread,
565: .bdrv_pwrite = raw_pwrite,
566: .bdrv_truncate = raw_truncate,
567: .bdrv_getlength = raw_getlength,
568: };
569:
570:
571:
572:
573: #ifdef CONFIG_COCOA