Skip to content

Commit 7f5b50a

Browse files
Fabiano Rosasxzpeter
Fabiano Rosas
authored andcommitted
migration/qemu-file: add utility methods for working with seekable channels
Add utility methods that will be needed when implementing 'mapped-ram' migration capability. Signed-off-by: Fabiano Rosas <[email protected]> Reviewed-by: "Daniel P. Berrangé" <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Peter Xu <[email protected]>
1 parent c05dfcb commit 7f5b50a

File tree

3 files changed

+114
-0
lines changed

3 files changed

+114
-0
lines changed

include/migration/qemu-file-types.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ unsigned int qemu_get_be16(QEMUFile *f);
5050
unsigned int qemu_get_be32(QEMUFile *f);
5151
uint64_t qemu_get_be64(QEMUFile *f);
5252

53+
bool qemu_file_is_seekable(QEMUFile *f);
54+
5355
static inline void qemu_put_be64s(QEMUFile *f, const uint64_t *pv)
5456
{
5557
qemu_put_be64(f, *pv);

migration/qemu-file.c

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "options.h"
3434
#include "qapi/error.h"
3535
#include "rdma.h"
36+
#include "io/channel-file.h"
3637

3738
#define IO_BUF_SIZE 32768
3839
#define MAX_IOV_SIZE MIN_CONST(IOV_MAX, 64)
@@ -255,6 +256,10 @@ static void qemu_iovec_release_ram(QEMUFile *f)
255256
memset(f->may_free, 0, sizeof(f->may_free));
256257
}
257258

259+
bool qemu_file_is_seekable(QEMUFile *f)
260+
{
261+
return qio_channel_has_feature(f->ioc, QIO_CHANNEL_FEATURE_SEEKABLE);
262+
}
258263

259264
/**
260265
* Flushes QEMUFile buffer
@@ -447,6 +452,107 @@ void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, size_t size)
447452
}
448453
}
449454

455+
void qemu_put_buffer_at(QEMUFile *f, const uint8_t *buf, size_t buflen,
456+
off_t pos)
457+
{
458+
Error *err = NULL;
459+
size_t ret;
460+
461+
if (f->last_error) {
462+
return;
463+
}
464+
465+
qemu_fflush(f);
466+
ret = qio_channel_pwrite(f->ioc, (char *)buf, buflen, pos, &err);
467+
468+
if (err) {
469+
qemu_file_set_error_obj(f, -EIO, err);
470+
return;
471+
}
472+
473+
if ((ssize_t)ret == QIO_CHANNEL_ERR_BLOCK) {
474+
qemu_file_set_error_obj(f, -EAGAIN, NULL);
475+
return;
476+
}
477+
478+
if (ret != buflen) {
479+
error_setg(&err, "Partial write of size %zu, expected %zu", ret,
480+
buflen);
481+
qemu_file_set_error_obj(f, -EIO, err);
482+
return;
483+
}
484+
485+
stat64_add(&mig_stats.qemu_file_transferred, buflen);
486+
487+
return;
488+
}
489+
490+
491+
size_t qemu_get_buffer_at(QEMUFile *f, const uint8_t *buf, size_t buflen,
492+
off_t pos)
493+
{
494+
Error *err = NULL;
495+
size_t ret;
496+
497+
if (f->last_error) {
498+
return 0;
499+
}
500+
501+
ret = qio_channel_pread(f->ioc, (char *)buf, buflen, pos, &err);
502+
503+
if ((ssize_t)ret == -1 || err) {
504+
qemu_file_set_error_obj(f, -EIO, err);
505+
return 0;
506+
}
507+
508+
if ((ssize_t)ret == QIO_CHANNEL_ERR_BLOCK) {
509+
qemu_file_set_error_obj(f, -EAGAIN, NULL);
510+
return 0;
511+
}
512+
513+
if (ret != buflen) {
514+
error_setg(&err, "Partial read of size %zu, expected %zu", ret, buflen);
515+
qemu_file_set_error_obj(f, -EIO, err);
516+
return 0;
517+
}
518+
519+
return ret;
520+
}
521+
522+
void qemu_set_offset(QEMUFile *f, off_t off, int whence)
523+
{
524+
Error *err = NULL;
525+
off_t ret;
526+
527+
if (qemu_file_is_writable(f)) {
528+
qemu_fflush(f);
529+
} else {
530+
/* Drop all cached buffers if existed; will trigger a re-fill later */
531+
f->buf_index = 0;
532+
f->buf_size = 0;
533+
}
534+
535+
ret = qio_channel_io_seek(f->ioc, off, whence, &err);
536+
if (ret == (off_t)-1) {
537+
qemu_file_set_error_obj(f, -EIO, err);
538+
}
539+
}
540+
541+
off_t qemu_get_offset(QEMUFile *f)
542+
{
543+
Error *err = NULL;
544+
off_t ret;
545+
546+
qemu_fflush(f);
547+
548+
ret = qio_channel_io_seek(f->ioc, 0, SEEK_CUR, &err);
549+
if (ret == (off_t)-1) {
550+
qemu_file_set_error_obj(f, -EIO, err);
551+
}
552+
return ret;
553+
}
554+
555+
450556
void qemu_put_byte(QEMUFile *f, int v)
451557
{
452558
if (f->last_error) {

migration/qemu-file.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,12 @@ QEMUFile *qemu_file_get_return_path(QEMUFile *f);
7575
int qemu_fflush(QEMUFile *f);
7676
void qemu_file_set_blocking(QEMUFile *f, bool block);
7777
int qemu_file_get_to_fd(QEMUFile *f, int fd, size_t size);
78+
void qemu_set_offset(QEMUFile *f, off_t off, int whence);
79+
off_t qemu_get_offset(QEMUFile *f);
80+
void qemu_put_buffer_at(QEMUFile *f, const uint8_t *buf, size_t buflen,
81+
off_t pos);
82+
size_t qemu_get_buffer_at(QEMUFile *f, const uint8_t *buf, size_t buflen,
83+
off_t pos);
7884

7985
QIOChannel *qemu_file_get_ioc(QEMUFile *file);
8086

0 commit comments

Comments
 (0)