[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |