WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] xentrace: make xentrace and xenmon work o

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] xentrace: make xentrace and xenmon work on Solaris and *BSD.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 22 Nov 2007 12:00:24 -0800
Delivery-date: Thu, 22 Nov 2007 12:01:40 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1195232885 0
# Node ID e2f5b5b24e07348d0f5e3d68569e00a978a251e8
# Parent  270bd0fc3669413bd22d9aca9b6735486642aeeb
xentrace: make xentrace and xenmon work on Solaris and *BSD.
 - Use getopt() to get rid of argp dependency which does not exist
   on Solaris and *BSD. Done by Tariq Magdon-Ismail.
 - Minor modifications by me (Christoph) to make it also work on *BSD.
 - Tested on Linux by me (Christoph). No functional change on Linux.
 - Tariq ok'd BSD modifications for Solaris
 - Tariq ok'd submission by me :)

Signed-off-by: Tariq Magdon-Ismail <tariqmi@xxxxxxx>
Signed-off-by: Christoph Egger <Christoph.Egger@xxxxxxx>
---
 tools/xenmon/xenbaked.c   |  197 ++++++++++++++++---------------
 tools/xentrace/xenctx.c   |   11 +
 tools/xentrace/xentrace.c |  288 ++++++++++++++++++++++------------------------
 3 files changed, 247 insertions(+), 249 deletions(-)

diff -r 270bd0fc3669 -r e2f5b5b24e07 tools/xenmon/xenbaked.c
--- a/tools/xenmon/xenbaked.c   Fri Nov 16 17:05:20 2007 +0000
+++ b/tools/xenmon/xenbaked.c   Fri Nov 16 17:08:05 2007 +0000
@@ -37,12 +37,12 @@
 #include <fcntl.h>
 #include <unistd.h>
 #include <errno.h>
-#include <argp.h>
 #include <signal.h>
 #include <xenctrl.h>
 #include <xen/xen.h>
 #include <string.h>
 #include <sys/select.h>
+#include <getopt.h>
 
 #define PERROR(_m, _a...)                                       \
 do {                                                            \
@@ -58,7 +58,6 @@ typedef struct { int counter; } atomic_t
 #include <xen/trace.h>
 #include "xenbaked.h"
 
-extern FILE *stderr;
 
 /***** Compile time configuration of defaults ********************************/
 
@@ -78,7 +77,6 @@ extern FILE *stderr;
 /***** The code **************************************************************/
 
 typedef struct settings_st {
-    char *outfile;
     struct timespec poll_sleep;
     unsigned long new_data_thresh;
     unsigned long ms_per_sample;
@@ -230,10 +228,10 @@ void dump_stats(void)
     }
 
     printf("processed %d total records in %d seconds (%ld per second)\n",
-           rec_count, (int)run_time, rec_count/run_time);
+           rec_count, (int)run_time, (long)(rec_count/run_time));
 
     printf("woke up %d times in %d seconds (%ld per second)\n", wakeups,
-          (int) run_time, wakeups/run_time);
+          (int) run_time, (long)(wakeups/run_time));
 
     check_gotten_sum();
 }
@@ -535,58 +533,106 @@ int monitor_tbufs(void)
 
 
 /******************************************************************************
- * Various declarations / definitions GNU argp needs to do its work
+ * Command line handling
  *****************************************************************************/
 
