All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v2 0/5] qga: add three logical memory hotplug related commands
@ 2015-01-22  2:40 zhanghailiang
  2015-01-22  2:40 ` [Qemu-devel] [PATCH v2 1/5] qga: introduce three guest memory block commmands with stubs zhanghailiang
                   ` (6 more replies)
  0 siblings, 7 replies; 9+ messages in thread
From: zhanghailiang @ 2015-01-22  2:40 UTC (permalink / raw)
  To: qemu-devel
  Cc: hangaohuai, zhanghailiang, peter.huangpeng, mdroth, lcapitulino, lersek

This patch series add three guest commands about memory block:
guest-get-memory-blocks, guest-set-memory-blocks, guest-get-memory-block-size.

With these three commands, we can get information about guest's memory block
online/offline status and memory block size (unit of memory online/offline 
operation ). Also, we can change guest's memory block status (Logical memory
hotplug/unplug) from host.

Example of usage:

{"execute":"guest-get-memory-blocks"}
{"return":[{"online":true,"can-offline":false,"phys-index":0},{"online":true,"can-offline":true,"phys-index":1},{"online":true,"can-offline":false,"phys-index":2},{"online":true,"can-offline":false,"phys-index":3}]}

{"execute":"guest-set-memory-blocks","arguments":{"mem-blks":[{"phys-index":0,"online":false},{"phys-index":1,"online":false},{"phys-index":3,"online":false}]}}
{"return":[{"response":"operation-failed","error-code":22,"phys-index":0},{"response":"success","phys-index":1},{"response":"operation-failed","error-code":16,"phys-index":3}]}

{"execute":"guest-get-memory-block-size"}
{"return":134217728}

v2:
 - Change return value of 'guest-set-memory-blocks' command from 'int' to a list
   of 'GuestMemoryBlockResponse', which contains more info about the operation 
   results. It is suggested by Michael Roth. It is more useful for callers to 
   know the exact operation result for each memory block, and also they can help
   callers to decide what to do next according to different error-code.

zhanghailiang (5):
  qga: introduce three guest memory block commmands with stubs
  qga: implement qmp_guest_get_memory_blocks() for Linux with sysfs
  qga: implement qmp_guest_set_memory_blocks() for Linux with sysfs
  qga: implement qmp_guest_get_memory_block_size() for Linux with sysfs
  qga: add memory block command that unsupported to blacklist

 qga/commands-posix.c | 324 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 qga/commands-win32.c |  21 ++++
 qga/qapi-schema.json | 114 ++++++++++++++++++
 3 files changed, 458 insertions(+), 1 deletion(-)

-- 
1.7.12.4

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PATCH v2 1/5] qga: introduce three guest memory block commmands with stubs
  2015-01-22  2:40 [Qemu-devel] [PATCH v2 0/5] qga: add three logical memory hotplug related commands zhanghailiang
