[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] Tools: add online/offline hotplug user interfaces



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1271834966 -3600
# Node ID 30f70835aa861f2d2a692a6a668d70c8d00b7871
# Parent  dbf0fd95180f97bdf403ada605400723e4e8563d
Tools: add online/offline hotplug user interfaces

Exporting cpu on/offline and memory on/offline hotplug interfaces,
so that users can do those (memory/cpu) hotplug actions with
following command line freely:

usage: xen-hptool <command> [args]
    xen-hptool command list:\n\n
    cpu-online    <cpuid>    online CPU <cpuid>
    cpu-offline   <cpuid>    offline CPU <cpuid>
    mem-online    <mfn>      online MEMORY <mfn>
    mem-offline   <mfn>      offline MEMORY <mfn>
    mem-status    <mfn>      query Memory status<mfn>

Signed-off-by: Yunhong Jiang<yunhong.jiang@xxxxxxxxx>
Signed-off-by: Liping Ke <liping.ke@xxxxxxxxx>
---
 .hgignore               |    1 
 tools/misc/Makefile     |    8 -
 tools/misc/xen-hptool.c |  329 ++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 334 insertions(+), 4 deletions(-)

diff -r dbf0fd95180f -r 30f70835aa86 .hgignore
--- a/.hgignore Tue Apr 20 14:32:53 2010 +0100
+++ b/.hgignore Wed Apr 21 08:29:26 2010 +0100
@@ -196,6 +196,7 @@
 ^tools/misc/xc_shadow$
 ^tools/misc/xen_cpuperf$
 ^tools/misc/xen-detect$
+^tools/misc/xen-hptool$
 ^tools/misc/xen-tmem-list-parse$
 ^tools/misc/xenperf$
 ^tools/misc/xenpm$
diff -r dbf0fd95180f -r 30f70835aa86 tools/misc/Makefile
--- a/tools/misc/Makefile       Tue Apr 20 14:32:53 2010 +0100
+++ b/tools/misc/Makefile       Wed Apr 21 08:29:26 2010 +0100
@@ -10,7 +10,7 @@ CFLAGS   += $(INCLUDES)
 
 HDRS     = $(wildcard *.h)
 
-TARGETS-y := xenperf xenpm xen-tmem-list-parse gtraceview gtracestat 
xenlockprof
+TARGETS-y := xenperf xenpm xen-tmem-list-parse gtraceview gtracestat 
xenlockprof xen-hptool
 TARGETS-$(CONFIG_X86) += xen-detect xen-hvmctx
 TARGETS := $(TARGETS-y)
 
@@ -22,7 +22,7 @@ INSTALL_BIN-$(CONFIG_X86) += xen-detect
 INSTALL_BIN-$(CONFIG_X86) += xen-detect
 INSTALL_BIN := $(INSTALL_BIN-y)
 
-INSTALL_SBIN-y := xm xen-bugtool xen-python-path xend xenperf xsview xenpm 
xen-tmem-list-parse gtraceview gtracestat xenlockprof
+INSTALL_SBIN-y := xm xen-bugtool xen-python-path xend xenperf xsview xenpm 
xen-tmem-list-parse gtraceview gtracestat xenlockprof xen-hptool
 INSTALL_SBIN-$(CONFIG_X86) += xen-hvmctx
 INSTALL_SBIN := $(INSTALL_SBIN-y)
 
@@ -49,8 +49,8 @@ clean:
 %.o: %.c $(HDRS) Makefile
        $(CC) -c $(CFLAGS) -o $@ $<
 
-xen-hvmctx xenperf xenpm gtracestat xenlockprof: %: %.o Makefile
-       $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) $(LDFLAGS_libxenctrl)
+xen-hvmctx xenperf xenpm gtracestat xenlockprof xen-hptool: %: %.o Makefile
+       $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) $(LDFLAGS_libxenctrl) 
$(LDFLAGS_libxenguest) $(LDFLAGS_libxenstore)
 
 gtraceview: %: %.o Makefile
        $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) $(CURSES_LIBS)