-
-/* command parser for GNU argp - see GNU docs for more info */
-error_t cmd_parser(int key, char *arg, struct argp_state *state)
-{
-    settings_t *setup = (settings_t *)state->input;
-
-    switch ( key )
+const char *program_version     = "xenbaked v1.4";
+const char *program_bug_address = "<rob.gardner@xxxxxx>";
+
+#define xstr(x) str(x)
+#define str(x) #x
+
+void usage(void)
+{
+#define USAGE_STR \
+"Usage: xenbaked [OPTION...]\n" \
+"Tool to capture and partially process Xen trace buffer data\n" \
+"\n" \
+"  -m, --ms_per_sample=MS     Specify the number of milliseconds per sample\n" 
\
+"                             (default " xstr(MS_PER_SAMPLE) ").\n" \
+"  -s, --poll-sleep=p         Set sleep time, p, in milliseconds between\n" \
+"                             polling the trace buffer for new data\n" \
+"                             (default " xstr(POLL_SLEEP_MILLIS) ").\n" \
+"  -t, --log-thresh=l         Set number, l, of new records required to\n" \
+"                             trigger a write to output (default " \
+                              xstr(NEW_DATA_THRESH) ").\n" \
+"  -?, --help                 Show this message\n" \
+" -V, --version              Print program version\n" \
+"\n" \
+"This tool is used to capture trace buffer data from Xen.  The data is\n" \
+"saved in a shared memory structure to be further processed by xenmon.\n"
+
+    printf(USAGE_STR);
+    printf("\nReport bugs to %s\n", program_bug_address);
+
+    exit(EXIT_FAILURE);
+}
+
+/* convert the argument string pointed to by arg to a long int representation 
*/
+long argtol(const char *restrict arg, int base)
+{
+    char *endp; 
+    long val;
+
+    errno = 0;
+    val = strtol(arg, &endp, base);
+
+    if (errno != 0) {
+        fprintf(stderr, "Invalid option argument: %s\n", arg);
+        fprintf(stderr, "Error: %s\n\n", strerror(errno));
+        usage();
+    } else if (endp == arg || *endp != '\0') {
+        fprintf(stderr, "Invalid option argument: %s\n\n", arg);
+        usage();
+    }
+
+    return val;
+}
+
+/* parse command line arguments */
+void parse_args(int argc, char **argv)
+{
+    int option;
+    static struct option long_options[] = {
+        { "log-thresh",    required_argument, 0, 't' },
+        { "poll-sleep",    required_argument, 0, 's' },
+        { "ms_per_sample", required_argument, 0, 'm' },
+        { "help",          no_argument,       0, '?' },
+        { "version",       no_argument,       0, 'V' },
+        { 0, 0, 0, 0 }
+    };
+
+    while ( (option = getopt_long(argc, argv, "m:s:t:?V",
+                    long_options, NULL)) != -1)
     {
-    case 't': /* set new records threshold for logging */
-    {
-        char *inval;
-        setup->new_data_thresh = strtol(arg, &inval, 0);
-        if ( inval == arg )
-            argp_usage(state);
-    }
-    break;
-
-    case 's': /* set sleep time (given in milliseconds) */
-    {
-        char *inval;
-        setup->poll_sleep = millis_to_timespec(strtol(arg, &inval, 0));
-        if ( inval == arg )
-            argp_usage(state);
-    }
-    break;
-
-    case 'm': /* set ms_per_sample */
-    {
-        char *inval;
-        setup->ms_per_sample = strtol(arg, &inval, 0);
-        if ( inval == arg )
-            argp_usage(state);
-    }
-    break;
-
-    case ARGP_KEY_ARG:
-    {
-        if ( state->arg_num == 0 )
-            setup->outfile = arg;
-        else
-            argp_usage(state);
-    }
-    break;
-
-    default:
-        return ARGP_ERR_UNKNOWN;
-    }
-
-    return 0;
+        switch ( option )
+        {
+            case 't': /* set new records threshold for logging */
+                opts.new_data_thresh = argtol(optarg, 0);
+                break;
+
+            case 's': /* set sleep time (given in milliseconds) */
+                opts.poll_sleep = millis_to_timespec(argtol(optarg, 0));
+                break;
+
+            case 'm': /* set ms_per_sample */
+                opts.ms_per_sample = argtol(optarg, 0);
+                break;
+
+            case 'V': /* print program version */
+                printf("%s\n", program_version);
+                exit(EXIT_SUCCESS);
+                break;
+
+            default:
+               usage(); 
+        }
+    }
+
+    /* all arguments should have been processed */
+    if (optind != argc) {
+        usage();
+    }
 }
 
 #define SHARED_MEM_FILE "/var/run/xenq-shm"