@ 2015-01-22  2:40 ` zhanghailiang
  2015-02-17 15:24   ` Eric Blake
  2015-01-22  2:40 ` [Qemu-devel] [PATCH v2 2/5] qga: implement qmp_guest_get_memory_blocks() for Linux with sysfs zhanghailiang
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 9+ messages in thread
From: zhanghailiang @ 2015-01-22  2:40 UTC (permalink / raw)
  To: qemu-devel
  Cc: hangaohuai, zhanghailiang, peter.huangpeng, mdroth, lcapitulino, lersek

Introduce three new guest commands:
guest-get-memory-blocks, guest-set-memory-blocks, guest-get-memory-block-size.

With these three commands, we can support online/offline guest's memory block
(logical memory hotplug/unplug) as required from host.

Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
---
 qga/commands-posix.c |  38 +++++++++++++++++
 qga/commands-win32.c |  19 +++++++++
 qga/qapi-schema.json | 114 +++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 171 insertions(+)

diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index f6f3e3c..76dc07b 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -1875,6 +1875,25 @@ int64_t qmp_guest_set_vcpus(GuestLogicalProcessorList *vcpus, Error **errp)
     return processed;
 }
 
+GuestMemoryBlockList *qmp_guest_get_memory_blocks(Error **errp)
+{
+    error_set(errp, QERR_UNSUPPORTED);
+    return NULL;
+}
+
+GuestMemoryBlockResponseList *
+qmp_guest_set_memory_blocks(GuestMemoryBlockList *mem_blks, Error **errp)
+{
+    error_set(errp, QERR_UNSUPPORTED);
+    return NULL;
+}
+
+int64_t qmp_guest_get_memory_block_size(Error **errp)
+{
+    error_set(errp, QERR_UNSUPPORTED);
+    return -1;
+}
+
 #else /* defined(__linux__) */
 
 void qmp_guest_suspend_disk(Error **errp)
@@ -1910,6 +1929,25 @@ int64_t qmp_guest_set_vcpus(GuestLogicalProcessorList *vcpus, Error **errp)
     return -1;
 }
 
+GuestMemoryBlockList *qmp_guest_get_memory_blocks(Error **errp)
+{
+    error_set(errp, QERR_UNSUPPORTED);
+    return NULL;
+}
+
+GuestMemoryBlockResponseList *
+qmp_guest_set_memory_blocks(GuestMemoryBlockList *mem_blks, Error **errp)
+{
+    error_set(errp, QERR_UNSUPPORTED);
+    return NULL;
+}
+
+int64_t qmp_guest_get_memory_block_size(Error **errp)
+{
+    error_set(errp, QERR_UNSUPPORTED);
+    return -1;
+}
+
 #endif
 
 #if !defined(CONFIG_FSFREEZE)
diff --git a/qga/commands-win32.c b/qga/commands-win32.c
index 3bcbeae..c596c0c 100644
--- a/qga/commands-win32.c
+++ b/qga/commands-win32.c
@@ -446,6 +446,25 @@ int64_t qmp_guest_set_vcpus(GuestLogicalProcessorList *vcpus, Error **errp)
     return -1;
 }
 
+GuestMemoryBlockList *qmp_guest_get_memory_blocks(Error **errp)
+{
+    error_set(errp, QERR_UNSUPPORTED);
+    return NULL;
+}
+
+GuestMemoryBlockResponseList *
+qmp_guest_set_memory_blocks(GuestMemoryBlockList *mem_blks, Error **errp)
+{
+    error_set(errp, QERR_UNSUPPORTED);
+    return NULL;
+}
+
+int64_t qmp_guest_get_memory_block_size(Error **errp)
+{
+    error_set(errp, QERR_UNSUPPORTED);
+    return -1;
+}
+
 /* add unsupported commands to the blacklist */
 GList *ga_command_blacklist_init(GList *blacklist)
 {
diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json
index 376e79f..20ba2ad 100644
--- a/qga/qapi-schema.json
+++ b/qga/qapi-schema.json
@@ -738,3 +738,117 @@
 ##
 { 'command': 'guest-get-fsinfo',
   'returns': ['GuestFilesystemInfo'] }
+
+##
+# @GuestMemoryBlock:
+#
+# @phys-index: Arbitrary guest-specific unique identifier of the MEMORY BLOCK.
+#
+# @online: Whether the MEMORY BLOCK is enabled in guest.
+#
+# @can-offline: #optional Whether offlining the MEMORY BLOCK is possible.
+#               This member is always filled in by the guest agent when the
+#               structure is returned, and always ignored on input (hence it
+#               can be omitted then).
+#
+# Since: 2.3
+##
+{ 'type': 'GuestMemoryBlock',
+  'data': {'phys-index': 'uint64',
+           'online': 'bool',
+           '*can-offline': 'bool'} }
+
+##
+# @guest-get-memory-blocks:
+#
+# Retrieve the list of the guest's memory blocks.
+#
+# This is a read-only operation.
+#
+# Returns: The list of all memory blocks the guest knows about.
+# Each memory block is put on the list exactly once, but their order
+# is unspecified.
+#
+# Since: 2.3
+##
+{ 'command': 'guest-get-memory-blocks',
+  'returns': ['GuestMemoryBlock'] }
+
+##
+# @GuestMemoryBlockResponseType
+#
+# An enumeration of memory block operation result.
+#
+# @sucess: the operation of online/offline memory block is successful.
+# @not-found: can't find the corresponding memoryXXX directory in sysfs.
+# @operation-not-supported: for some old kernels, it does not support
+#                           online or offline memory block.
+# @operation-failed: the operation of online/offline memory block fails,
+#                    because of some errors happen.
+#
+# Since: 2.3
+##
+{ 'enum': 'GuestMemoryBlockResponseType',
+  'data': ['success', 'not-found', 'operation-not-supported',
+           'operation-failed'] }
+
+##
+# @GuestMemoryBlockResponse:
+#
+# @phys-index: same with the 'phys-index' member of @GuestMemoryBlock.
+#
+# @response: the result of memory block operation.
+#
+# @error-code: #optional the error number.
+#               When memory block operation fails, we assign the value of
+#               'errno' to this member, it indicates what goes wrong.
+#               When the operation succeeds, it will be omitted.
+#
+# Since: 2.3
+##
+{ 'type': 'GuestMemoryBlockResponse',
+  'data': { 'phys-index': 'uint64',
+            'response': 'GuestMemoryBlockResponseType',
+            '*error-code': 'int' }}
+
+##
+# @guest-set-memory-blocks:
+#
+# Attempt to reconfigure (currently: enable/disable) state of memory blocks
+# inside the guest.
+#
+# The input list is processed node by node in order. In each node @phys-index
+# is used to look up the guest MEMORY BLOCK, for which @online specifies the
+# requested state. The set of distinct @phys-index's is only required to be a
+# subset of the guest-supported identifiers. There's no restriction on list
+# length or on repeating the same @phys-index (with possibly different @online
+# field).
+# Preferably the input list should describe a modified subset of
+# @guest-get-memory-blocks' return value.
+#
+# Returns: The operation results, it is a list of @GuestMemoryBlockResponse,
+#          which is corresponding to the input list.
+#
+#          Note: it will return NULL if the @mem-blks list was empty on input,
+#          or there is an error, and in this case, guest state will not be
+#          changed.
+#
+# Since: 2.3
+##
+{ 'command': 'guest-set-memory-blocks',
+  'data':    {'mem-blks': ['GuestMemoryBlock'] },
+  'returns': ['GuestMemoryBlockResponse'] }
+
+##
+# @guest-get-memory-block-size:
+#
+# Get the the size (in bytes) of a memory block in guest.
+# It is the unit of memory block online/offline operation (also called Logical
+# Memory Hotplug).
+#
+# Returns: memory block size in bytes.
+#
+# Since 2.3
+##
+{ 'command': 'guest-get-memory-block-size',
+  'returns': 'int' }
-- 
1.7.12.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PATCH v2 2/5] qga: implement qmp_guest_get_memory_blocks() for Linux with sysfs
  2015-01-22  2:40 [Qemu-devel] [PATCH v2 0/5] qga: add three logical memory hotplug related commands zhanghailiang
  2015-01-22  2:40 ` [Qemu-devel] [PATCH v2 1/5] qga: introduce three guest memory block commmands with stubs zhanghailiang
