[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH RFC for-2.3 2/6] qga: introduce three help functions
From: |
zhanghailiang |
Subject: |
[Qemu-devel] [PATCH RFC for-2.3 2/6] qga: introduce three help functions for memory block functions |
Date: |
Sat, 6 Dec 2014 14:59:15 +0800 |
Signed-off-by: zhanghailiang <address@hidden>
---
qga/commands-posix.c | 130 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 130 insertions(+)
diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index b0d6a5d..8917dca 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -1875,6 +1875,136 @@ 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);
+ }
+ res = close(fd);
+ g_assert(res == 0);
+}
+
+static void ga_write_sysfs_file(int dirfd, const char *pathname,
+ const char *buf, int size, Error **errp)
+{
+ int fd;
+ int res;
+
+ 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);
+ }
+
+ res = close(fd);
+ g_assert(res == 0);
+}
+
+/* Transfer online/offline status between @mem_blk and the guest system.
+ *
+ * On input either @errp or address@hidden must be NULL.
+ *
+ * In address@hidden 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,
+ Error **errp)
+{
+ char *dirpath;
+ int dirfd;
+ int res;
+ char *status;
+ Error *local_err = NULL;
+
+ dirpath = g_strdup_printf("/sys/devices/system/memory/memory%" PRId64 "/",
+ mem_blk->phys_index);
+ dirfd = open(dirpath, O_RDONLY | O_DIRECTORY);
+ if (dirfd == -1) {
+ error_setg_errno(errp, errno, "open(\"%s\")", dirpath);
+ g_free(dirpath);
+ return;
+ }
+ 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) {
+ error_setg(errp, "memory block #%" PRId64 " can't be "
+ "offlined", mem_blk->phys_index);
+ }
+ } else {
+ error_propagate(errp, local_err);
+ }
+ return;
+ }
+
+ 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),
+ errp);
+ g_free(new_state);
+ } /* otherwise pretend successful re-(on|off)-lining */
+ }
+
+ g_free(status);
+ res = close(dirfd);
+ g_assert(res == 0);
+}
+
#else /* defined(__linux__) */
void qmp_guest_suspend_disk(Error **errp)
--
1.7.12.4
- [Qemu-devel] [PATCH RFC for-2.3 0/6] qga: add three logical memory hotplug related commands, zhanghailiang, 2014/12/06
- [Qemu-devel] [PATCH RFC for-2.3 3/6] qga: implement qmp_guest_get_memory_blocks() for Linux with sysfs, zhanghailiang, 2014/12/06
- [Qemu-devel] [PATCH RFC for-2.3 6/6] qga: add memory block command that unsupported to blacklist, zhanghailiang, 2014/12/06
- [Qemu-devel] [PATCH RFC for-2.3 2/6] qga: introduce three help functions for memory block functions,
zhanghailiang <=
- [Qemu-devel] [PATCH RFC for-2.3 4/6] qga: implement qmp_guest_set_memory_blocks() for Linux with sysfs, zhanghailiang, 2014/12/06
- [Qemu-devel] [PATCH RFC for-2.3 5/6] qga: implement qmp_guest_get_memory_block_size() for Linux with sysfs, zhanghailiang, 2014/12/06
- [Qemu-devel] [PATCH RFC for-2.3 1/6] qga: introduce three guest memory block commands with stubs, zhanghailiang, 2014/12/06