2
0

channel-file.c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. /*
  2. * QEMU I/O channels files driver
  3. *
  4. * Copyright (c) 2015 Red Hat, Inc.
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2.1 of the License, or (at your option) any later version.
  10. *
  11. * This library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  18. *
  19. */
  20. #include "qemu/osdep.h"
  21. #include "io/channel-file.h"
  22. #include "io/channel-util.h"
  23. #include "io/channel-watch.h"
  24. #include "qapi/error.h"
  25. #include "qemu/module.h"
  26. #include "qemu/sockets.h"
  27. #include "trace.h"
  28. QIOChannelFile *
  29. qio_channel_file_new_fd(int fd)
  30. {
  31. QIOChannelFile *ioc;
  32. ioc = QIO_CHANNEL_FILE(object_new(TYPE_QIO_CHANNEL_FILE));
  33. ioc->fd = fd;
  34. if (lseek(fd, 0, SEEK_CUR) != (off_t)-1) {
  35. qio_channel_set_feature(QIO_CHANNEL(ioc), QIO_CHANNEL_FEATURE_SEEKABLE);
  36. }
  37. trace_qio_channel_file_new_fd(ioc, fd);
  38. return ioc;
  39. }
  40. QIOChannelFile *
  41. qio_channel_file_new_dupfd(int fd, Error **errp)
  42. {
  43. int newfd = dup(fd);
  44. if (newfd < 0) {
  45. error_setg_errno(errp, errno, "Could not dup FD %d", fd);
  46. return NULL;
  47. }
  48. return qio_channel_file_new_fd(newfd);
  49. }
  50. QIOChannelFile *
  51. qio_channel_file_new_path(const char *path,
  52. int flags,
  53. mode_t mode,
  54. Error **errp)
  55. {
  56. QIOChannelFile *ioc;
  57. ioc = QIO_CHANNEL_FILE(object_new(TYPE_QIO_CHANNEL_FILE));
  58. if (flags & O_CREAT) {
  59. ioc->fd = qemu_create(path, flags & ~O_CREAT, mode, errp);
  60. } else {
  61. ioc->fd = qemu_open(path, flags, errp);
  62. }
  63. if (ioc->fd < 0) {
  64. object_unref(OBJECT(ioc));
  65. return NULL;
  66. }
  67. if (lseek(ioc->fd, 0, SEEK_CUR) != (off_t)-1) {
  68. qio_channel_set_feature(QIO_CHANNEL(ioc), QIO_CHANNEL_FEATURE_SEEKABLE);
  69. }
  70. trace_qio_channel_file_new_path(ioc, path, flags, mode, ioc->fd);
  71. return ioc;
  72. }
  73. static void qio_channel_file_init(Object *obj)
  74. {
  75. QIOChannelFile *ioc = QIO_CHANNEL_FILE(obj);
  76. ioc->fd = -1;
  77. }
  78. static void qio_channel_file_finalize(Object *obj)
  79. {
  80. QIOChannelFile *ioc = QIO_CHANNEL_FILE(obj);
  81. if (ioc->fd != -1) {
  82. qemu_close(ioc->fd);
  83. ioc->fd = -1;
  84. }
  85. }
  86. static ssize_t qio_channel_file_readv(QIOChannel *ioc,
  87. const struct iovec *iov,
  88. size_t niov,
  89. int **fds,
  90. size_t *nfds,
  91. int flags,
  92. Error **errp)
  93. {
  94. QIOChannelFile *fioc = QIO_CHANNEL_FILE(ioc);
  95. ssize_t ret;
  96. retry:
  97. ret = readv(fioc->fd, iov, niov);
  98. if (ret < 0) {
  99. if (errno == EAGAIN) {
  100. return QIO_CHANNEL_ERR_BLOCK;
  101. }
  102. if (errno == EINTR) {
  103. goto retry;
  104. }
  105. error_setg_errno(errp, errno,
  106. "Unable to read from file");
  107. return -1;
  108. }
  109. return ret;
  110. }
  111. static ssize_t qio_channel_file_writev(QIOChannel *ioc,
  112. const struct iovec *iov,
  113. size_t niov,
  114. int *fds,
  115. size_t nfds,
  116. int flags,
  117. Error **errp)
  118. {
  119. QIOChannelFile *fioc = QIO_CHANNEL_FILE(ioc);
  120. ssize_t ret;
  121. retry:
  122. ret = writev(fioc->fd, iov, niov);
  123. if (ret <= 0) {
  124. if (errno == EAGAIN) {
  125. return QIO_CHANNEL_ERR_BLOCK;
  126. }
  127. if (errno == EINTR) {
  128. goto retry;
  129. }
  130. error_setg_errno(errp, errno,
  131. "Unable to write to file");
  132. return -1;
  133. }
  134. return ret;
  135. }
  136. #ifdef CONFIG_PREADV
  137. static ssize_t qio_channel_file_preadv(QIOChannel *ioc,
  138. const struct iovec *iov,
  139. size_t niov,
  140. off_t offset,
  141. Error **errp)
  142. {
  143. QIOChannelFile *fioc = QIO_CHANNEL_FILE(ioc);
  144. ssize_t ret;
  145. retry:
  146. ret = preadv(fioc->fd, iov, niov, offset);
  147. if (ret < 0) {
  148. if (errno == EAGAIN) {
  149. return QIO_CHANNEL_ERR_BLOCK;
  150. }
  151. if (errno == EINTR) {
  152. goto retry;
  153. }
  154. error_setg_errno(errp, errno, "Unable to read from file");
  155. return -1;
  156. }
  157. return ret;
  158. }
  159. static ssize_t qio_channel_file_pwritev(QIOChannel *ioc,
  160. const struct iovec *iov,
  161. size_t niov,
  162. off_t offset,
  163. Error **errp)
  164. {
  165. QIOChannelFile *fioc = QIO_CHANNEL_FILE(ioc);
  166. ssize_t ret;
  167. retry:
  168. ret = pwritev(fioc->fd, iov, niov, offset);
  169. if (ret <= 0) {
  170. if (errno == EAGAIN) {
  171. return QIO_CHANNEL_ERR_BLOCK;
  172. }
  173. if (errno == EINTR) {
  174. goto retry;
  175. }
  176. error_setg_errno(errp, errno, "Unable to write to file");
  177. return -1;
  178. }
  179. return ret;
  180. }
  181. #endif /* CONFIG_PREADV */
  182. static int qio_channel_file_set_blocking(QIOChannel *ioc,
  183. bool enabled,
  184. Error **errp)
  185. {
  186. #ifdef WIN32
  187. /* not implemented */
  188. error_setg_errno(errp, errno, "Failed to set FD nonblocking");
  189. return -1;
  190. #else
  191. QIOChannelFile *fioc = QIO_CHANNEL_FILE(ioc);
  192. if (!g_unix_set_fd_nonblocking(fioc->fd, !enabled, NULL)) {
  193. error_setg_errno(errp, errno, "Failed to set FD nonblocking");
  194. return -1;
  195. }
  196. return 0;
  197. #endif
  198. }
  199. static off_t qio_channel_file_seek(QIOChannel *ioc,
  200. off_t offset,
  201. int whence,
  202. Error **errp)
  203. {
  204. QIOChannelFile *fioc = QIO_CHANNEL_FILE(ioc);
  205. off_t ret;
  206. ret = lseek(fioc->fd, offset, whence);
  207. if (ret == (off_t)-1) {
  208. error_setg_errno(errp, errno,
  209. "Unable to seek to offset %lld whence %d in file",
  210. (long long int)offset, whence);
  211. return -1;
  212. }
  213. return ret;
  214. }
  215. static int qio_channel_file_close(QIOChannel *ioc,
  216. Error **errp)
  217. {
  218. QIOChannelFile *fioc = QIO_CHANNEL_FILE(ioc);
  219. if (qemu_close(fioc->fd) < 0) {
  220. error_setg_errno(errp, errno,
  221. "Unable to close file");
  222. return -1;
  223. }
  224. fioc->fd = -1;
  225. return 0;
  226. }
  227. static void qio_channel_file_set_aio_fd_handler(QIOChannel *ioc,
  228. AioContext *read_ctx,
  229. IOHandler *io_read,
  230. AioContext *write_ctx,
  231. IOHandler *io_write,
  232. void *opaque)
  233. {
  234. QIOChannelFile *fioc = QIO_CHANNEL_FILE(ioc);
  235. qio_channel_util_set_aio_fd_handler(fioc->fd, read_ctx, io_read,
  236. fioc->fd, write_ctx, io_write,
  237. opaque);
  238. }
  239. static GSource *qio_channel_file_create_watch(QIOChannel *ioc,
  240. GIOCondition condition)
  241. {
  242. QIOChannelFile *fioc = QIO_CHANNEL_FILE(ioc);
  243. return qio_channel_create_fd_watch(ioc,
  244. fioc->fd,
  245. condition);
  246. }
  247. static void qio_channel_file_class_init(ObjectClass *klass,
  248. void *class_data G_GNUC_UNUSED)
  249. {
  250. QIOChannelClass *ioc_klass = QIO_CHANNEL_CLASS(klass);
  251. ioc_klass->io_writev = qio_channel_file_writev;
  252. ioc_klass->io_readv = qio_channel_file_readv;
  253. ioc_klass->io_set_blocking = qio_channel_file_set_blocking;
  254. #ifdef CONFIG_PREADV
  255. ioc_klass->io_pwritev = qio_channel_file_pwritev;
  256. ioc_klass->io_preadv = qio_channel_file_preadv;
  257. #endif
  258. ioc_klass->io_seek = qio_channel_file_seek;
  259. ioc_klass->io_close = qio_channel_file_close;
  260. ioc_klass->io_create_watch = qio_channel_file_create_watch;
  261. ioc_klass->io_set_aio_fd_handler = qio_channel_file_set_aio_fd_handler;
  262. }
  263. static const TypeInfo qio_channel_file_info = {
  264. .parent = TYPE_QIO_CHANNEL,
  265. .name = TYPE_QIO_CHANNEL_FILE,
  266. .instance_size = sizeof(QIOChannelFile),
  267. .instance_init = qio_channel_file_init,
  268. .instance_finalize = qio_channel_file_finalize,
  269. .class_init = qio_channel_file_class_init,
  270. };
  271. static void qio_channel_file_register_types(void)
  272. {
  273. type_register_static(&qio_channel_file_info);
  274. }
  275. type_init(qio_channel_file_register_types);