@ 2015-01-22  2:40 ` zhanghailiang
  2015-01-22  2:40 ` [Qemu-devel] [PATCH v2 3/5] qga: implement qmp_guest_set_memory_blocks() " zhanghailiang
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: zhanghailiang @ 2015-01-22  2:40 UTC (permalink / raw)
  To: qemu-devel
  Cc: hangaohuai, zhanghailiang, peter.huangpeng, mdroth, lcapitulino, lersek

We can get guest's memory block information by using command
"guest-get-memory-blocks", the returned value contains a list of memory block
info, such as phys-index, online state, can-offline info.

Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
---
 qga/commands-posix.c | 231 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 230 insertions(+), 1 deletion(-)

diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index 76dc07b..3f66489 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -1875,9 +1875,238 @@ int64_t qmp_guest_set_vcpus(GuestLogicalProcessorList *vcpus, Error **errp)
     return processed;
 }
 
+static void ga_read_sysfs_file(int dirfd, const char *pathname, char *buf,
+                               int size, Error **errp)
+{
+    int fd;
+    int res;
+
+    errno = 0;
+    fd = openat(dirfd, pathname, O_RDONLY);
+    if (fd == -1) {
+        error_setg_errno(errp, errno, "open sysfs file \"%s\"", pathname);
+        return;
+    }
+
+    res = pread(fd, buf, size, 0);
+    if (res == -1) {
+        error_setg_errno(errp, errno, "pread sysfs file \"%s\"", pathname);
+    } else if (res == 0) {
+        error_setg(errp, "pread sysfs file \"%s\": unexpected EOF", pathname);
+    }
+    close(fd);
+}
+
+static void ga_write_sysfs_file(int dirfd, const char *pathname,
+                                const char *buf, int size, Error **errp)
+{
+    int fd;
+
+    errno = 0;
+    fd = openat(dirfd, pathname, O_WRONLY);
+    if (fd == -1) {
+        error_setg_errno(errp, errno, "open sysfs file \"%s\"", pathname);
+        return;
+    }
+
+    if (pwrite(fd, buf, size, 0) == -1) {
+        error_setg_errno(errp, errno, "pwrite sysfs file \"%s\"", pathname);
+    }
+
+    close(fd);
+}
+
+/* Transfer online/offline status between @mem_blk and the guest system.
+ *
+ * On input either @errp or *@errp must be NULL.
+ *
+ * In system-to-@mem_blk direction, the following @mem_blk fields are accessed:
+ * - R: mem_blk->phys_index
+ * - W: mem_blk->online
+ * - W: mem_blk->can_offline
+ *
+ * In @mem_blk-to-system direction, the following @mem_blk fields are accessed:
+ * - R: mem_blk->phys_index
+ * - R: mem_blk->online
+ *-  R: mem_blk->can_offline
+ * Written members remain unmodified on error.
+ */
+static void transfer_memory_block(GuestMemoryBlock *mem_blk, bool sys2memblk,
+                                  GuestMemoryBlockResponse *result,
+                                  Error **errp)
+{
+    char *dirpath;
+    int dirfd;
+    char *status;
+    Error *local_err = NULL;
+
+    if (!sys2memblk) {
+        DIR *dp;
+
+        if (!result) {
+            error_setg(errp, "Internal error, 'result' should not be NULL");
+            return;
+        }
+        errno = 0;
+        dp = opendir("/sys/devices/system/memory/");
+         /* if there is no 'memory' directory in sysfs,
+         * we think this VM does not support online/offline memory block,
+         * any other solution?
+         */
+        if (!dp && errno == ENOENT) {
+            result->response =
+                GUEST_MEMORY_BLOCK_RESPONSE_TYPE_OPERATION_NOT_SUPPORTED;
+            goto out1;
+        }
+        closedir(dp);
+    }
+
+    dirpath = g_strdup_printf("/sys/devices/system/memory/memory%" PRId64 "/",
+                              mem_blk->phys_index);
+    dirfd = open(dirpath, O_RDONLY | O_DIRECTORY);
+    if (dirfd == -1) {
+        if (sys2memblk) {
+            error_setg_errno(errp, errno, "open(\"%s\")", dirpath);
+        } else {
+            if (errno == ENOENT) {
+                result->response = GUEST_MEMORY_BLOCK_RESPONSE_TYPE_NOT_FOUND;
+            } else {
+                result->response =
+                    GUEST_MEMORY_BLOCK_RESPONSE_TYPE_OPERATION_FAILED;
+            }
+        }
+        g_free(dirpath);
+        goto out1;
+    }
+    g_free(dirpath);
+
+    status = g_malloc0(10);
+    ga_read_sysfs_file(dirfd, "state", status, 10, &local_err);
+    if (local_err) {
+        /* treat with sysfs file that not exist in old kernel */
+        if (errno == ENOENT) {
+            error_free(local_err);
+            if (sys2memblk) {
+                mem_blk->online = true;
+                mem_blk->can_offline = false;
+            } else if (!mem_blk->online) {
+                result->response =
+                    GUEST_MEMORY_BLOCK_RESPONSE_TYPE_OPERATION_NOT_SUPPORTED;
+            }
+        } else {
+            if (sys2memblk) {
+                error_propagate(errp, local_err);
+            } else {
+                result->response =
+                    GUEST_MEMORY_BLOCK_RESPONSE_TYPE_OPERATION_FAILED;
+            }
+        }
+        goto out2;
+    }
+
+    if (sys2memblk) {
+        char removable = '0';
+
+        mem_blk->online = (strncmp(status, "online", 6) == 0);
+
+        ga_read_sysfs_file(dirfd, "removable", &removable, 1, &local_err);
+        if (local_err) {
+            /* if no 'removable' file, it does't support offline mem blk */
+            if (errno == ENOENT) {
+                error_free(local_err);
+                mem_blk->can_offline = false;
+            } else {
+                error_propagate(errp, local_err);
+            }
+        } else {
+            mem_blk->can_offline = (removable != '0');
+        }
+    } else {
+        if (mem_blk->online != (strncmp(status, "online", 6) == 0)) {
+            char *new_state = mem_blk->online ? g_strdup("online") :
+                                                g_strdup("offline");
+
+            ga_write_sysfs_file(dirfd, "state", new_state, strlen(new_state),
+                                &local_err);
+            g_free(new_state);
+            if (local_err) {
+                error_free(local_err);
+                result->response =
+                    GUEST_MEMORY_BLOCK_RESPONSE_TYPE_OPERATION_FAILED;
+                goto out2;
+            }
+
+            result->response = GUEST_MEMORY_BLOCK_RESPONSE_TYPE_SUCCESS;
+            result->has_error_code = false;
+        } /* otherwise pretend successful re-(on|off)-lining */
+    }
+    g_free(status);
+    close(dirfd);
+    return;
+
+out2:
+    g_free(status);
+    close(dirfd);
+out1:
+    if (!sys2memblk) {
+        result->has_error_code = true;
+        result->error_code = errno;
+    }
+}
+
 GuestMemoryBlockList *qmp_guest_get_memory_blocks(Error **errp)
 {
-    error_set(errp, QERR_UNSUPPORTED);
+    GuestMemoryBlockList *head, **link;
+    Error *local_err = NULL;
+    struct dirent *de;
+    DIR *dp;
+
+    head = NULL;
+    link = &head;
+
+    dp = opendir("/sys/devices/system/memory/");
+    if (!dp) {
+        error_setg_errno(errp, errno, "Can't open directory"
+                         "\"/sys/devices/system/memory/\"\n");
+        return NULL;
+    }
+
+    /* Note: the phys_index of memory block may be discontinuous,
+     * this is because a memblk is the unit of the Sparse Memory design, which
+     * allows discontinuous memory ranges (ex. NUMA), so here we should
+     * traverse the memory block directory.
+     */
+    while ((de = readdir(dp)) != NULL) {
+        GuestMemoryBlock *mem_blk;
+        GuestMemoryBlockList *entry;
+
+        if ((strncmp(de->d_name, "memory", 6) != 0) ||
+            !(de->d_type & DT_DIR)) {
+            continue;
+        }
+
+        mem_blk = g_malloc0(sizeof *mem_blk);
+        /* The d_name is "memoryXXX",  phys_index is block id, same as XXX */
+        mem_blk->phys_index = strtoul(&de->d_name[6], NULL, 10);
+        mem_blk->has_can_offline = true; /* lolspeak ftw */
+        transfer_memory_block(mem_blk, true, NULL, &local_err);
+
+        entry = g_malloc0(sizeof *entry);
+        entry->value = mem_blk;
+
+        *link = entry;
+        link = &entry->next;
+    }
+
+    closedir(dp);
+    if (local_err == NULL) {
+        /* there's no guest with zero memory blocks */
+        g_assert(head != NULL);
+        return head;
+    }
+
+    qapi_free_GuestMemoryBlockList(head);
+    error_propagate(errp, local_err);
     return NULL;
 }
 
