common.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. /*
  2. * Copyright (C) 2005 Anthony Liguori <anthony@codemonkey.ws>
  3. *
  4. * Network Block Device Common Code
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; under version 2 of the License.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #include "qemu/osdep.h"
  19. #include "trace.h"
  20. #include "nbd-internal.h"
  21. /* Discard length bytes from channel. Return -errno on failure and 0 on
  22. * success */
  23. int nbd_drop(QIOChannel *ioc, size_t size, Error **errp)
  24. {
  25. ssize_t ret = 0;
  26. char small[1024];
  27. char *buffer;
  28. buffer = sizeof(small) >= size ? small : g_malloc(MIN(65536, size));
  29. while (size > 0) {
  30. ssize_t count = MIN(65536, size);
  31. ret = nbd_read(ioc, buffer, MIN(65536, size), NULL, errp);
  32. if (ret < 0) {
  33. goto cleanup;
  34. }
  35. size -= count;
  36. }
  37. cleanup:
  38. if (buffer != small) {
  39. g_free(buffer);
  40. }
  41. return ret;
  42. }
  43. void nbd_tls_handshake(QIOTask *task,
  44. void *opaque)
  45. {
  46. struct NBDTLSHandshakeData *data = opaque;
  47. qio_task_propagate_error(task, &data->error);
  48. data->complete = true;
  49. g_main_loop_quit(data->loop);
  50. }
  51. const char *nbd_opt_lookup(uint32_t opt)
  52. {
  53. switch (opt) {
  54. case NBD_OPT_EXPORT_NAME:
  55. return "export name";
  56. case NBD_OPT_ABORT:
  57. return "abort";
  58. case NBD_OPT_LIST:
  59. return "list";
  60. case NBD_OPT_STARTTLS:
  61. return "starttls";
  62. case NBD_OPT_INFO:
  63. return "info";
  64. case NBD_OPT_GO:
  65. return "go";
  66. case NBD_OPT_STRUCTURED_REPLY:
  67. return "structured reply";
  68. case NBD_OPT_LIST_META_CONTEXT:
  69. return "list meta context";
  70. case NBD_OPT_SET_META_CONTEXT:
  71. return "set meta context";
  72. default:
  73. return "<unknown>";
  74. }
  75. }
  76. const char *nbd_rep_lookup(uint32_t rep)
  77. {
  78. switch (rep) {
  79. case NBD_REP_ACK:
  80. return "ack";
  81. case NBD_REP_SERVER:
  82. return "server";
  83. case NBD_REP_INFO:
  84. return "info";
  85. case NBD_REP_META_CONTEXT:
  86. return "meta context";
  87. case NBD_REP_ERR_UNSUP:
  88. return "unsupported";
  89. case NBD_REP_ERR_POLICY:
  90. return "denied by policy";
  91. case NBD_REP_ERR_INVALID:
  92. return "invalid";
  93. case NBD_REP_ERR_PLATFORM:
  94. return "platform lacks support";
  95. case NBD_REP_ERR_TLS_REQD:
  96. return "TLS required";
  97. case NBD_REP_ERR_UNKNOWN:
  98. return "export unknown";
  99. case NBD_REP_ERR_SHUTDOWN:
  100. return "server shutting down";
  101. case NBD_REP_ERR_BLOCK_SIZE_REQD:
  102. return "block size required";
  103. default:
  104. return "<unknown>";
  105. }
  106. }
  107. const char *nbd_info_lookup(uint16_t info)
  108. {
  109. switch (info) {
  110. case NBD_INFO_EXPORT:
  111. return "export";
  112. case NBD_INFO_NAME:
  113. return "name";
  114. case NBD_INFO_DESCRIPTION:
  115. return "description";
  116. case NBD_INFO_BLOCK_SIZE:
  117. return "block size";
  118. default:
  119. return "<unknown>";
  120. }
  121. }
  122. const char *nbd_cmd_lookup(uint16_t cmd)
  123. {
  124. switch (cmd) {
  125. case NBD_CMD_READ:
  126. return "read";
  127. case NBD_CMD_WRITE:
  128. return "write";
  129. case NBD_CMD_DISC:
  130. return "disconnect";
  131. case NBD_CMD_FLUSH:
  132. return "flush";
  133. case NBD_CMD_TRIM:
  134. return "trim";
  135. case NBD_CMD_CACHE:
  136. return "cache";
  137. case NBD_CMD_WRITE_ZEROES:
  138. return "write zeroes";
  139. case NBD_CMD_BLOCK_STATUS:
  140. return "block status";
  141. default:
  142. return "<unknown>";
  143. }
  144. }
  145. const char *nbd_reply_type_lookup(uint16_t type)
  146. {
  147. switch (type) {
  148. case NBD_REPLY_TYPE_NONE:
  149. return "none";
  150. case NBD_REPLY_TYPE_OFFSET_DATA:
  151. return "data";
  152. case NBD_REPLY_TYPE_OFFSET_HOLE:
  153. return "hole";
  154. case NBD_REPLY_TYPE_BLOCK_STATUS:
  155. return "block status";
  156. case NBD_REPLY_TYPE_ERROR:
  157. return "generic error";
  158. case NBD_REPLY_TYPE_ERROR_OFFSET:
  159. return "error at offset";
  160. default:
  161. if (type & (1 << 15)) {
  162. return "<unknown error>";
  163. }
  164. return "<unknown>";
  165. }
  166. }
  167. const char *nbd_err_lookup(int err)
  168. {
  169. switch (err) {
  170. case NBD_SUCCESS:
  171. return "success";
  172. case NBD_EPERM:
  173. return "EPERM";
  174. case NBD_EIO:
  175. return "EIO";
  176. case NBD_ENOMEM:
  177. return "ENOMEM";
  178. case NBD_EINVAL:
  179. return "EINVAL";
  180. case NBD_ENOSPC:
  181. return "ENOSPC";
  182. case NBD_EOVERFLOW:
  183. return "EOVERFLOW";
  184. case NBD_ENOTSUP:
  185. return "ENOTSUP";
  186. case NBD_ESHUTDOWN:
  187. return "ESHUTDOWN";
  188. default:
  189. return "<unknown>";
  190. }
  191. }
  192. int nbd_errno_to_system_errno(int err)
  193. {
  194. int ret;
  195. switch (err) {
  196. case NBD_SUCCESS:
  197. ret = 0;
  198. break;
  199. case NBD_EPERM:
  200. ret = EPERM;
  201. break;
  202. case NBD_EIO:
  203. ret = EIO;
  204. break;
  205. case NBD_ENOMEM:
  206. ret = ENOMEM;
  207. break;
  208. case NBD_ENOSPC:
  209. ret = ENOSPC;
  210. break;
  211. case NBD_EOVERFLOW:
  212. ret = EOVERFLOW;
  213. break;
  214. case NBD_ENOTSUP:
  215. ret = ENOTSUP;
  216. break;
  217. case NBD_ESHUTDOWN:
  218. ret = ESHUTDOWN;
  219. break;
  220. default:
  221. trace_nbd_unknown_error(err);
  222. /* fallthrough */
  223. case NBD_EINVAL:
  224. ret = EINVAL;
  225. break;
  226. }
  227. return ret;
  228. }