Skip to content

Commit

Permalink
QAPI: Introduce memchar-read QMP command
Browse files Browse the repository at this point in the history
Signed-off-by: Lei Li <lilei@linux.vnet.ibm.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
  • Loading branch information
leilihh authored and Luiz Capitulino committed Jan 25, 2013
1 parent 1f590cf commit 49b6d72
Show file tree
Hide file tree
Showing 6 changed files with 159 additions and 0 deletions.
21 changes: 21 additions & 0 deletions hmp-commands.hx
Expand Up @@ -855,6 +855,27 @@ STEXI
Provide writing interface for CirMemCharDriver. Write @var{data}
to char device 'memory'.

ETEXI

{
.name = "memchar_read",
.args_type = "device:s,size:i",
.params = "device size",
.help = "Provide read interface for CirMemCharDriver. Read from"
"it and return the data with size.",
.mhandler.cmd = hmp_memchar_read,
},

STEXI
@item memchar_read @var{device}
@findex memchar_read
Provide read interface for CirMemCharDriver. Read from char device
'memory' and return the data.

@var{size} is the size of data want to read from. Refer to unencoded
size of the raw data, would adjust to the init size of the memchar
if the requested size is larger than it.

ETEXI

{
Expand Down
21 changes: 21 additions & 0 deletions hmp.c
Expand Up @@ -675,6 +675,27 @@ void hmp_memchar_write(Monitor *mon, const QDict *qdict)
hmp_handle_error(mon, &errp);
}

void hmp_memchar_read(Monitor *mon, const QDict *qdict)
{
uint32_t size = qdict_get_int(qdict, "size");
const char *chardev = qdict_get_str(qdict, "device");
MemCharRead *meminfo;
Error *errp = NULL;

meminfo = qmp_memchar_read(chardev, size, false, 0, &errp);
if (errp) {
monitor_printf(mon, "%s\n", error_get_pretty(errp));
error_free(errp);
return;
}

if (meminfo->count > 0) {
monitor_printf(mon, "%s\n", meminfo->data);
}

qapi_free_MemCharRead(meminfo);
}

static void hmp_cont_cb(void *opaque, int err)
{
if (!err) {
Expand Down
1 change: 1 addition & 0 deletions hmp.h
Expand Up @@ -44,6 +44,7 @@ void hmp_cpu(Monitor *mon, const QDict *qdict);
void hmp_memsave(Monitor *mon, const QDict *qdict);
void hmp_pmemsave(Monitor *mon, const QDict *qdict);
void hmp_memchar_write(Monitor *mon, const QDict *qdict);
void hmp_memchar_read(Monitor *mon, const QDict *qdict);
void hmp_cont(Monitor *mon, const QDict *qdict);
void hmp_system_wakeup(Monitor *mon, const QDict *qdict);
void hmp_inject_nmi(Monitor *mon, const QDict *qdict);
Expand Down
36 changes: 36 additions & 0 deletions qapi-schema.json
Expand Up @@ -362,6 +362,42 @@
'data': {'device': 'str', 'size': 'int', 'data': 'str',
'*format': 'DataFormat'} }

##
# @MemCharRead
#
# Result of QMP command memchar-read.
#
# @data: The data read from memchar as string.
#
# @count: The numbers of bytes read from.
#
# Since: 1.4
##
{ 'type': 'MemCharRead',
'data': { 'data': 'str', 'count': 'int' } }

##
# @memchar-read:
#
# Provide read interface for memchardev. Read from the char
# device 'memory' and return the data.
#
# @device: the name of the memory char device.
#
# @size: the size to read in bytes.
#
# @format: #optional the format of the data want to read from
# memchardev, by default is 'utf8'.
#
# Returns: @MemCharRead
# If @device is not a valid memchr device, DeviceNotFound
#
# Since: 1.4
##
{ 'command': 'memchar-read',
'data': {'device': 'str', 'size': 'int', '*format': 'DataFormat'},
'returns': 'MemCharRead' }

##
# @CommandInfo:
#
Expand Down
47 changes: 47 additions & 0 deletions qemu-char.c
Expand Up @@ -2790,6 +2790,53 @@ void qmp_memchar_write(const char *device, int64_t size,
}
}

MemCharRead *qmp_memchar_read(const char *device, int64_t size,
bool has_format, enum DataFormat format,
Error **errp)
{
CharDriverState *chr;
guchar *read_data;
MemCharRead *meminfo;
size_t count;

chr = qemu_chr_find(device);
if (!chr) {
error_set(errp, QERR_DEVICE_NOT_FOUND, device);
return NULL;
}

if (qemu_is_chr(chr, "memory")) {
error_setg(errp,"%s is not memory char device", device);
return NULL;
}

if (size <= 0) {
error_setg(errp, "size must be greater than zero");
return NULL;
}

meminfo = g_malloc0(sizeof(MemCharRead));

count = qemu_chr_cirmem_count(chr);
if (count == 0) {
meminfo->data = g_strdup("");
return meminfo;
}

size = size > count ? count : size;
read_data = g_malloc0(size + 1);

meminfo->count = cirmem_chr_read(chr, read_data, size);

if (has_format && (format == DATA_FORMAT_BASE64)) {
meminfo->data = g_base64_encode(read_data, (size_t)meminfo->count);
} else {
meminfo->data = (char *)read_data;
}

return meminfo;
}

QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename)
{
char host[65], port[33], width[8], height[8];
Expand Down
33 changes: 33 additions & 0 deletions qmp-commands.hx
Expand Up @@ -496,6 +496,39 @@ Example:
"format": "utf8" } }
<- { "return": {} }

EQMP

{
.name = "memchar-read",
.args_type = "device:s,size:i,format:s?",
.mhandler.cmd_new = qmp_marshal_input_memchar_read,
},

SQMP
memchar-read
-------------

Provide read interface for CirMemCharDriver. Read from the char
device memory and return the data with size.

Arguments:

- "device": the name of the char device, must be unique (json-string)
- "size": the memory size wanted to read in bytes (refer to unencoded
size of the raw data), would adjust to the init size of the
memchar if the requested size is larger than it. (json-int)
- "format": the data format write to memchardev, default is
utf8. (json-string, optional)
- Possible values: "utf8", "base64"

Example:

-> { "execute": "memchar-read",
"arguments": { "device": foo,
"size": 1000,
"format": "utf8" } }
<- { "return": { "data": "data string...", "count": 1000 } }

EQMP

{
Expand Down

0 comments on commit 49b6d72

Please sign in to comment.