-- 
1.7.12.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PATCH v2 3/5] qga: implement qmp_guest_set_memory_blocks() for Linux with sysfs
  2015-01-22  2:40 [Qemu-devel] [PATCH v2 0/5] qga: add three logical memory hotplug related commands zhanghailiang
  2015-01-22  2:40 ` [Qemu-devel] [PATCH v2 1/5] qga: introduce three guest memory block commmands with stubs zhanghailiang
  2015-01-22  2:40 ` [Qemu-devel] [PATCH v2 2/5] qga: implement qmp_guest_get_memory_blocks() for Linux with sysfs zhanghailiang
@ 2015-01-22  2:40 ` zhanghailiang
  2015-01-22  2:40 ` [Qemu-devel] [PATCH v2 4/5] qga: implement qmp_guest_get_memory_block_size() " zhanghailiang
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: zhanghailiang @ 2015-01-22  2:40 UTC (permalink / raw)
  To: qemu-devel
  Cc: hangaohuai, zhanghailiang, peter.huangpeng, mdroth, lcapitulino, lersek

We can change guest's online/offline state of memory blocks, by using
command 'guest-set-memory-blocks'.

Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
---
 qga/commands-posix.c | 30 +++++++++++++++++++++++++++++-
 1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index 3f66489..4b41385 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -2113,7 +2113,35 @@ GuestMemoryBlockList *qmp_guest_get_memory_blocks(Error **errp)
 GuestMemoryBlockResponseList *
 qmp_guest_set_memory_blocks(GuestMemoryBlockList *mem_blks, Error **errp)
 {
-    error_set(errp, QERR_UNSUPPORTED);
+    GuestMemoryBlockResponseList *head, **link;
+    Error *local_err = NULL;
+
+    head = NULL;
+    link = &head;
+
+    while (mem_blks != NULL) {
+        GuestMemoryBlockResponse *result;
+        GuestMemoryBlockResponseList *entry;
+        GuestMemoryBlock *current_mem_blk = mem_blks->value;
+
+        result = g_malloc0(sizeof(*result));
+        result->phys_index = current_mem_blk->phys_index;
+        transfer_memory_block(current_mem_blk, false, result, &local_err);
+        if (local_err) { /* should never happen */
+            goto err;
+        }
+        entry = g_malloc0(sizeof *entry);
+        entry->value = result;
+
+        *link = entry;
+        link = &entry->next;
+        mem_blks = mem_blks->next;
+    }
+
+    return head;
+err:
+    qapi_free_GuestMemoryBlockResponseList(head);
+    error_propagate(errp, local_err);
     return NULL;
 }
 