@@ -637,59 +683,18 @@ void alloc_qos_data(int ncpu)
 }
 
 
-#define xstr(x) str(x)
-#define str(x) #x
-
-const struct argp_option cmd_opts[] =
-{
-    { .name = "log-thresh", .key='t', .arg="l",
-      .doc =
-      "Set number, l, of new records required to trigger a write to output "
-      "(default " xstr(NEW_DATA_THRESH) ")." },
-
-    { .name = "poll-sleep", .key='s', .arg="p",
-      .doc = 
-      "Set sleep time, p, in milliseconds between polling the trace buffer "
-      "for new data (default " xstr(POLL_SLEEP_MILLIS) ")." },
-
-    { .name = "ms_per_sample", .key='m', .arg="MS",
-      .doc = 
-      "Specify the number of milliseconds per sample "
-      " (default " xstr(MS_PER_SAMPLE) ")." },
-
-    {0}
-};
-
-const struct argp parser_def =
-{
-    .options = cmd_opts,
-    .parser = cmd_parser,
-    //    .args_doc = "[output file]",
-    .doc =
-    "Tool to capture and partially process Xen trace buffer data"
-    "\v"
-    "This tool is used to capture trace buffer data from Xen.  The data is "
-    "saved in a shared memory structure to be further processed by xenmon."
-};
-
-
-const char *argp_program_version     = "xenbaked v1.4";
-const char *argp_program_bug_address = "<rob.gardner@xxxxxx>";
-
-
 int main(int argc, char **argv)
 {
     int ret;
     struct sigaction act;
 
     time(&start_time);
-    opts.outfile = 0;
     opts.poll_sleep = millis_to_timespec(POLL_SLEEP_MILLIS);
     opts.new_data_thresh = NEW_DATA_THRESH;
     opts.ms_per_sample = MS_PER_SAMPLE;
     opts.cpu_freq = CPU_FREQ;
 
-    argp_parse(&parser_def, argc, argv, 0, 0, &opts);
+    parse_args(argc, argv);
     fprintf(stderr, "ms_per_sample = %ld\n", opts.ms_per_sample);
 
 
diff -r 270bd0fc3669 -r e2f5b5b24e07 tools/xentrace/xenctx.c
--- a/tools/xentrace/xenctx.c   Fri Nov 16 17:05:20 2007 +0000
+++ b/tools/xentrace/xenctx.c   Fri Nov 16 17:08:05 2007 +0000
@@ -18,7 +18,6 @@
 #include <fcntl.h>
 #include <unistd.h>
 #include <errno.h>
-#include <argp.h>
 #include <signal.h>
 #include <string.h>
 #include <inttypes.h>
@@ -32,10 +31,15 @@ int stack_trace = 0;
 int stack_trace = 0;
 
 #if defined (__i386__)
+#if defined (__OpenBSD__)
+#define FMT_SIZE_T             "%08lx"
+#define INSTR_POINTER(regs)    (unsigned long)(regs->eip)
+#else
 #define FMT_SIZE_T             "%08x"
+#define INSTR_POINTER(regs)    (regs->eip)
+#endif
 #define STACK_POINTER(regs)    (regs->esp)
 #define FRAME_POINTER(regs)    (regs->ebp)
-#define INSTR_POINTER(regs)    (regs->eip)
 #define STACK_ROWS             4
 #define STACK_COLS             8
 #elif defined (__x86_64__)
@@ -622,7 +626,8 @@ void print_stack(vcpu_guest_context_t *c
         printf("Stack Trace:\n");
     else
         printf("Call Trace:\n");
-    printf("%c [<" FMT_SIZE_T ">] ", stack_trace ? '*' : ' ', 
INSTR_POINTER(regs));
+    printf("%c [<" FMT_SIZE_T ">] ",
+        stack_trace ? '*' : ' ', INSTR_POINTER(regs));
 
     print_symbol(INSTR_POINTER(regs));
     printf(" <--\n");
diff -r 270bd0fc3669 -r e2f5b5b24e07 tools/xentrace/xentrace.c
--- a/tools/xentrace/xentrace.c Fri Nov 16 17:05:20 2007 +0000
+++ b/tools/xentrace/xentrace.c Fri Nov 16 17:08:05 2007 +0000
@@ -18,10 +18,10 @@
 #include <fcntl.h>
 #include <unistd.h>
 #include <errno.h>
-#include <argp.h>
 #include <signal.h>
 #include <inttypes.h>
 #include <string.h>
+#include <getopt.h>
 #include <assert.h>
 
 #include <xen/xen.h>
@@ -37,7 +37,6 @@ do {                                    
     errno = __saved_errno;                                      \
 } while (0)
 
-extern FILE *stderr;
 
 /***** Compile time configuration of defaults ********************************/
 
@@ -411,166 +410,155 @@ int monitor_tbufs(int outfd)
 
 
 /******************************************************************************
- * Various declarations / definitions GNU argp needs to do its work
+ * Command line handling
  *****************************************************************************/
 
-int parse_evtmask(char *arg, struct argp_state *state)
-{
-    settings_t *setup = (settings_t *)state->input;
-    char *inval;
-
+#define xstr(x) str(x)
+#define str(x) #x
+
+const char *program_version     = "xentrace v1.1";
+const char *program_bug_address = "<mark.a.williamson@xxxxxxxxx>";
+
+void usage(void)
+{
+#define USAGE_STR \
+"Usage: xentrace [OPTION...] [output file]\n" \
+"Tool to capture Xen trace buffer data\n" \
+"\n" \
+"  -c, --cpu-mask=c        Set cpu-mask\n" \
+"  -e, --evt-mask=e        Set evt-mask\n" \
+"  -s, --poll-sleep=p      Set sleep time, p, in milliseconds between\n" \
+"                          polling the trace buffer for new data\n" \
+"                          (default " xstr(POLL_SLEEP_MILLIS) ").\n" \
+"  -S, --trace-buf-size=N  Set trace buffer size in pages (default " \
+                           xstr(DEFAULT_TBUF_SIZE) ").\n" \
+"                          N.B. that the trace buffer cannot be resized.\n" \
+"                          if it has already been set this boot cycle,\n" \
+"                          this argument will be ignored.\n" \
+"  -t, --log-thresh=l      Set number, l, of new records required to\n" \
+"                          trigger a write to output (default " \
+                           xstr(NEW_DATA_THRESH) ").\n" \
+"  -?, --help              Show this message\n" \
+"  -V, --version           Print program version\n" \
+"\n" \
+"This tool is used to capture trace buffer data from Xen. The\n" \
+"data is output in a binary format, in the following order:\n" \
+"\n" \
+"  CPU(uint) TSC(uint64_t) EVENT(uint32_t) D1 D2 D3 D4 D5 (all uint32_t)\n" \
+"\n" \
+"The output should be parsed using the tool xentrace_format,\n" \
+"which can produce human-readable output in ASCII format.\n" 
+
+    printf(USAGE_STR);
+    printf("\nReport bugs to %s\n", program_bug_address);
+
+    exit(EXIT_FAILURE);
+}
+
+/* convert the argument string pointed to by arg to a long int representation 
*/
+long argtol(const char *restrict arg, int base)
+{
+    char *endp;
+    long val;
+
+    errno = 0;
+    val = strtol(arg, &endp, base);
+    
+    if (errno != 0) {
+        fprintf(stderr, "Invalid option argument: %s\n", arg);
+        fprintf(stderr, "Error: %s\n\n", strerror(errno));
+        usage();
+    } else if (endp == arg || *endp != '\0') {
+        fprintf(stderr, "Invalid option argument: %s\n\n", arg);
+        usage();
+    }
+
+    return val;
+}
+
+int parse_evtmask(char *arg)
+{
     /* search filtering class */
     if (strcmp(arg, "gen") == 0){ 
-        setup->evt_mask |= TRC_GEN;
+        opts.evt_mask |= TRC_GEN;
     } else if(strcmp(arg, "sched") == 0){ 
-        setup->evt_mask |= TRC_SCHED;
+        opts.evt_mask |= TRC_SCHED;
     } else if(strcmp(arg, "dom0op") == 0){ 
-        setup->evt_mask |= TRC_DOM0OP;
+        opts.evt_mask |= TRC_DOM0OP;
     } else if(strcmp(arg, "hvm") == 0){ 
-        setup->evt_mask |= TRC_HVM;
+        opts.evt_mask |= TRC_HVM;
     } else if(strcmp(arg, "all") == 0){ 
-        setup->evt_mask |= TRC_ALL;
+        opts.evt_mask |= TRC_ALL;
     } else {
-        setup->evt_mask = strtol(arg, &inval, 0);
-        if ( inval == arg )
-            argp_usage(state);
+        opts.evt_mask = argtol(arg, 0);
     }
 
     return 0;
-
-}
-
-/* command parser for GNU argp - see GNU docs for more info */
-error_t cmd_parser(int key, char *arg, struct argp_state *state)
-{
-    settings_t *setup = (settings_t *)state->input;
-
-    switch ( key )
-    {
-    case 't': /* set new records threshold for logging */
-    {
-        char *inval;
-        setup->new_data_thresh = strtol(arg, &inval, 0);
-        if ( inval == arg )
-            argp_usage(state);
-    }
-    break;
-
-    case 's': /* set sleep time (given in milliseconds) */
-    {
-        char *inval;
-        setup->poll_sleep = millis_to_timespec(strtol(arg, &inval, 0));
-        if ( inval == arg )
-            argp_usage(state);
-    }
-    break;
-
-    case 'c': /* set new cpu mask for filtering*/
-    {
-        char *inval;
-        setup->cpu_mask = strtol(arg, &inval, 0);
-        if ( inval == arg )
-            argp_usage(state);
-    }
-    break;
-    
-    case 'e': /* set new event mask for filtering*/
-    {
-        parse_evtmask(arg, state);
-    }
-    break;
-    
-    case 'S': /* set tbuf size (given in pages) */
-    {
-        char *inval;
-        setup->tbuf_size = strtol(arg, &inval, 0);
-        if ( inval == arg )
-            argp_usage(state);
-    }
-    break;
-
-    case 'D': /* Discard traces currently in the buffer before beginning */
-    {
-        opts.discard = 1;
-    }
-    break;
-
-    case ARGP_KEY_ARG:
-    {
-        if ( state->arg_num == 0 )
-            setup->outfile = arg;
-        else
-            argp_usage(state);
-    }
-    break;
+}
+
+/* parse command line arguments */
+void parse_args(int argc, char **argv)
+{
+    int option;
+    static struct option long_options[] = {
+        { "log-thresh",     required_argument, 0, 't' },
+        { "poll-sleep",     required_argument, 0, 's' },
+        { "cpu-mask",       required_argument, 0, 'c' },
+        { "evt-mask",       required_argument, 0, 'e' },
+        { "trace-buf-size", required_argument, 0, 'S' },
+        { "help",           no_argument,       0, '?' },
+        { "version",        no_argument,       0, 'V' },
+        { 0, 0, 0, 0 }
+    };
+
+    while ( (option = getopt_long(argc, argv, "c:e:s:S:t:?V",
+                    long_options, NULL)) != -1) 
+    {
+        switch ( option )
+        {
+        case 't': /* set new records threshold for logging */
+            opts.new_data_thresh = argtol(optarg, 0);
+            break;
+
+        case 's': /* set sleep time (given in milliseconds) */
+            opts.poll_sleep = millis_to_timespec(argtol(optarg, 0));
+            break;
+
+        case 'c': /* set new cpu mask for filtering*/
+            opts.cpu_mask = argtol(optarg, 0);
+            break;
         
-    default:
-        return ARGP_ERR_UNKNOWN;
-    }
-
-    return 0;
-}
-
-#define xstr(x) str(x)
-#define str(x) #x
-
-const struct argp_option cmd_opts[] =
-{
-    { .name = "log-thresh", .key='t', .arg="l",
-      .doc =
-      "Set number, l, of new records required to trigger a write to output "
-      "(default " xstr(NEW_DATA_THRESH) ")." },
-
-    { .name = "poll-sleep", .key='s', .arg="p",
-      .doc = 
-      "Set sleep time, p, in milliseconds between polling the trace buffer "
-      "for new data (default " xstr(POLL_SLEEP_MILLIS) ")." },
-
-    { .name = "cpu-mask", .key='c', .arg="c",
-      .doc = 
-      "Set cpu-mask." },
-
-    { .name = "evt-mask", .key='e', .arg="e",
-      .doc = 
-      "Set trace event mask.  This can accept a numerical (including hex) "
-      " argument or a symbolic name.  Symbolic names include: gen, sched, "
-      "dom0op, hvm, and all." },
-
-    { .name = "trace-buf-size", .key='S', .arg="N",
-      .doc =
-      "Set trace buffer size in pages (default " xstr(DEFAULT_TBUF_SIZE) "). "
-      "N.B. that the trace buffer cannot be resized.  If it has "
-      "already been set this boot cycle, this argument will be ignored." },
-
-    { .name = "discard-buffers", .key='D', .arg=NULL,
-      .flags=OPTION_ARG_OPTIONAL,
-      .doc = "Discard all records currently in the trace buffers before "
-      " beginning." },
-
-    {0}
-};
-
-const struct argp parser_def =
-{
-    .options = cmd_opts,
-    .parser = cmd_parser,
-    .args_doc = "[output file]",
-    .doc =
-    "Tool to capure Xen trace buffer data"
-    "\v"
-    "This tool is used to capture trace buffer data from Xen.  The data is "
-    "output in a binary format, in the following order:\n\n"
-    "  CPU(uint) TSC(uint64_t) EVENT(uint32_t) D1 D2 D3 D4 D5 "
-    "(all uint32_t)\n\n"
-    "The output should be parsed using the tool xentrace_format, which can "
-    "produce human-readable output in ASCII format."
-};
-
-
-const char *argp_program_version     = "xentrace v1.1";
-const char *argp_program_bug_address = "<mark.a.williamson@xxxxxxxxx>";
+        case 'e': /* set new event mask for filtering*/
+            parse_evtmask(optarg);
+            break;
         
-    
+        case 'S': /* set tbuf size (given in pages) */
+            opts.tbuf_size = argtol(optarg, 0);
+            break;
+
+        case 'V': /* print program version */
+            printf("%s\n", program_version);
+            exit(EXIT_SUCCESS);
+            break;
+            
+        default:
+            usage();
+        }
+    }
+
+    /* get outfile (required last argument) */
+    if (optind != (argc-1))
+        usage();
+
+    opts.outfile = argv[optind];
+}
+
+
+/* *BSD has no O_LARGEFILE */
+#ifndef O_LARGEFILE
+#define O_LARGEFILE    0
+#endif
+
 int main(int argc, char **argv)
 {
     int outfd = 1, ret;
@@ -582,8 +570,8 @@ int main(int argc, char **argv)
     opts.evt_mask = 0;
     opts.cpu_mask = 0;
 
-    argp_parse(&parser_def, argc, argv, 0, 0, &opts);
-
+    parse_args(argc, argv);
+    
     if (opts.evt_mask != 0) { 
         set_mask(opts.evt_mask, 0);
     }

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] xentrace: make xentrace and xenmon work on Solaris and *BSD., Xen patchbot-unstable <=