Signed-off-by: Jose Renato Santos diff -Naur oprofile-0.9.1/ChangeLog oprofile-0.9.1-passive/ChangeLog --- oprofile-0.9.1/ChangeLog 2005-07-18 13:02:37.000000000 -0700 +++ oprofile-0.9.1-passive/ChangeLog 2006-08-23 17:55:14.000000000 -0700 @@ -1,3 +1,30 @@ +2006-08-23 Jose Renato Santos + + * daemon/init.c: + * daemon/opd_interface.h: + * daemon/opd_kernel.h: + * daemon/opd_kernel.c: + * daemon/opd_sfile.c: + * daemon/opd_trans.h: + * daemon/opd_trans.c: + * daemon/oprofiled.h: + * daemon/oprofiled.c: + * doc/opcontrol.1.in: + * utils/opcontrol: Added support for passive + domains in Xen (for Xen 3.0.3) + +2005-12-22 Jose Renato Santos + + * daemon/init.c: + * daemon/opd_interface.h: + * daemon/opd_kernel.h: + * daemon/opd_kernel.c: + * daemon/opd_trans.c: + * daemon/oprofiled.h: + * daemon/oprofiled.c: + * doc/opcontrol.1.in: + * utils/opcontrol: Added support for Xen + 2005-07-18 John Levon * libutil++/tests/Makefile.am: canonicalize diff -Naur oprofile-0.9.1/daemon/init.c oprofile-0.9.1-passive/daemon/init.c --- oprofile-0.9.1/daemon/init.c 2005-05-02 08:06:57.000000000 -0700 +++ oprofile-0.9.1-passive/daemon/init.c 2006-08-22 08:46:00.000000000 -0700 @@ -7,6 +7,9 @@ * * @author John Levon * @author Philippe Elie + * Modified by Aravind Menon for Xen + * These modifications are: + * Copyright (C) 2005 Hewlett-Packard Co. */ #include "config.h" @@ -222,6 +225,9 @@ size_t opd_buf_size; opd_create_vmlinux(vmlinux, kernel_range); + opd_create_xen(xenimage, xen_range); + if (xen_passive_setup) + opd_create_passive(xen_passive_setup); opd_buf_size = opd_read_fs_int("/dev/oprofile/", "buffer_size", 1); kernel_pointer_size = opd_read_fs_int("/dev/oprofile/", "pointer_size", 1); diff -Naur oprofile-0.9.1/daemon/opd_interface.h oprofile-0.9.1-passive/daemon/opd_interface.h --- oprofile-0.9.1/daemon/opd_interface.h 2005-04-13 19:14:17.000000000 -0700 +++ oprofile-0.9.1-passive/daemon/opd_interface.h 2006-08-23 17:45:00.000000000 -0700 @@ -8,6 +8,9 @@ * * @author John Levon * @author Philippe Elie + * Modified by Aravind Menon for Xen + * These modifications are: + * Copyright (C) 2005 Hewlett-Packard Co. */ #ifndef OPD_INTERFACE_H @@ -17,10 +20,14 @@ #define CPU_SWITCH_CODE 2 #define COOKIE_SWITCH_CODE 3 #define KERNEL_ENTER_SWITCH_CODE 4 -#define KERNEL_EXIT_SWITCH_CODE 5 -#define MODULE_LOADED_CODE 6 +#define USER_ENTER_SWITCH_CODE 5 +#define MODULE_LOADED_CODE 6 #define CTX_TGID_CODE 7 #define TRACE_BEGIN_CODE 8 -#define LAST_CODE 9 +/* Code 9 used to be TRACE_END_CODE which is not used anymore */ +/* Code 9 is now considered an unknown escape code */ +#define XEN_ENTER_SWITCH_CODE 10 +#define DOMAIN_SWITCH_CODE 11 +#define LAST_CODE 12 #endif /* OPD_INTERFACE_H */ diff -Naur oprofile-0.9.1/daemon/opd_kernel.c oprofile-0.9.1-passive/daemon/opd_kernel.c --- oprofile-0.9.1/daemon/opd_kernel.c 2004-01-29 12:00:26.000000000 -0800 +++ oprofile-0.9.1-passive/daemon/opd_kernel.c 2006-08-23 16:50:43.000000000 -0700 @@ -7,6 +7,9 @@ * * @author John Levon * @author Philippe Elie + * Modified by Aravind Menon for Xen + * These modifications are: + * Copyright (C) 2005 Hewlett-Packard Co. */ #include "opd_kernel.h" @@ -29,6 +32,13 @@ static struct kernel_image vmlinux_image; +static struct kernel_image xen_image; + +static LIST_HEAD(passive_vmlinux); +static LIST_HEAD(passive_xen); +static LIST_HEAD(passive_apps); +static LIST_HEAD(passive_modules); + void opd_create_vmlinux(char const * name, char const * arg) { /* vmlinux is *not* on the list of modules */ @@ -54,6 +64,107 @@ } } +void opd_create_xen(char const * name, char const * arg) +{ + int stat; + + /* xen is *not* on the list of modules */ + list_init(&xen_image.list); + + /* for no xen */ + if (no_xen) { + xen_image.name = "no-xen"; + return; + } + + xen_image.name = xstrdup(name); + + stat = sscanf(arg, "%llx,%llx", &xen_image.start, &xen_image.end); + + verbprintf(vmisc, "xen_start = %llx, xen_end = %llx\n", + xen_image.start, xen_image.end); + + if ( stat != 2 ) { + fprintf(stderr, "error: mis-parsed xen range: %llx-%llx\n", + xen_image.start, xen_image.end); + exit(EXIT_FAILURE); + } +} + +void opd_create_passive_domain(int id, char const * image_kernel, + char const * range, char const * image_xen) +{ + char file[64]; + struct kernel_image * image; + int stat; + + image = xmalloc(sizeof(struct kernel_image)); + image->name = xstrdup(image_kernel); + image->start = image->end = 0; + stat = sscanf(range, "%llx,%llx", &image->start, &image->end); + image->id = id; + list_add(&image->list, &passive_vmlinux); + + if ( stat != 2 ) { + fprintf(stderr, "error: mis-parsed passive domain range for " + "domain %d: %llx-%llx\n", id, image->start, image->end); + exit(EXIT_FAILURE); + } + + image = xmalloc(sizeof(struct kernel_image)); + image->name = xstrdup(image_xen); + image->start = xen_image.start; + image->end = xen_image.end; + image->id = id; + list_add(&image->list, &passive_xen); + + sprintf(file, "domain%d-apps", id); + image = xmalloc(sizeof(struct kernel_image)); + image->name = xstrdup(file); + image->start = 0; + image->end = 0; + image->id = id; + list_add(&image->list, &passive_apps); + + sprintf(file, "domain%d-modules", id); + image = xmalloc(sizeof(struct kernel_image)); + image->name = xstrdup(file); + image->start = 0; + image->end = 0; + image->id = id; + list_add(&image->list, &passive_modules); + +} + +void opd_create_passive(char const *setup_file) +{ + FILE *fp; + int id=0; + char image_kernel[128+1]; + char range[32+1]; + char image_xen[128+1]; + int stat; + + image_kernel[0] = range[0] = image_xen[0] = 0; + + fp = fopen(setup_file, "r"); + + if (!fp) { + fprintf(stderr, "error: Could not open Xen passive domain " + "setup file %s\n", setup_file); + exit(EXIT_FAILURE); + } + + while (1) { + stat = fscanf(fp, "%d %128s %32s %128s", &id, image_kernel, range, + image_xen); + if ( stat != 4 ) + return; + opd_create_passive_domain(id, image_kernel, range, image_xen); + } + + fclose(fp); +} /** * Allocate and initialise a kernel image description @@ -180,6 +291,65 @@ struct list_head * pos; struct kernel_image * image = &vmlinux_image; + if (current_domain != COORDINATOR_DOMAIN) { + /* We always rely on pc for identifying Xen samples + * since on Xen entry/exit cpu_mode may still + * indicate we are in kernel or user level while the + * pc belongs to xen address space */ + list_for_each(pos, &passive_xen) { + image = list_entry(pos, struct kernel_image, list); + if (image->id == current_domain + && image->start <= trans->pc + && image->end > trans->pc) + return image; + } + + /* for kernel and user level samples we rely on + * cpu_mode value (i.e. trans->in_kernel) + * Note however that we incremented trans->in_kernel + * when entering passive domain mode, Now vaid values + * are in range [1,3] */ + switch ( trans->in_kernel ) { + + /* kernel mode */ + case 2: + list_for_each(pos, &passive_vmlinux) { + image = list_entry(pos, struct kernel_image, list); + if ( (image->id == current_domain) + && ( (image->start == 0 && image->end == 0) + || (image->start <= trans->pc + && image->end > trans->pc) ) ) + return image; + } + /* if not in kernel image range then it should be a module */ + list_for_each(pos, &passive_modules) { + image = list_entry(pos, struct kernel_image, list); + if (image->id == current_domain) + return image; + } + /* This should not happen if the kernel and user level + oprofile code are sane and in sync */ + return NULL; + /* user mode */ + case 1: + list_for_each(pos, &passive_apps) { + image = list_entry(pos, struct kernel_image, list); + if (image->id == current_domain) + return image; + } + return NULL; + default: + printf("Unexpected error on passive mode: CPU mode is " + "%d for domain %d\n", trans->in_kernel, current_domain); + return NULL; + } + + + } + + if (xen_image.start <= trans->pc && xen_image.end > trans->pc) + return &xen_image; + if (no_vmlinux) return image; diff -Naur oprofile-0.9.1/daemon/opd_kernel.h oprofile-0.9.1-passive/daemon/opd_kernel.h --- oprofile-0.9.1/daemon/opd_kernel.h 2003-09-24 14:21:14.000000000 -0700 +++ oprofile-0.9.1-passive/daemon/opd_kernel.h 2006-08-22 09:26:41.000000000 -0700 @@ -7,6 +7,9 @@ * * @author John Levon * @author Philippe Elie + * Modified by Aravind Menon for Xen + * These modifications are: + * Copyright (C) 2005 Hewlett-Packard Co. */ #ifndef OPD_KERNEL_H @@ -20,6 +23,12 @@ /** create the kernel image */ void opd_create_vmlinux(char const * name, char const * arg); +/** create Xen image */ +void opd_create_xen(char const * name, char const * arg); + +/** create Xen passive domain images */ +void opd_create_passive(char const *setup_file); + /** opd_reread_module_info - parse /proc/modules for kernel modules */ void opd_reread_module_info(void); @@ -28,6 +37,7 @@ char * name; vma_t start; vma_t end; + int id; struct list_head list; }; diff -Naur oprofile-0.9.1/daemon/opd_sfile.c oprofile-0.9.1-passive/daemon/opd_sfile.c --- oprofile-0.9.1/daemon/opd_sfile.c 2005-05-25 17:00:02.000000000 -0700 +++ oprofile-0.9.1-passive/daemon/opd_sfile.c 2006-08-23 16:54:46.000000000 -0700 @@ -226,7 +226,7 @@ } /* we might need a kernel image start/end to hash on */ - if (trans->in_kernel) { + else if (trans->in_kernel) { ki = find_kernel_image(trans); if (!ki) { verbprintf(vsamples, "Lost kernel sample %llx\n", trans->pc); diff -Naur oprofile-0.9.1/daemon/opd_trans.c oprofile-0.9.1-passive/daemon/opd_trans.c --- oprofile-0.9.1/daemon/opd_trans.c 2005-05-25 17:00:02.000000000 -0700 +++ oprofile-0.9.1-passive/daemon/opd_trans.c 2006-08-23 16:56:07.000000000 -0700 @@ -7,6 +7,9 @@ * * @author John Levon * @author Philippe Elie + * Modified by Aravind Menon for Xen + * These modifications are: + * Copyright (C) 2005 Hewlett-Packard Co. */ #include "opd_trans.h" @@ -24,6 +27,8 @@ #include #include +int32_t current_domain = COORDINATOR_DOMAIN; + extern size_t kernel_pointer_size; @@ -210,6 +215,9 @@ { verbprintf(vmisc, "KERNEL_ENTER_SWITCH to kernel\n"); trans->in_kernel = 1; + /* if in passive domain mode cpu mode should be incremented */ + if (current_domain != COORDINATOR_DOMAIN) + trans->in_kernel++; clear_trans_current(trans); /* subtlety: we must keep trans->cookie cached, * even though it's meaningless for the kernel - @@ -219,10 +227,13 @@ } -static void code_kernel_exit(struct transient * trans) +static void code_user_enter(struct transient * trans) { - verbprintf(vmisc, "KERNEL_EXIT_SWITCH to user-space\n"); + verbprintf(vmisc, "USER_ENTER_SWITCH to user-space\n"); trans->in_kernel = 0; + /* if in passive domain mode cpu mode should be incremented */ + if (current_domain != COORDINATOR_DOMAIN) + trans->in_kernel++; clear_trans_current(trans); clear_trans_last(trans); } @@ -248,6 +259,37 @@ trans->tracing = TRACING_START; } +static void code_xen_enter(struct transient *trans) +{ + verbprintf(vmisc, "XEN_ENTER_SWITCH to xen\n"); + trans->in_kernel = 2; + /* if in passive domain mode cpu mode should be incremented */ + if (current_domain != COORDINATOR_DOMAIN) + trans->in_kernel++; + trans->current = NULL; + /* subtlety: we must keep trans->cookie cached, even though it's + * meaningless for Xen - same reason as for kernel + */ +} + +static void code_domain_switch(struct transient *trans) +{ + /* While processing passive domain samples we ensure (in_kernel!=0) + * We do this in order to ignore cookies for passive domain samples + * But, we have to remember the kernel value for coordinator domain, + * so we do the safe thing: increment when leaving the coordinator + * domain and decrement when returning to it + */ + if (current_domain == COORDINATOR_DOMAIN) + trans->in_kernel++; + + trans->current = NULL; + current_domain = (int32_t) pop_buffer_value(trans); + + /* If returning to coordinator domain restore the kernel value */ + if (current_domain == COORDINATOR_DOMAIN) + trans->in_kernel--; +} typedef void (*handler_t)(struct transient *); @@ -257,11 +299,14 @@ &code_cpu_switch, &code_cookie_switch, &code_kernel_enter, - &code_kernel_exit, + &code_user_enter, &code_module_loaded, /* tgid handled differently */ &code_unknown, &code_trace_begin, + &code_unknown, + &code_xen_enter, + &code_domain_switch, }; diff -Naur oprofile-0.9.1/daemon/opd_trans.h oprofile-0.9.1-passive/daemon/opd_trans.h --- oprofile-0.9.1/daemon/opd_trans.h 2005-05-02 08:06:59.000000000 -0700 +++ oprofile-0.9.1-passive/daemon/opd_trans.h 2006-08-22 10:04:52.000000000 -0700 @@ -15,6 +15,10 @@ #include "opd_cookie.h" #include "op_types.h" +#define COORDINATOR_DOMAIN -1 + +extern int32_t current_domain; + struct sfile; struct anon_mapping; diff -Naur oprofile-0.9.1/daemon/oprofiled.c oprofile-0.9.1-passive/daemon/oprofiled.c --- oprofile-0.9.1/daemon/oprofiled.c 2005-03-29 09:10:51.000000000 -0800 +++ oprofile-0.9.1-passive/daemon/oprofiled.c 2006-08-22 09:37:36.000000000 -0700 @@ -7,6 +7,9 @@ * * @author John Levon * @author Philippe Elie + * Modified by Aravind Menon for Xen + * These modifications are: + * Copyright (C) 2005 Hewlett-Packard Co. */ #include "config.h" @@ -60,6 +63,10 @@ int no_vmlinux; char * vmlinux; char * kernel_range; +int no_xen; +char * xenimage; +char * xen_range; +char * xen_passive_setup; static char * verbose; static char * binary_name_filter; static char * events; @@ -75,7 +82,10 @@ { "kernel-range", 'r', POPT_ARG_STRING, &kernel_range, 0, "Kernel VMA range", "start-end", }, { "vmlinux", 'k', POPT_ARG_STRING, &vmlinux, 0, "vmlinux kernel image", "file", }, { "no-vmlinux", 0, POPT_ARG_NONE, &no_vmlinux, 0, "vmlinux kernel image file not available", NULL, }, + { "xen-range", 0, POPT_ARG_STRING, &xen_range, 0, "Xen VMA range", "start-end", }, + { "xen-image", 0, POPT_ARG_STRING, &xenimage, 0, "Xen image", "file", }, { "image", 0, POPT_ARG_STRING, &binary_name_filter, 0, "image name filter", "profile these comma separated image" }, + { "xen-passive-setup", 0, POPT_ARG_STRING, &xen_passive_setup, 0, "Xen passive domain setup file", "filename", }, { "separate-lib", 0, POPT_ARG_INT, &separate_lib, 0, "separate library samples for each distinct application", "[0|1]", }, { "separate-kernel", 0, POPT_ARG_INT, &separate_kernel, 0, "separate kernel samples for each distinct application", "[0|1]", }, { "separate-thread", 0, POPT_ARG_INT, &separate_thread, 0, "thread-profiling mode", "[0|1]" }, @@ -407,7 +417,26 @@ poptPrintHelp(optcon, stderr, 0); exit(EXIT_FAILURE); } - + + if (!xenimage || !strcmp("", xenimage)) { + no_xen = 1; + } else { + no_xen = 0; + + /* canonicalise xen image filename. */ + tmp = xmalloc(PATH_MAX); + if (realpath(xenimage, tmp)) + xenimage = tmp; + else + free(tmp); + + if (!xen_range || !strcmp("", xen_range)) { + fprintf(stderr, "oprofiled: no Xen VMA range specified.\n"); + poptPrintHelp(optcon, stderr, 0); + exit(EXIT_FAILURE); + } + } + opd_parse_events(events); opd_parse_image_filter(); diff -Naur oprofile-0.9.1/daemon/oprofiled.h oprofile-0.9.1-passive/daemon/oprofiled.h --- oprofile-0.9.1/daemon/oprofiled.h 2005-04-26 16:49:45.000000000 -0700 +++ oprofile-0.9.1-passive/daemon/oprofiled.h 2006-08-22 08:46:33.000000000 -0700 @@ -7,6 +7,9 @@ * * @author John Levon * @author Philippe Elie + * Modified by Aravind Menon for Xen + * These modifications are: + * Copyright (C) 2005 Hewlett-Packard Co. */ #ifndef OPROFILED_H @@ -58,5 +61,9 @@ extern int no_vmlinux; extern char * vmlinux; extern char * kernel_range; +extern int no_xen; +extern char * xenimage; +extern char * xen_range; +extern char * xen_passive_setup; #endif /* OPROFILED_H */ diff -Naur oprofile-0.9.1/doc/opcontrol.1.in oprofile-0.9.1-passive/doc/opcontrol.1.in --- oprofile-0.9.1/doc/opcontrol.1.in 2005-04-28 14:09:21.000000000 -0700 +++ oprofile-0.9.1-passive/doc/opcontrol.1.in 2006-08-21 15:31:41.000000000 -0700 @@ -105,7 +105,8 @@ .BI "--callgraph=#depth" Enable callgraph sample collection with a maximum depth. Use 0 to disable callgraph profiling. This option is currently only usable on x86, using a -2.6+ kernel with callgraph support enabled. +2.6+ kernel with callgraph support enabled. This option is not yet supported +on Xen. .br .TP .BI "--image="[name,name...|"all"] @@ -129,8 +130,52 @@ .BI "--kernel-range="start,end Set kernel range vma address in hexadecimal. +.SH OPTIONS (specific to Xen) +.TP +.BI "--xen="file +Xen image +.br +.TP +.BI "--active-domains=" +List of domain ids participating in a multi-domain profiling session. +Each of the specified domains must run an instance of oprofile. The +sequence of opcontrol commands in each domain must follow a given +order which is specified in the oprofile user manual. If +more than one domain is specified in they should be separated using +commas. This option can only be used in domain 0 which is the only domain +that can coordinate a multi-domain profiling session. Including domain 0 in +the list of active domains is optional. (e.g. --active-domains=2,5,6 and +--active-domains=0,2,5,6 are equivalent). +This option can only be specified +if --start-daemon is also specified and it is only +valid for the current run of the oprofile daemon; e.g. the list +of active domains is not persistent. +.br +.TP +.BI "--passive-domains=" or "--domains=" +List of domain ids to be profiled, separated by commas. +As opposed to the --active-domains option, the domains specified with this +option do not need to run oprofile. This makes +profiling multiple domains easier. However, with the passive-domains option, +samples in user level processes and kernel modules cannot be +mapped to specific symbols and are aggregated +under a generic class. Both --active-domains and --passive-domains +options can be specified in the same command, but the same domain cannot be +specified in both options. This option can only be specified if either --start +or --start-daemon is specified on the same command and it is only valid for +the current run of the oprofile daemon; e.g. the list of passive domains is +not persistent. +.br +.TP +.BI "--passive-images=" or "--domains-images=" +List of kernel images associated with the domains specified in the +--passive-domains option, also separated by commas. The association +between the images and domains is based on the order they are +specified in both options. +.br + .SH ENVIRONMENT -No special environment variables are recognised by opreport. +No special environment variables are recognised by opcontrol. .SH FILES .TP diff -Naur oprofile-0.9.1/utils/opcontrol oprofile-0.9.1-passive/utils/opcontrol --- oprofile-0.9.1/utils/opcontrol 2005-06-16 12:12:07.000000000 -0700 +++ oprofile-0.9.1-passive/utils/opcontrol 2006-08-23 17:25:13.000000000 -0700 @@ -144,6 +144,17 @@ --buffer-size=num kernel buffer size in sample units --cpu-buffer-size=num per-cpu buffer size in units (2.6 only) --note-table-size kernel notes buffer size in notes units (2.4 only) + + --xen=file Xen image (for Xen only) + --active-domains=id[,ids] list of domains in multiple domain profiling session (Xen) + (detailed profiling of user level and kernel modules code) + (requires running oprofile on these domains) + --passive-domains=id[,ids] list of domains to be profiled (Xen). + or --domains=id[,ids] (coarse profiling of user level and kernel modules code) + (no need to run oprofile on these domains) + --passive-images=file[,files] list of kernel images associated with each passive domain + or + --domain-images=file[,files] " >&2 } @@ -246,6 +257,7 @@ CPU_BUF_SIZE=0 NOTE_SIZE=0 VMLINUX= + XENIMAGE="none" VERBOSE="" SEPARATE_LIB=0 SEPARATE_KERNEL=0 @@ -259,6 +271,9 @@ SETUP_DIR="/root/.oprofile" SETUP_FILE="$SETUP_DIR/daemonrc" + # location for passing info about passive domains to daemon + PASSIVE_SETUP_FILE="$SETUP_DIR/xendomain.setup" + CPUTYPE=`cat $MOUNT/cpu_type` OP_COUNTERS=`ls $MOUNT/ | grep "^[0-9]\+\$" | tr "\n" " "` NR_CHOSEN=0 @@ -326,6 +341,7 @@ echo "NOTE_SIZE=$NOTE_SIZE" >> $SETUP_FILE fi echo "CALLGRAPH=$CALLGRAPH" >> $SETUP_FILE + echo "XENIMAGE=$XENIMAGE" >> $SETUP_FILE } @@ -363,7 +379,7 @@ } -check_valid_args() +check_valid_vmlinux() { if test -z "$VMLINUX"; then echo "No vmlinux file specified. You must specify the correct vmlinux file, e.g." >&2 @@ -387,34 +403,134 @@ } -# get start and end points of the kernel -get_kernel_range() +# similar check for Xen image +check_valid_xen() { - if test ! -z "$KERNEL_RANGE"; then - return; + if test -f "$XENIMAGE"; then + return fi - if test "$VMLINUX" = "none"; then + if test "$XENIMAGE" = "none"; then + return + fi + + echo "The specified XenImage file \"$XENIMAGE\" does not exist." >&2 + exit 1 +} + + +# get start and end points of a file image (linux kernel or xen) +# get_image_range parameter: $1=type_of_image (linux or xen) +get_image_range() +{ + if test "$1" = "xen"; then + if test ! -z "$XEN_RANGE"; then + return; + fi + FILE_IMAGE="$XENIMAGE" + else + if test ! -z "$KERNEL_RANGE"; then + return; + fi + FILE_IMAGE="$VMLINUX" + fi + + if test "$FILE_IMAGE" = "none"; then return; fi # start at the start of .text and then continue to the end - range_info=`objdump -h $VMLINUX 2>/dev/null | grep " .text "` + range_info=`objdump -h $FILE_IMAGE 2>/dev/null | grep " .text "` tmp1=`echo $range_info | awk '{print $4}'` tmp_length=`echo $range_info | awk '{print $3}'` - tmp2=`objdump -h $VMLINUX --adjust-vma=0x$tmp_length 2>/dev/null | grep " .text " | awk '{print $4}'` + tmp2=`objdump -h $FILE_IMAGE --adjust-vma=0x$tmp_length 2>/dev/null | grep " .text " | awk '{print $4}'` if test -z "$tmp1" -o -z "$tmp2"; then - echo "The specified file $VMLINUX does not seem to be valid" >&2 - echo "Make sure you are using vmlinux not vmlinuz" >&2 + echo "The specified file $FILE_IMAGE does not seem to be valid" >&2 + echo "Make sure you are using the non-compressed image file (e.g. vmlinux not vmlinuz)" >&2 vecho "found start as \"$tmp1\", end as \"$tmp2\"" >&2 exit 1 fi - KERNEL_RANGE="`echo $tmp1`,`echo $tmp2`" - vecho "KERNEL_RANGE $KERNEL_RANGE" + if test "$1" = "xen"; then + XEN_RANGE="`echo $tmp1`,`echo $tmp2`" + vecho "XEN_RANGE $XEN_RANGE" + else + KERNEL_RANGE="`echo $tmp1`,`echo $tmp2`" + vecho "KERNEL_RANGE $KERNEL_RANGE" + fi } +set_passive_domain() +{ + DOMAIN_ID=$1 + FILE_IMAGE=$2 + XEN_IMAGE=$3 + + if test "$FILE_IMAGE" = "none"; then + RANGE="0,0" + FILE_IMAGE="domain$DOMAIN_ID-kernel" + else + # Find VMA range for passive domain kernel image + range_info=`objdump -h $FILE_IMAGE 2>/dev/null | grep " .text "` + tmp1=`echo $range_info | awk '{print $4}'` + tmp_length=`echo $range_info | awk '{print $3}'` + tmp2=`objdump -h $FILE_IMAGE --adjust-vma=0x$tmp_length 2>/dev/null | grep " .text " | awk '{print $4}'` + + if test -z "$tmp1" -o -z "$tmp2"; then + echo "The specified file $FILE_IMAGE does not seem to be valid" >&2 + echo "Make sure you are using the non-compressed image file (e.g. vmlinux not vmlinuz)" >&2 + vecho "found start as \"$tmp1\", end as \"$tmp2\"" >&2 + exit 1 + fi + RANGE="`echo $tmp1`,`echo $tmp2`" + fi + echo " $DOMAIN_ID $FILE_IMAGE $RANGE $XEN_IMAGE" >> $PASSIVE_SETUP_FILE +} + + +set_passive_domain_config() +{ + + create_dir "$SETUP_DIR" + + touch $PASSIVE_SETUP_FILE + chmod 644 $PASSIVE_SETUP_FILE + >$PASSIVE_SETUP_FILE + + NDOMAINS=`echo "$PASSIVE_DOMAINS" | awk -F',' '{print NF}'` + + if test -n "$PASSIVE_IMAGES"; then + NIMAGES=`echo "$PASSIVE_IMAGES" | awk -F',' '{print NF}'` + if [ $NDOMAINS != $NIMAGES ]; then + echo "# of passive domains and # of passive images doesn't match." >&2 + do_help + exit 1 + fi + + for (( i=1; i<=$NDOMAINS; i++ )); do + ID=`echo "$PASSIVE_DOMAINS" | awk -F"," '{print $'$i'}'` + FILE=`echo "$PASSIVE_IMAGES" | awk -F',' '{print $'$i'}'` + if test ! -f "$FILE"; then + echo "Image $FILE for passive domain $ID not found." >&2 + return 1 + fi + LNK_KERNEL=/boot/domain$ID-kernel + ln -sf $FILE $LNK_KERNEL + LNK_XEN=/boot/domain$ID-xen + ln -sf $XENIMAGE $LNK_XEN + set_passive_domain $ID $LNK_KERNEL $LNK_XEN + done + else + for (( i=1; i<=$NDOMAINS; i++ )); do + ID=`echo "$PASSIVE_DOMAINS" | awk -F"," '{print $'$i'}'` + LNK_XEN=/boot/domain$ID-xen + set_passive_domain $ID none $LNK_XEN + done + + fi +} + # validate --separate= parameters. This function is called with IFS=, # so on each argument is splitted @@ -692,7 +808,7 @@ VMLINUX=$val DO_SETUP=yes # check validity - get_kernel_range + get_image_range "linux" ;; --no-vmlinux) VMLINUX=none @@ -703,6 +819,27 @@ KERNEL_RANGE=$val DO_SETUP=yes ;; + --xen) + error_if_empty $arg $val + XENIMAGE=$val + DO_SETUP=yes + get_image_range "xen" + ;; + --active-domains) + error_if_empty $arg $val + ACTIVE_DOMAINS=$val + DO_SETUP=yes + ;; + --passive-domains|--domains) + error_if_empty $arg $val + PASSIVE_DOMAINS=$val + DO_SETUP=yes + ;; + --passive-images|--domain-images) + error_if_empty $arg $val + PASSIVE_IMAGES=$val + DO_SETUP=yes + ;; --note-table-size) error_if_empty $arg $val if test $"KERNEL_SUPPORT" = "yes"; then @@ -775,6 +912,16 @@ exit 1 fi fi + + if test -n "$ACTIVE_DOMAINS" -a "$START_DAEMON" != "yes"; then + echo "Option \"--active-domains\" can only be used with option \"-start-daemon\"." >&2 + exit 1 + fi + + if test -n "$PASSIVE_DOMAINS" -a "$START_DAEMON" != "yes" -a "$START" != "yes"; then + echo "Option \"--passive-domains\" or "--domains" can only be used with option \"--start-daemon\" or \"--start\"." >&2 + exit 1 + fi } @@ -974,6 +1121,23 @@ fi fi + if test -n "$ACTIVE_DOMAINS"; then + if test "$KERNEL_SUPPORT" = "yes"; then + echo $ACTIVE_DOMAINS >$MOUNT/active_domains + else + echo "active-domains not supported - ignored" >&2 + fi + fi + + if test -n "$PASSIVE_DOMAINS"; then + if test "$KERNEL_SUPPORT" = "yes"; then + echo $PASSIVE_DOMAINS >$MOUNT/passive_domains + set_passive_domain_config + else + echo "passive-domains not supported - ignored" >&2 + fi + fi + if test $NOTE_SIZE != 0; then set_param notesize $NOTE_SIZE fi @@ -1066,8 +1230,10 @@ do_setup do_load_setup - check_valid_args - get_kernel_range + check_valid_vmlinux + check_valid_xen + get_image_range "linux" + get_image_range "xen" do_param_setup OPD_ARGS=" \ @@ -1084,10 +1250,18 @@ OPD_ARGS="$OPD_ARGS --vmlinux=$VMLINUX --kernel-range=$KERNEL_RANGE" fi + if ! test "$XENIMAGE" = "none"; then + OPD_ARGS="$OPD_ARGS --xen-image=$XENIMAGE --xen-range=$XEN_RANGE" + fi + if ! test -z "$IMAGE_FILTER"; then OPD_ARGS="$OPD_ARGS --image=$IMAGE_FILTER" fi + if ! test -z "$PASSIVE_DOMAINS"; then + OPD_ARGS="$OPD_ARGS --xen-passive-setup=$PASSIVE_SETUP_FILE" + fi + if test -n "$VERBOSE"; then OPD_ARGS="$OPD_ARGS --verbose=$VERBOSE" fi @@ -1294,6 +1468,8 @@ move_and_remove $SAMPLES_DIR/current/{root} hup_daemon + + rm -f /boot/domain-*-kernel /boot/domain-*-xen } @@ -1324,7 +1500,8 @@ fi if test "$SETUP" = "yes"; then - check_valid_args + check_valid_vmlinux + check_valid_xen do_save_setup fi