-- 
1.7.12.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PATCH v2 4/5] qga: implement qmp_guest_get_memory_block_size() for Linux with sysfs
  2015-01-22  2:40 [Qemu-devel] [PATCH v2 0/5] qga: add three logical memory hotplug related commands zhanghailiang
                   ` (2 preceding siblings ...)
  2015-01-22  2:40 ` [Qemu-devel] [PATCH v2 3/5] qga: implement qmp_guest_set_memory_blocks() " zhanghailiang
@ 2015-01-22  2:40 ` zhanghailiang
  2015-01-22  2:40 ` [Qemu-devel] [PATCH v2 5/5] qga: add memory block command that unsupported to blacklist zhanghailiang
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: zhanghailiang @ 2015-01-22  2:40 UTC (permalink / raw)
  To: qemu-devel
  Cc: hangaohuai, zhanghailiang, peter.huangpeng, mdroth, lcapitulino, lersek

The size of a memory block is architecture dependent, it represents the logical
unit upon which memory online/offline operations are to be performed.

Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
---
 qga/commands-posix.c | 29 +++++++++++++++++++++++++++--
 1 file changed, 27 insertions(+), 2 deletions(-)

diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index 4b41385..44d9e8f 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -2147,8 +2147,33 @@ err:
 
 int64_t qmp_guest_get_memory_block_size(Error **errp)
 {
-    error_set(errp, QERR_UNSUPPORTED);
-    return -1;
+    Error *local_err = NULL;
+    char *dirpath;
+    int dirfd;
+    char *buf;
+    int64_t block_size;
+
+    dirpath = g_strdup_printf("/sys/devices/system/memory/");
+    dirfd = open(dirpath, O_RDONLY | O_DIRECTORY);
+    if (dirfd == -1) {
+        error_setg_errno(errp, errno, "open(\"%s\")", dirpath);
+        g_free(dirpath);
+        return -1;
+    }
+    g_free(dirpath);
+
+    buf = g_malloc0(20);
+    ga_read_sysfs_file(dirfd, "block_size_bytes", buf, 20, &local_err);
+    if (local_err) {
+        g_free(buf);
+        error_propagate(errp, local_err);
+        return -1;
+    }
+
+    block_size = strtol(buf, NULL, 16); /* the unit is bytes */
+    g_free(buf);
+
+    return block_size;
 }
 
 #else /* defined(__linux__) */
