2
0

qemu-file.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835
  1. #include "qemu-common.h"
  2. #include "qemu/iov.h"
  3. #include "qemu/sockets.h"
  4. #include "block/coroutine.h"
  5. #include "migration/migration.h"
  6. #include "migration/qemu-file.h"
  7. #include "trace.h"
  8. #define IO_BUF_SIZE 32768
  9. #define MAX_IOV_SIZE MIN(IOV_MAX, 64)
  10. struct QEMUFile {
  11. const QEMUFileOps *ops;
  12. void *opaque;
  13. int64_t bytes_xfer;
  14. int64_t xfer_limit;
  15. int64_t pos; /* start of buffer when writing, end of buffer
  16. when reading */
  17. int buf_index;
  18. int buf_size; /* 0 when writing */
  19. uint8_t buf[IO_BUF_SIZE];
  20. struct iovec iov[MAX_IOV_SIZE];
  21. unsigned int iovcnt;
  22. int last_error;
  23. };
  24. typedef struct QEMUFileStdio {
  25. FILE *stdio_file;
  26. QEMUFile *file;
  27. } QEMUFileStdio;
  28. typedef struct QEMUFileSocket {
  29. int fd;
  30. QEMUFile *file;
  31. } QEMUFileSocket;
  32. static ssize_t socket_writev_buffer(void *opaque, struct iovec *iov, int iovcnt,
  33. int64_t pos)
  34. {
  35. QEMUFileSocket *s = opaque;
  36. ssize_t len;
  37. ssize_t size = iov_size(iov, iovcnt);
  38. len = iov_send(s->fd, iov, iovcnt, 0, size);
  39. if (len < size) {
  40. len = -socket_error();
  41. }
  42. return len;
  43. }
  44. static int socket_get_fd(void *opaque)
  45. {
  46. QEMUFileSocket *s = opaque;
  47. return s->fd;
  48. }
  49. static int socket_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
  50. {
  51. QEMUFileSocket *s = opaque;
  52. ssize_t len;
  53. for (;;) {
  54. len = qemu_recv(s->fd, buf, size, 0);
  55. if (len != -1) {
  56. break;
  57. }
  58. if (socket_error() == EAGAIN) {
  59. yield_until_fd_readable(s->fd);
  60. } else if (socket_error() != EINTR) {
  61. break;
  62. }
  63. }
  64. if (len == -1) {
  65. len = -socket_error();
  66. }
  67. return len;
  68. }
  69. static int socket_close(void *opaque)
  70. {
  71. QEMUFileSocket *s = opaque;
  72. closesocket(s->fd);
  73. g_free(s);
  74. return 0;
  75. }
  76. static int stdio_get_fd(void *opaque)
  77. {
  78. QEMUFileStdio *s = opaque;
  79. return fileno(s->stdio_file);
  80. }
  81. static int stdio_put_buffer(void *opaque, const uint8_t *buf, int64_t pos,
  82. int size)
  83. {
  84. QEMUFileStdio *s = opaque;
  85. int res;
  86. res = fwrite(buf, 1, size, s->stdio_file);
  87. if (res != size) {
  88. return -errno;
  89. }
  90. return res;
  91. }
  92. static int stdio_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
  93. {
  94. QEMUFileStdio *s = opaque;
  95. FILE *fp = s->stdio_file;
  96. int bytes;
  97. for (;;) {
  98. clearerr(fp);
  99. bytes = fread(buf, 1, size, fp);
  100. if (bytes != 0 || !ferror(fp)) {
  101. break;
  102. }
  103. if (errno == EAGAIN) {
  104. yield_until_fd_readable(fileno(fp));
  105. } else if (errno != EINTR) {
  106. break;
  107. }
  108. }
  109. return bytes;
  110. }
  111. static int stdio_pclose(void *opaque)
  112. {
  113. QEMUFileStdio *s = opaque;
  114. int ret;
  115. ret = pclose(s->stdio_file);
  116. if (ret == -1) {
  117. ret = -errno;
  118. } else if (!WIFEXITED(ret) || WEXITSTATUS(ret) != 0) {
  119. /* close succeeded, but non-zero exit code: */
  120. ret = -EIO; /* fake errno value */
  121. }
  122. g_free(s);
  123. return ret;
  124. }
  125. static int stdio_fclose(void *opaque)
  126. {
  127. QEMUFileStdio *s = opaque;
  128. int ret = 0;
  129. if (s->file->ops->put_buffer || s->file->ops->writev_buffer) {
  130. int fd = fileno(s->stdio_file);
  131. struct stat st;
  132. ret = fstat(fd, &st);
  133. if (ret == 0 && S_ISREG(st.st_mode)) {
  134. /*
  135. * If the file handle is a regular file make sure the
  136. * data is flushed to disk before signaling success.
  137. */
  138. ret = fsync(fd);
  139. if (ret != 0) {
  140. ret = -errno;
  141. return ret;
  142. }
  143. }
  144. }
  145. if (fclose(s->stdio_file) == EOF) {
  146. ret = -errno;
  147. }
  148. g_free(s);
  149. return ret;
  150. }
  151. static const QEMUFileOps stdio_pipe_read_ops = {
  152. .get_fd = stdio_get_fd,
  153. .get_buffer = stdio_get_buffer,
  154. .close = stdio_pclose
  155. };
  156. static const QEMUFileOps stdio_pipe_write_ops = {
  157. .get_fd = stdio_get_fd,
  158. .put_buffer = stdio_put_buffer,
  159. .close = stdio_pclose
  160. };
  161. QEMUFile *qemu_popen_cmd(const char *command, const char *mode)
  162. {
  163. FILE *stdio_file;
  164. QEMUFileStdio *s;
  165. if (mode == NULL || (mode[0] != 'r' && mode[0] != 'w') || mode[1] != 0) {
  166. fprintf(stderr, "qemu_popen: Argument validity check failed\n");
  167. return NULL;
  168. }
  169. stdio_file = popen(command, mode);
  170. if (stdio_file == NULL) {
  171. return NULL;
  172. }
  173. s = g_malloc0(sizeof(QEMUFileStdio));
  174. s->stdio_file = stdio_file;
  175. if (mode[0] == 'r') {
  176. s->file = qemu_fopen_ops(s, &stdio_pipe_read_ops);
  177. } else {
  178. s->file = qemu_fopen_ops(s, &stdio_pipe_write_ops);
  179. }
  180. return s->file;
  181. }
  182. static const QEMUFileOps stdio_file_read_ops = {
  183. .get_fd = stdio_get_fd,
  184. .get_buffer = stdio_get_buffer,
  185. .close = stdio_fclose
  186. };
  187. static const QEMUFileOps stdio_file_write_ops = {
  188. .get_fd = stdio_get_fd,
  189. .put_buffer = stdio_put_buffer,
  190. .close = stdio_fclose
  191. };
  192. static ssize_t unix_writev_buffer(void *opaque, struct iovec *iov, int iovcnt,
  193. int64_t pos)
  194. {
  195. QEMUFileSocket *s = opaque;
  196. ssize_t len, offset;
  197. ssize_t size = iov_size(iov, iovcnt);
  198. ssize_t total = 0;
  199. assert(iovcnt > 0);
  200. offset = 0;
  201. while (size > 0) {
  202. /* Find the next start position; skip all full-sized vector elements */
  203. while (offset >= iov[0].iov_len) {
  204. offset -= iov[0].iov_len;
  205. iov++, iovcnt--;
  206. }
  207. /* skip `offset' bytes from the (now) first element, undo it on exit */
  208. assert(iovcnt > 0);
  209. iov[0].iov_base += offset;
  210. iov[0].iov_len -= offset;
  211. do {
  212. len = writev(s->fd, iov, iovcnt);
  213. } while (len == -1 && errno == EINTR);
  214. if (len == -1) {
  215. return -errno;
  216. }
  217. /* Undo the changes above */
  218. iov[0].iov_base -= offset;
  219. iov[0].iov_len += offset;
  220. /* Prepare for the next iteration */
  221. offset += len;
  222. total += len;
  223. size -= len;
  224. }
  225. return total;
  226. }
  227. static int unix_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
  228. {
  229. QEMUFileSocket *s = opaque;
  230. ssize_t len;
  231. for (;;) {
  232. len = read(s->fd, buf, size);
  233. if (len != -1) {
  234. break;
  235. }
  236. if (errno == EAGAIN) {
  237. yield_until_fd_readable(s->fd);
  238. } else if (errno != EINTR) {
  239. break;
  240. }
  241. }
  242. if (len == -1) {
  243. len = -errno;
  244. }
  245. return len;
  246. }
  247. static int unix_close(void *opaque)
  248. {
  249. QEMUFileSocket *s = opaque;
  250. close(s->fd);
  251. g_free(s);
  252. return 0;
  253. }
  254. static const QEMUFileOps unix_read_ops = {
  255. .get_fd = socket_get_fd,
  256. .get_buffer = unix_get_buffer,
  257. .close = unix_close
  258. };
  259. static const QEMUFileOps unix_write_ops = {
  260. .get_fd = socket_get_fd,
  261. .writev_buffer = unix_writev_buffer,
  262. .close = unix_close
  263. };
  264. QEMUFile *qemu_fdopen(int fd, const char *mode)
  265. {
  266. QEMUFileSocket *s;
  267. if (mode == NULL ||
  268. (mode[0] != 'r' && mode[0] != 'w') ||
  269. mode[1] != 'b' || mode[2] != 0) {
  270. fprintf(stderr, "qemu_fdopen: Argument validity check failed\n");
  271. return NULL;
  272. }
  273. s = g_malloc0(sizeof(QEMUFileSocket));
  274. s->fd = fd;
  275. if (mode[0] == 'r') {
  276. s->file = qemu_fopen_ops(s, &unix_read_ops);
  277. } else {
  278. s->file = qemu_fopen_ops(s, &unix_write_ops);
  279. }
  280. return s->file;
  281. }
  282. static const QEMUFileOps socket_read_ops = {
  283. .get_fd = socket_get_fd,
  284. .get_buffer = socket_get_buffer,
  285. .close = socket_close
  286. };
  287. static const QEMUFileOps socket_write_ops = {
  288. .get_fd = socket_get_fd,
  289. .writev_buffer = socket_writev_buffer,
  290. .close = socket_close
  291. };
  292. bool qemu_file_mode_is_not_valid(const char *mode)
  293. {
  294. if (mode == NULL ||
  295. (mode[0] != 'r' && mode[0] != 'w') ||
  296. mode[1] != 'b' || mode[2] != 0) {
  297. fprintf(stderr, "qemu_fopen: Argument validity check failed\n");
  298. return true;
  299. }
  300. return false;
  301. }
  302. QEMUFile *qemu_fopen_socket(int fd, const char *mode)
  303. {
  304. QEMUFileSocket *s;
  305. if (qemu_file_mode_is_not_valid(mode)) {
  306. return NULL;
  307. }
  308. s = g_malloc0(sizeof(QEMUFileSocket));
  309. s->fd = fd;
  310. if (mode[0] == 'w') {
  311. qemu_set_block(s->fd);
  312. s->file = qemu_fopen_ops(s, &socket_write_ops);
  313. } else {
  314. s->file = qemu_fopen_ops(s, &socket_read_ops);
  315. }
  316. return s->file;
  317. }
  318. QEMUFile *qemu_fopen(const char *filename, const char *mode)
  319. {
  320. QEMUFileStdio *s;
  321. if (qemu_file_mode_is_not_valid(mode)) {
  322. return NULL;
  323. }
  324. s = g_malloc0(sizeof(QEMUFileStdio));
  325. s->stdio_file = fopen(filename, mode);
  326. if (!s->stdio_file) {
  327. goto fail;
  328. }
  329. if (mode[0] == 'w') {
  330. s->file = qemu_fopen_ops(s, &stdio_file_write_ops);
  331. } else {
  332. s->file = qemu_fopen_ops(s, &stdio_file_read_ops);
  333. }
  334. return s->file;
  335. fail:
  336. g_free(s);
  337. return NULL;
  338. }
  339. QEMUFile *qemu_fopen_ops(void *opaque, const QEMUFileOps *ops)
  340. {
  341. QEMUFile *f;
  342. f = g_malloc0(sizeof(QEMUFile));
  343. f->opaque = opaque;
  344. f->ops = ops;
  345. return f;
  346. }
  347. /*
  348. * Get last error for stream f
  349. *
  350. * Return negative error value if there has been an error on previous
  351. * operations, return 0 if no error happened.
  352. *
  353. */
  354. int qemu_file_get_error(QEMUFile *f)
  355. {
  356. return f->last_error;
  357. }
  358. void qemu_file_set_error(QEMUFile *f, int ret)
  359. {
  360. if (f->last_error == 0) {
  361. f->last_error = ret;
  362. }
  363. }
  364. static inline bool qemu_file_is_writable(QEMUFile *f)
  365. {
  366. return f->ops->writev_buffer || f->ops->put_buffer;
  367. }
  368. /**
  369. * Flushes QEMUFile buffer
  370. *
  371. * If there is writev_buffer QEMUFileOps it uses it otherwise uses
  372. * put_buffer ops.
  373. */
  374. void qemu_fflush(QEMUFile *f)
  375. {
  376. ssize_t ret = 0;
  377. if (!qemu_file_is_writable(f)) {
  378. return;
  379. }
  380. if (f->ops->writev_buffer) {
  381. if (f->iovcnt > 0) {
  382. ret = f->ops->writev_buffer(f->opaque, f->iov, f->iovcnt, f->pos);
  383. }
  384. } else {
  385. if (f->buf_index > 0) {
  386. ret = f->ops->put_buffer(f->opaque, f->buf, f->pos, f->buf_index);
  387. }
  388. }
  389. if (ret >= 0) {
  390. f->pos += ret;
  391. }
  392. f->buf_index = 0;
  393. f->iovcnt = 0;
  394. if (ret < 0) {
  395. qemu_file_set_error(f, ret);
  396. }
  397. }
  398. void ram_control_before_iterate(QEMUFile *f, uint64_t flags)
  399. {
  400. int ret = 0;
  401. if (f->ops->before_ram_iterate) {
  402. ret = f->ops->before_ram_iterate(f, f->opaque, flags);
  403. if (ret < 0) {
  404. qemu_file_set_error(f, ret);
  405. }
  406. }
  407. }
  408. void ram_control_after_iterate(QEMUFile *f, uint64_t flags)
  409. {
  410. int ret = 0;
  411. if (f->ops->after_ram_iterate) {
  412. ret = f->ops->after_ram_iterate(f, f->opaque, flags);
  413. if (ret < 0) {
  414. qemu_file_set_error(f, ret);
  415. }
  416. }
  417. }
  418. void ram_control_load_hook(QEMUFile *f, uint64_t flags)
  419. {
  420. int ret = -EINVAL;
  421. if (f->ops->hook_ram_load) {
  422. ret = f->ops->hook_ram_load(f, f->opaque, flags);
  423. if (ret < 0) {
  424. qemu_file_set_error(f, ret);
  425. }
  426. } else {
  427. qemu_file_set_error(f, ret);
  428. }
  429. }
  430. size_t ram_control_save_page(QEMUFile *f, ram_addr_t block_offset,
  431. ram_addr_t offset, size_t size, int *bytes_sent)
  432. {
  433. if (f->ops->save_page) {
  434. int ret = f->ops->save_page(f, f->opaque, block_offset,
  435. offset, size, bytes_sent);
  436. if (ret != RAM_SAVE_CONTROL_DELAYED) {
  437. if (bytes_sent && *bytes_sent > 0) {
  438. qemu_update_position(f, *bytes_sent);
  439. } else if (ret < 0) {
  440. qemu_file_set_error(f, ret);
  441. }
  442. }
  443. return ret;
  444. }
  445. return RAM_SAVE_CONTROL_NOT_SUPP;
  446. }
  447. static void qemu_fill_buffer(QEMUFile *f)
  448. {
  449. int len;
  450. int pending;
  451. assert(!qemu_file_is_writable(f));
  452. pending = f->buf_size - f->buf_index;
  453. if (pending > 0) {
  454. memmove(f->buf, f->buf + f->buf_index, pending);
  455. }
  456. f->buf_index = 0;
  457. f->buf_size = pending;
  458. len = f->ops->get_buffer(f->opaque, f->buf + pending, f->pos,
  459. IO_BUF_SIZE - pending);
  460. if (len > 0) {
  461. f->buf_size += len;
  462. f->pos += len;
  463. } else if (len == 0) {
  464. qemu_file_set_error(f, -EIO);
  465. } else if (len != -EAGAIN) {
  466. qemu_file_set_error(f, len);
  467. }
  468. }
  469. int qemu_get_fd(QEMUFile *f)
  470. {
  471. if (f->ops->get_fd) {
  472. return f->ops->get_fd(f->opaque);
  473. }
  474. return -1;
  475. }
  476. void qemu_update_position(QEMUFile *f, size_t size)
  477. {
  478. f->pos += size;
  479. }
  480. /** Closes the file
  481. *
  482. * Returns negative error value if any error happened on previous operations or
  483. * while closing the file. Returns 0 or positive number on success.
  484. *
  485. * The meaning of return value on success depends on the specific backend
  486. * being used.
  487. */
  488. int qemu_fclose(QEMUFile *f)
  489. {
  490. int ret;
  491. qemu_fflush(f);
  492. ret = qemu_file_get_error(f);
  493. if (f->ops->close) {
  494. int ret2 = f->ops->close(f->opaque);
  495. if (ret >= 0) {
  496. ret = ret2;
  497. }
  498. }
  499. /* If any error was spotted before closing, we should report it
  500. * instead of the close() return value.
  501. */
  502. if (f->last_error) {
  503. ret = f->last_error;
  504. }
  505. g_free(f);
  506. trace_qemu_file_fclose();
  507. return ret;
  508. }
  509. static void add_to_iovec(QEMUFile *f, const uint8_t *buf, int size)
  510. {
  511. /* check for adjacent buffer and coalesce them */
  512. if (f->iovcnt > 0 && buf == f->iov[f->iovcnt - 1].iov_base +
  513. f->iov[f->iovcnt - 1].iov_len) {
  514. f->iov[f->iovcnt - 1].iov_len += size;
  515. } else {
  516. f->iov[f->iovcnt].iov_base = (uint8_t *)buf;
  517. f->iov[f->iovcnt++].iov_len = size;
  518. }
  519. if (f->iovcnt >= MAX_IOV_SIZE) {
  520. qemu_fflush(f);
  521. }
  522. }
  523. void qemu_put_buffer_async(QEMUFile *f, const uint8_t *buf, int size)
  524. {
  525. if (!f->ops->writev_buffer) {
  526. qemu_put_buffer(f, buf, size);
  527. return;
  528. }
  529. if (f->last_error) {
  530. return;
  531. }
  532. f->bytes_xfer += size;
  533. add_to_iovec(f, buf, size);
  534. }
  535. void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size)
  536. {
  537. int l;
  538. if (f->last_error) {
  539. return;
  540. }
  541. while (size > 0) {
  542. l = IO_BUF_SIZE - f->buf_index;
  543. if (l > size) {
  544. l = size;
  545. }
  546. memcpy(f->buf + f->buf_index, buf, l);
  547. f->bytes_xfer += l;
  548. if (f->ops->writev_buffer) {
  549. add_to_iovec(f, f->buf + f->buf_index, l);
  550. }
  551. f->buf_index += l;
  552. if (f->buf_index == IO_BUF_SIZE) {
  553. qemu_fflush(f);
  554. }
  555. if (qemu_file_get_error(f)) {
  556. break;
  557. }
  558. buf += l;
  559. size -= l;
  560. }
  561. }
  562. void qemu_put_byte(QEMUFile *f, int v)
  563. {
  564. if (f->last_error) {
  565. return;
  566. }
  567. f->buf[f->buf_index] = v;
  568. f->bytes_xfer++;
  569. if (f->ops->writev_buffer) {
  570. add_to_iovec(f, f->buf + f->buf_index, 1);
  571. }
  572. f->buf_index++;
  573. if (f->buf_index == IO_BUF_SIZE) {
  574. qemu_fflush(f);
  575. }
  576. }
  577. void qemu_file_skip(QEMUFile *f, int size)
  578. {
  579. if (f->buf_index + size <= f->buf_size) {
  580. f->buf_index += size;
  581. }
  582. }
  583. int qemu_peek_buffer(QEMUFile *f, uint8_t *buf, int size, size_t offset)
  584. {
  585. int pending;
  586. int index;
  587. assert(!qemu_file_is_writable(f));
  588. index = f->buf_index + offset;
  589. pending = f->buf_size - index;
  590. if (pending < size) {
  591. qemu_fill_buffer(f);
  592. index = f->buf_index + offset;
  593. pending = f->buf_size - index;
  594. }
  595. if (pending <= 0) {
  596. return 0;
  597. }
  598. if (size > pending) {
  599. size = pending;
  600. }
  601. memcpy(buf, f->buf + index, size);
  602. return size;
  603. }
  604. int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size)
  605. {
  606. int pending = size;
  607. int done = 0;
  608. while (pending > 0) {
  609. int res;
  610. res = qemu_peek_buffer(f, buf, pending, 0);
  611. if (res == 0) {
  612. return done;
  613. }
  614. qemu_file_skip(f, res);
  615. buf += res;
  616. pending -= res;
  617. done += res;
  618. }
  619. return done;
  620. }
  621. int qemu_peek_byte(QEMUFile *f, int offset)
  622. {
  623. int index = f->buf_index + offset;
  624. assert(!qemu_file_is_writable(f));
  625. if (index >= f->buf_size) {
  626. qemu_fill_buffer(f);
  627. index = f->buf_index + offset;
  628. if (index >= f->buf_size) {
  629. return 0;
  630. }
  631. }
  632. return f->buf[index];
  633. }
  634. int qemu_get_byte(QEMUFile *f)
  635. {
  636. int result;
  637. result = qemu_peek_byte(f, 0);
  638. qemu_file_skip(f, 1);
  639. return result;
  640. }
  641. int64_t qemu_ftell(QEMUFile *f)
  642. {
  643. qemu_fflush(f);
  644. return f->pos;
  645. }
  646. int qemu_file_rate_limit(QEMUFile *f)
  647. {
  648. if (qemu_file_get_error(f)) {
  649. return 1;
  650. }
  651. if (f->xfer_limit > 0 && f->bytes_xfer > f->xfer_limit) {
  652. return 1;
  653. }
  654. return 0;
  655. }
  656. int64_t qemu_file_get_rate_limit(QEMUFile *f)
  657. {
  658. return f->xfer_limit;
  659. }
  660. void qemu_file_set_rate_limit(QEMUFile *f, int64_t limit)
  661. {
  662. f->xfer_limit = limit;
  663. }
  664. void qemu_file_reset_rate_limit(QEMUFile *f)
  665. {
  666. f->bytes_xfer = 0;
  667. }
  668. void qemu_put_be16(QEMUFile *f, unsigned int v)
  669. {
  670. qemu_put_byte(f, v >> 8);
  671. qemu_put_byte(f, v);
  672. }
  673. void qemu_put_be32(QEMUFile *f, unsigned int v)
  674. {
  675. qemu_put_byte(f, v >> 24);
  676. qemu_put_byte(f, v >> 16);
  677. qemu_put_byte(f, v >> 8);
  678. qemu_put_byte(f, v);
  679. }
  680. void qemu_put_be64(QEMUFile *f, uint64_t v)
  681. {
  682. qemu_put_be32(f, v >> 32);
  683. qemu_put_be32(f, v);
  684. }
  685. unsigned int qemu_get_be16(QEMUFile *f)
  686. {
  687. unsigned int v;
  688. v = qemu_get_byte(f) << 8;
  689. v |= qemu_get_byte(f);
  690. return v;
  691. }
  692. unsigned int qemu_get_be32(QEMUFile *f)
  693. {
  694. unsigned int v;
  695. v = qemu_get_byte(f) << 24;
  696. v |= qemu_get_byte(f) << 16;
  697. v |= qemu_get_byte(f) << 8;
  698. v |= qemu_get_byte(f);
  699. return v;
  700. }
  701. uint64_t qemu_get_be64(QEMUFile *f)
  702. {
  703. uint64_t v;
  704. v = (uint64_t)qemu_get_be32(f) << 32;
  705. v |= qemu_get_be32(f);
  706. return v;
  707. }