mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 10:11:27 +01:00
libxc/migration: export read_record for common use
read_record() could be used by primary to read dirty bitmap record sent by secondary under COLO. When used by xc save side, we need to pass the backchannel fd instead of ctx->fd to read_record(), so we added a fd param to it. No functional changes. CC: Andrew Cooper <andrew.cooper3@citrix.com> Signed-off-by: Yang Hongyang <hongyang.yang@easystack.cn> Signed-off-by: Wen Congyang <wency@cn.fujitsu.com> Signed-off-by: Changlong Xie <xiecl.fnst@cn.fujitsu.com> Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
This commit is contained in:
1 parent
9f4edff430
commit
d34ef46bc4
3 files changed
+64
-62
No files matched your search
@@ -89,6 +89,55 @@ int write_split_record(struct xc_sr_context *ctx, struct xc_sr_record *rec,
|
||||
return -1;
|
||||
}
|
||||
|
||||
int read_record(struct xc_sr_context *ctx, int fd, struct xc_sr_record *rec)
|
||||
{
|
||||
xc_interface *xch = ctx->xch;
|
||||
struct xc_sr_rhdr rhdr;
|
||||
size_t datasz;
|
||||
|
||||
if ( read_exact(fd, &rhdr, sizeof(rhdr)) )
|
||||
{
|
||||
PERROR("Failed to read Record Header from stream");
|
||||
return -1;
|
||||
}
|
||||
else if ( rhdr.length > REC_LENGTH_MAX )
|
||||
{
|
||||
ERROR("Record (0x%08x, %s) length %#x exceeds max (%#x)", rhdr.type,
|
||||
rec_type_to_str(rhdr.type), rhdr.length, REC_LENGTH_MAX);
|
||||
return -1;
|
||||
}
|
||||
|
||||
datasz = ROUNDUP(rhdr.length, REC_ALIGN_ORDER);
|
||||
|
||||
if ( datasz )
|
||||
{
|
||||
rec->data = malloc(datasz);
|
||||
|
||||
if ( !rec->data )
|
||||
{
|
||||
ERROR("Unable to allocate %zu bytes for record data (0x%08x, %s)",
|
||||
datasz, rhdr.type, rec_type_to_str(rhdr.type));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( read_exact(fd, rec->data, datasz) )
|
||||
{
|
||||
free(rec->data);
|
||||
rec->data = NULL;
|
||||
PERROR("Failed to read %zu bytes of data for record (0x%08x, %s)",
|
||||
datasz, rhdr.type, rec_type_to_str(rhdr.type));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
rec->data = NULL;
|
||||
|
||||
rec->type = rhdr.type;
|
||||
rec->length = rhdr.length;
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
static void __attribute__((unused)) build_assertions(void)
|
||||
{
|
||||
XC_BUILD_BUG_ON(sizeof(struct xc_sr_ihdr) != 24);
|
||||
|
||||
@@ -371,6 +371,20 @@ static inline int write_record(struct xc_sr_context *ctx,
|
||||
return write_split_record(ctx, rec, NULL, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Reads a record from the stream, and fills in the record structure.
|
||||
*
|
||||
* Returns 0 on success and non-0 on failure.
|
||||
*
|
||||
* On success, the records type and size shall be valid.
|
||||
* - If size is 0, data shall be NULL.
|
||||
* - If size is non-0, data shall be a buffer allocated by malloc() which must
|
||||
* be passed to free() by the caller.
|
||||
*
|
||||
* On failure, the contents of the record structure are undefined.
|
||||
*/
|
||||
int read_record(struct xc_sr_context *ctx, int fd, struct xc_sr_record *rec);
|
||||
|
||||
/*
|
||||
* This would ideally be private in restore.c, but is needed by
|
||||
* x86_pv_localise_page() if we receive pagetables frames ahead of the
|
||||
|
||||
@@ -68,67 +68,6 @@ static int read_headers(struct xc_sr_context *ctx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reads a record from the stream, and fills in the record structure.
|
||||
*
|
||||
* Returns 0 on success and non-0 on failure.
|
||||
*
|
||||
* On success, the records type and size shall be valid.
|
||||
* - If size is 0, data shall be NULL.
|
||||
* - If size is non-0, data shall be a buffer allocated by malloc() which must
|
||||
* be passed to free() by the caller.
|
||||
*
|
||||
* On failure, the contents of the record structure are undefined.
|
||||
*/
|
||||
static int read_record(struct xc_sr_context *ctx, struct xc_sr_record *rec)
|
||||
{
|
||||
xc_interface *xch = ctx->xch;
|
||||
struct xc_sr_rhdr rhdr;
|
||||
size_t datasz;
|
||||
|
||||
if ( read_exact(ctx->fd, &rhdr, sizeof(rhdr)) )
|
||||
{
|
||||
PERROR("Failed to read Record Header from stream");
|
||||
return -1;
|
||||
}
|
||||
else if ( rhdr.length > REC_LENGTH_MAX )
|
||||
{
|
||||
ERROR("Record (0x%08x, %s) length %#x exceeds max (%#x)", rhdr.type,
|
||||
rec_type_to_str(rhdr.type), rhdr.length, REC_LENGTH_MAX);
|
||||
return -1;
|
||||
}
|
||||
|
||||
datasz = ROUNDUP(rhdr.length, REC_ALIGN_ORDER);
|
||||
|
||||
if ( datasz )
|
||||
{
|
||||
rec->data = malloc(datasz);
|
||||
|
||||
if ( !rec->data )
|
||||
{
|
||||
ERROR("Unable to allocate %zu bytes for record data (0x%08x, %s)",
|
||||
datasz, rhdr.type, rec_type_to_str(rhdr.type));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( read_exact(ctx->fd, rec->data, datasz) )
|
||||
{
|
||||
free(rec->data);
|
||||
rec->data = NULL;
|
||||
PERROR("Failed to read %zu bytes of data for record (0x%08x, %s)",
|
||||
datasz, rhdr.type, rec_type_to_str(rhdr.type));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
rec->data = NULL;
|
||||
|
||||
rec->type = rhdr.type;
|
||||
rec->length = rhdr.length;
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
/*
|
||||
* Is a pfn populated?
|
||||
*/
|
||||
@@ -650,7 +589,7 @@ static int restore(struct xc_sr_context *ctx)
|
||||
|
||||
do
|
||||
{
|
||||
rc = read_record(ctx, &rec);
|
||||
rc = read_record(ctx, ctx->fd, &rec);
|
||||
if ( rc )
|
||||
{
|
||||
if ( ctx->restore.buffer_all_records )
|
||||
|
||||