-- 
1.7.12.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PATCH v2 5/5] qga: add memory block command that unsupported to blacklist
  2015-01-22  2:40 [Qemu-devel] [PATCH v2 0/5] qga: add three logical memory hotplug related commands zhanghailiang
                   ` (3 preceding siblings ...)
  2015-01-22  2:40 ` [Qemu-devel] [PATCH v2 4/5] qga: implement qmp_guest_get_memory_block_size() " zhanghailiang
@ 2015-01-22  2:40 ` zhanghailiang
  2015-02-12  8:27 ` [Qemu-devel] [PATCH v2 0/5] qga: add three logical memory hotplug related commands zhanghailiang
  2015-02-17  2:05 ` Michael Roth
  6 siblings, 0 replies; 9+ messages in thread
From: zhanghailiang @ 2015-01-22  2:40 UTC (permalink / raw)
  To: qemu-devel
  Cc: hangaohuai, zhanghailiang, peter.huangpeng, mdroth, lcapitulino, lersek

For memory block command, we only support for linux with sysfs.

Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
Reviewed-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
 qga/commands-posix.c | 4 +++-
 qga/commands-win32.c | 2 ++
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index 44d9e8f..aa9ae05 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -2286,7 +2286,9 @@ GList *ga_command_blacklist_init(GList *blacklist)
         const char *list[] = {
             "guest-suspend-disk", "guest-suspend-ram",
             "guest-suspend-hybrid", "guest-network-get-interfaces",
-            "guest-get-vcpus", "guest-set-vcpus", NULL};
+            "guest-get-vcpus", "guest-set-vcpus",
+            "guest-get-memory-blocks", "guest-set-memory-blocks",
+            "guest-get-memory-block-size", NULL};
         char **p = (char **)list;
 
         while (*p) {
diff --git a/qga/commands-win32.c b/qga/commands-win32.c
index c596c0c..7daff9a 100644
--- a/qga/commands-win32.c
+++ b/qga/commands-win32.c
@@ -473,6 +473,8 @@ GList *ga_command_blacklist_init(GList *blacklist)
         "guest-file-write", "guest-file-seek", "guest-file-flush",
         "guest-suspend-hybrid", "guest-network-get-interfaces",
         "guest-get-vcpus", "guest-set-vcpus",
+        "guest-get-memory-blocks", "guest-set-memory-blocks",
+        "guest-get-memory-block-size",
         "guest-fsfreeze-freeze-list", "guest-get-fsinfo",
         "guest-fstrim", NULL};
     char **p = (char **)list_unsupported;
-- 
1.7.12.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [Qemu-devel] [PATCH v2 0/5] qga: add three logical memory hotplug related commands
  2015-01-22  2:40 [Qemu-devel] [PATCH v2 0/5] qga: add three logical memory hotplug related commands zhanghailiang
                   ` (4 preceding siblings ...)
  2015-01-22  2:40 ` [Qemu-devel] [PATCH v2 5/5] qga: add memory block command that unsupported to blacklist zhanghailiang
@ 2015-02-12  8:27 ` zhanghailiang
  2015-02-17  2:05 ` Michael Roth
  6 siblings, 0 replies; 9+ messages in thread
From: zhanghailiang @ 2015-02-12  8:27 UTC (permalink / raw)
  To: qemu-devel, mdroth; +Cc: hangaohuai, lersek, peter.huangpeng, lcapitulino

ping...

Any comments/feedbacks are warmly welcomed.
Michael? What's your opinion?  ;) Thanks.

On 2015/1/22 10:40, zhanghailiang wrote:
> This patch series add three guest commands about memory block:
> guest-get-memory-blocks, guest-set-memory-blocks, guest-get-memory-block-size.
>
> With these three commands, we can get information about guest's memory block
> online/offline status and memory block size (unit of memory online/offline
> operation ). Also, we can change guest's memory block status (Logical memory
> hotplug/unplug) from host.
>
> Example of usage:
>
> {"execute":"guest-get-memory-blocks"}
> {"return":[{"online":true,"can-offline":false,"phys-index":0},{"online":true,"can-offline":true,"phys-index":1},{"online":true,"can-offline":false,"phys-index":2},{"online":true,"can-offline":false,"phys-index":3}]}
>
> {"execute":"guest-set-memory-blocks","arguments":{"mem-blks":[{"phys-index":0,"online":false},{"phys-index":1,"online":false},{"phys-index":3,"online":false}]}}
> {"return":[{"response":"operation-failed","error-code":22,"phys-index":0},{"response":"success","phys-index":1},{"response":"operation-failed","error-code":16,"phys-index":3}]}
>
> {"execute":"guest-get-memory-block-size"}
> {"return":134217728}
>
> v2:
>   - Change return value of 'guest-set-memory-blocks' command from 'int' to a list
>     of 'GuestMemoryBlockResponse', which contains more info about the operation
>     results. It is suggested by Michael Roth. It is more useful for callers to
>     know the exact operation result for each memory block, and also they can help
>     callers to decide what to do next according to different error-code.
>
> zhanghailiang (5):
>    qga: introduce three guest memory block commmands with stubs
>    qga: implement qmp_guest_get_memory_blocks() for Linux with sysfs
>    qga: implement qmp_guest_set_memory_blocks() for Linux with sysfs
>    qga: implement qmp_guest_get_memory_block_size() for Linux with sysfs
>    qga: add memory block command that unsupported to blacklist
>
>   qga/commands-posix.c | 324 ++++++++++++++++++++++++++++++++++++++++++++++++++-
>   qga/commands-win32.c |  21 ++++
>   qga/qapi-schema.json | 114 ++++++++++++++++++
>   3 files changed, 458 insertions(+), 1 deletion(-)
>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Qemu-devel] [PATCH v2 0/5] qga: add three logical memory hotplug related commands
  2015-01-22  2:40 [Qemu-devel] [PATCH v2 0/5] qga: add three logical memory hotplug related commands zhanghailiang
                   ` (5 preceding siblings ...)
  2015-02-12  8:27 ` [Qemu-devel] [PATCH v2 0/5] qga: add three logical memory hotplug related commands zhanghailiang
@ 2015-02-17  2:05 ` Michael Roth
  6 siblings, 0 replies; 9+ messages in thread