diff -r dbf0fd95180f -r 30f70835aa86 tools/misc/xen-hptool.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/misc/xen-hptool.c   Wed Apr 21 08:29:26 2010 +0100
@@ -0,0 +1,329 @@
+#include <xenctrl.h>
+#include <xc_private.h>
+#include <xc_core.h>
+
+#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
+
+static int xc_fd;
+
+/* help message */
+void show_help(void)
+{
+    fprintf(stderr,
+            "\nxen cpu memory hotplug tool\n\n"
+            "usage: xen-hptool <command> [args]\n\n"
+            "xen-hptool command list:\n\n"
+            "cpu-online    <cpuid>    online CPU <cpuid>\n"
+            "cpu-offline   <cpuid>    offline CPU <cpuid>\n"
+            "mem-online    <mfn>      online MEMORY <mfn>\n"
+            "mem-offline   <mfn>      offline MEMORY <mfn>\n"
+            "mem-status    <mfn>      query Memory status<mfn>\n"
+           );
+}
+
+/* wrapper function */
+static int help_func(int argc, char *argv[])
+{
+    show_help();
+    return 0;
+}
+
+static int hp_mem_online_func(int argc, char *argv[])
+{
+    uint32_t status;
+    int ret;
+    unsigned long mfn;
+
+    if (argc != 1)
+    {
+        show_help();
+        return -1;
+    }
+
+    sscanf(argv[0], "%lx", &mfn);
+    printf("Prepare to online MEMORY mfn %lx\n", mfn);
+
+    ret = xc_mark_page_online(xc_fd, mfn, mfn, &status);
+
+    if (ret < 0)
+        fprintf(stderr, "Onlining page mfn %lx failed, error %x", mfn, ret);
+    else if (status & (PG_ONLINE_FAILED |PG_ONLINE_BROKEN)) {
+        fprintf(stderr, "Onlining page mfn %lx is broken, "
+                        "Memory online failed\n", mfn);
+        ret = -1;
+       }
+    else if (status & PG_ONLINE_ONLINED)
+        printf("Memory mfn %lx onlined successfully\n", mfn);
+    else
+        printf("Memory is already onlined!\n");
+
+    return ret;
+}
+
+static int hp_mem_query_func(int argc, char *argv[])
+{
+    uint32_t status;
+    int ret;
+    unsigned long mfn;
+
+    if (argc != 1)
+    {
+        show_help();
+        return -1;
+    }
+
+    sscanf(argv[0], "%lx", &mfn);
+    printf("Querying MEMORY mfn %lx status\n", mfn);
+    ret = xc_query_page_offline_status(xc_fd, mfn, mfn, &status);
+
+    if (ret < 0)
+        fprintf(stderr, "Querying page mfn %lx failed, error %x", mfn, ret);
+    else
+    {
+               printf("Memory Status %x: [", status);
+        if ( status & PG_OFFLINE_STATUS_OFFLINE_PENDING)
+            printf(" PAGE_OFFLINE_PENDING ");
+        if ( status & PG_OFFLINE_STATUS_BROKEN )
+            printf(" PAGE_BROKEND  ");
+        if ( status & PG_OFFLINE_STATUS_OFFLINED )
+            printf(" PAGE_OFFLINED ");
+               else
+            printf(" PAGE_ONLINED ");
+        printf("]\n");
+    }
+
+    return ret;
+}
+
+extern int xs_suspend_evtchn_port(int domid);
+
+static int suspend_guest(int xc_handle, int xce, int domid, int *evtchn)
+{
+    int port, rc, suspend_evtchn = -1;
+
+    if (!evtchn)
+        return -1;
+
+    port = xs_suspend_evtchn_port(domid);
+    if (port < 0)
+    {
+        fprintf(stderr, "DOM%d: No suspend port, try live migration\n", domid);
+        goto failed;
+    }
+    suspend_evtchn = xc_suspend_evtchn_init(xc_handle, xce, domid, port);
+    if (suspend_evtchn < 0)
+    {
+        fprintf(stderr, "Suspend evtchn initialization failed\n");
+        goto failed;
+    }
+    *evtchn = suspend_evtchn;
+
+    rc = xc_evtchn_notify(xce, suspend_evtchn);
+    if (rc < 0)
+    {
+        fprintf(stderr, "Failed to notify suspend channel: errno %d\n", rc);
+        goto failed;
+    }
+    if (xc_await_suspend(xce, suspend_evtchn) < 0)
+    {
+        fprintf(stderr, "Suspend Failed\n");
+        goto failed;
+    }
+    return 0;
+
+failed:
+    if (suspend_evtchn != -1)
+        xc_suspend_evtchn_release(xce, suspend_evtchn);
+
+    return -1;
+}
+
+static int hp_mem_offline_func(int argc, char *argv[])
+{
+    uint32_t status, domid;
+    int ret;
+    unsigned long mfn;
+
+    if (argc != 1)
+    {
+        show_help();
+        return -1;
+    }
+
+    sscanf(argv[0], "%lx", &mfn);
+    printf("Prepare to offline MEMORY mfn %lx\n", mfn);
+    ret = xc_mark_page_offline(xc_fd, mfn, mfn, &status);
+    if (ret < 0) {
+        fprintf(stderr, "Offlining page mfn %lx failed, error %x\n", mfn, ret);
+        if (status & (PG_OFFLINE_XENPAGE | PG_OFFLINE_FAILED))
+            fprintf(stderr, "XEN_PAGE is not permitted be offlined\n");
+        else if (status & (PG_OFFLINE_FAILED | PG_OFFLINE_NOT_CONV_RAM))
+            fprintf(stderr, "RESERVED RAM is not permitted to be offlined\n");
+    }
+    else
+    {
+        switch(status & PG_OFFLINE_STATUS_MASK)
+        {
+            case PG_OFFLINE_OFFLINED:
+            {
+                printf("Memory mfn %lx offlined successfully, current state is"
+                       " [PG_OFFLINE_OFFLINED]\n", mfn);
+                if (status & PG_OFFLINE_BROKEN)
+                    printf("And this offlined PAGE is already marked broken"
+                        " before!\n");
+                break;
+            }
+            case PG_OFFLINE_FAILED:
+            {
+                fprintf(stderr, "Memory mfn %lx offline failed\n", mfn);
+                if ( status & PG_OFFLINE_ANONYMOUS)
+                    fprintf(stderr, "the memory is an anonymous page!\n");
+                ret = -1;
+                break;
+            }
+            case PG_OFFLINE_PENDING:
+            {
+                if (status & PG_OFFLINE_XENPAGE) {
+                    ret = -1;
+                    fprintf(stderr, "Memory mfn %lx offlined succssefully,"
+                            "this page is xen page, current state is"
+                            " [PG_OFFLINE_PENDING, PG_OFFLINE_XENPAGE]\n", 
mfn);
+                }
+                else if (status & PG_OFFLINE_OWNED)
+                {
+                    int result, xce, suspend_evtchn = -1;
+                    xce = xc_evtchn_open();
+
+                    if (xce < 0)
+                    {
+                        fprintf(stderr, "When exchange page, fail"
+                                " to open evtchn\n");
+                        return -1;
+                    }
+
+                    domid = status >> PG_OFFLINE_OWNER_SHIFT;
+                    if (suspend_guest(xc_fd, xce, domid, &suspend_evtchn))
+                    {
+                        fprintf(stderr, "Failed to suspend guest %d for"
+                                " mfn %lx\n", domid, mfn);
+                        xc_evtchn_close(xce);
+                        return -1;
+                    }
+
+                    result = xc_exchange_page(xc_fd, domid, mfn);
+
+                    /* Exchange page successfully */
+                    if (result == 0)
+                        printf("Memory mfn %lx offlined successfully, this "
+                                "page is DOM%d page and being swapped "
+                                "successfully, current state is "
+                                "[PG_OFFLINE_OFFLINED, PG_OFFLINE_OWNED]\n",
+                                mfn, domid);
+                    else {
+                        ret = -1;
+                        fprintf(stderr, "Memory mfn %lx offlined successfully"
+                                " , this page is DOM%d page yet failed to be "
+                                "exchanged. current state is "
+                                "[PG_OFFLINE_PENDING, PG_OFFLINE_OWNED]\n",
+                                mfn, domid);
+                    }
+                    xc_domain_resume(xc_fd, domid, 1);
+                    xc_suspend_evtchn_release(xce, suspend_evtchn);
+                    xc_evtchn_close(xce);
+                }
+                break;
+            }
+        }//end of switch
+    }//end of if
+
+    return ret;
+}
+
+
+static int hp_cpu_online_func(int argc, char *argv[])
+{
+    int cpu, ret;
+
+    if (argc != 1)
+    {
+        show_help();
+        return -1;
+    }
+
+    cpu = atoi(argv[0]);
+    printf("Prepare to online CPU %d\n", cpu);
+    ret = xc_cpu_online(xc_fd, cpu);
+    if (ret < 0)
+        fprintf(stderr, "CPU %d onlined failed\n", cpu);
+    else
+        printf("CPU %d onlined successfully\n", cpu);
+
+    return ret;
+
+}
+static int hp_cpu_offline_func(int argc, char *argv[])
+{
+    int cpu, ret;
+
+    if (argc !=1)
+    {
+        show_help();
+        return -1;
+    }
+    cpu = atoi(argv[0]);
+    printf("Prepare to offline CPU %d\n", cpu);
+    ret = xc_cpu_offline(xc_fd, cpu);
+    if (ret < 0)
+        fprintf(stderr, "CPU %d offlined failed\n", cpu);
+    else
+        printf("CPU %d offlined successfully\n", cpu);
+
+    return ret;
+}
+
+struct {
+    const char *name;
+    int (*function)(int argc, char *argv[]);
+} main_options[] = {
+    { "help", help_func },
+    { "cpu-online", hp_cpu_online_func },
+    { "cpu-offline", hp_cpu_offline_func },
+    { "mem-status", hp_mem_query_func},
+    { "mem-online", hp_mem_online_func},
+    { "mem-offline", hp_mem_offline_func},
+};
+
+
+int main(int argc, char *argv[])
+{
+    int i, ret;
+    if (argc < 2)
+    {
+        show_help();
+        return 0;
+    }
+
+    xc_fd = xc_interface_open();
+    if ( xc_fd < 0 )
+    {
+        fprintf(stderr, "failed to get the handler\n");
+        return 0;
+    }
+
+    for (i = 0; i < ARRAY_SIZE(main_options); i++)
+    {
+        if (!strncmp(main_options[i].name, argv[1], strlen(argv[1])))
+        {
+            ret = main_options[i].function(argc -2, argv + 2);
+            break;
+        }
+    }
+    if (i >= ARRAY_SIZE(main_options))
+        show_help();
+    else if (ret < 0)
+        fprintf(stderr, "Required Ops failed\n");
+
+    xc_interface_close(xc_fd);
+
+    return 0;
+}

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.