From: Michael Roth @ 2015-02-17  2:05 UTC (permalink / raw)
  To: zhanghailiang, qemu-devel
  Cc: hangaohuai, lersek, peter.huangpeng, lcapitulino

Quoting zhanghailiang (2015-01-21 20:40:01)
> This patch series add three guest commands about memory block:
> guest-get-memory-blocks, guest-set-memory-blocks, guest-get-memory-block-size.
> 
> With these three commands, we can get information about guest's memory block
> online/offline status and memory block size (unit of memory online/offline 
> operation ). Also, we can change guest's memory block status (Logical memory
> hotplug/unplug) from host.

Thanks, applied to QGA tree:

https://github.com/mdroth/qemu/commits/qga

with a small change to patch 2 that replaces an assertion that the block
list isn't NULL with a reported error instead. This is more of an assertion
about the guest OS than the code itself, so it's best to avoid tying the
life-cycle of the agent to it. Otherwise looks good.

> 
> Example of usage:
> 
> {"execute":"guest-get-memory-blocks"}
> {"return":[{"online":true,"can-offline":false,"phys-index":0},{"online":true,"can-offline":true,"phys-index":1},{"online":true,"can-offline":false,"phys-index":2},{"online":true,"can-offline":false,"phys-index":3}]}
> 
> {"execute":"guest-set-memory-blocks","arguments":{"mem-blks":[{"phys-index":0,"online":false},{"phys-index":1,"online":false},{"phys-index":3,"online":false}]}}
> {"return":[{"response":"operation-failed","error-code":22,"phys-index":0},{"response":"success","phys-index":1},{"response":"operation-failed","error-code":16,"phys-index":3}]}
> 
> {"execute":"guest-get-memory-block-size"}
> {"return":134217728}
> 
> v2:
>  - Change return value of 'guest-set-memory-blocks' command from 'int' to a list
>    of 'GuestMemoryBlockResponse', which contains more info about the operation 
>    results. It is suggested by Michael Roth. It is more useful for callers to 
>    know the exact operation result for each memory block, and also they can help
>    callers to decide what to do next according to different error-code.
> 
> zhanghailiang (5):
>   qga: introduce three guest memory block commmands with stubs
>   qga: implement qmp_guest_get_memory_blocks() for Linux with sysfs
>   qga: implement qmp_guest_set_memory_blocks() for Linux with sysfs
>   qga: implement qmp_guest_get_memory_block_size() for Linux with sysfs
>   qga: add memory block command that unsupported to blacklist
> 
>  qga/commands-posix.c | 324 ++++++++++++++++++++++++++++++++++++++++++++++++++-
>  qga/commands-win32.c |  21 ++++
>  qga/qapi-schema.json | 114 ++++++++++++++++++
>  3 files changed, 458 insertions(+), 1 deletion(-)
> 
> -- 
> 1.7.12.4

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Qemu-devel] [PATCH v2 1/5] qga: introduce three guest memory block commmands with stubs
  2015-01-22  2:40 ` [Qemu-devel] [PATCH v2 1/5] qga: introduce three guest memory block commmands with stubs zhanghailiang
@ 2015-02-17 15:24   ` Eric Blake
  0 siblings, 0 replies; 9+ messages in thread
From: Eric Blake @ 2015-02-17 15:24 UTC (permalink / raw)
  To: zhanghailiang, qemu-devel
  Cc: hangaohuai, lcapitulino, lersek, peter.huangpeng, mdroth

[-- Attachment #1: Type: text/plain, Size: 1516 bytes --]

On 01/21/2015 07:40 PM, zhanghailiang wrote:
> Introduce three new guest commands:
> guest-get-memory-blocks, guest-set-memory-blocks, guest-get-memory-block-size.
> 
> With these three commands, we can support online/offline guest's memory block
> (logical memory hotplug/unplug) as required from host.
> 
> Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
> ---
>  qga/commands-posix.c |  38 +++++++++++++++++
>  qga/commands-win32.c |  19 +++++++++
>  qga/qapi-schema.json | 114 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 171 insertions(+)
> 

> +
> +##
> +# @guest-get-memory-block-size:
> +#
> +# Get the the size (in bytes) of a memory block in guest.
> +# It is the unit of memory block online/offline operation (also called Logical
> +# Memory Hotplug).
> +#
> +# Returns: memory block size in bytes.
> +#
> +# Since 2.3
> +##
> +{ 'command': 'guest-get-memory-block-size',
> +  'returns': 'int' }

Yuck.  This is not extensible.  Please consider instead providing a
dictionary-based response, so that you can add further dictionary
members in the future if you have additional pieces of information to
return.  In fact, if you do that, it might be better to name this
guest-get-memory-block-info, where size is the only info you provide
now, but where adding other parameters in the future is much easier to
predict.

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2015-02-17 15:24 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-01-22  2:40 [Qemu-devel] [PATCH v2 0/5] qga: add three logical memory hotplug related commands zhanghailiang
2015-01-22  2:40 ` [Qemu-devel] [PATCH v2 1/5] qga: introduce three guest memory block commmands with stubs zhanghailiang
2015-02-17 15:24   ` Eric Blake
2015-01-22  2:40 ` [Qemu-devel] [PATCH v2 2/5] qga: implement qmp_guest_get_memory_blocks() for Linux with sysfs zhanghailiang
2015-01-22  2:40 ` [Qemu-devel] [PATCH v2 3/5] qga: implement qmp_guest_set_memory_blocks() " zhanghailiang
2015-01-22  2:40 ` [Qemu-devel] [PATCH v2 4/5] qga: implement qmp_guest_get_memory_block_size() " zhanghailiang
2015-01-22  2:40 ` [Qemu-devel] [PATCH v2 5/5] qga: add memory block command that unsupported to blacklist zhanghailiang
2015-02-12  8:27 ` [Qemu-devel] [PATCH v2 0/5] qga: add three logical memory hotplug related commands zhanghailiang
2015-02-17  2:05 ` Michael Roth

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.