diff -r d7d77bace286 tools/libxl/libxl.c --- a/tools/libxl/libxl.c Fri Nov 27 10:13:42 2009 +0000 +++ b/tools/libxl/libxl.c Fri Nov 27 10:18:18 2009 +0000 @@ -468,6 +468,24 @@ if (rc < 0) { XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, rc, "xc_domain_destroy failed for %d", domid); return -1; + } + return 0; +} + +int libxl_console_attach(struct libxl_ctx *ctx, uint32_t domid, int cons_num) +{ + struct stat st; + const char *XENCONSOLE = "/usr/lib/xen/bin/xenconsole"; + char *cmd = NULL; + + if (stat(XENCONSOLE, &st) != 0) { + XL_LOG(ctx, XL_LOG_ERROR, "could not access %s", XENCONSOLE); + return ERROR_FAIL; + } + + cmd = libxl_sprintf(ctx, "%s %d --num %d", XENCONSOLE, domid, cons_num); + if (system(cmd) != 0) { + return ERROR_FAIL; } return 0; } diff -r d7d77bace286 tools/libxl/libxl.h --- a/tools/libxl/libxl.h Fri Nov 27 10:13:42 2009 +0000 +++ b/tools/libxl/libxl.h Fri Nov 27 10:18:18 2009 +0000 @@ -266,6 +266,8 @@ int libxl_domain_pause(struct libxl_ctx *ctx, uint32_t domid); int libxl_domain_unpause(struct libxl_ctx *ctx, uint32_t domid); +int libxl_console_attach(struct libxl_ctx *ctx, uint32_t domid, int cons_num); + struct libxl_dominfo * libxl_domain_list(struct libxl_ctx *ctx, int *nb_domain); xc_dominfo_t * libxl_domain_infolist(struct libxl_ctx *ctx, int *nb_domain); diff -r d7d77bace286 tools/libxl/xl.c --- a/tools/libxl/xl.c Fri Nov 27 10:13:42 2009 +0000 +++ b/tools/libxl/xl.c Fri Nov 27 10:18:18 2009 +0000 @@ -715,6 +715,7 @@ printf(" pci-list list pass-through pci devices for a domain\n\n"); printf(" pause pause execution of a domain\n\n"); printf(" unpause unpause a paused domain\n\n"); + printf(" console attach to domain's console\n\n"); } else if(!strcmp(command, "create")) { printf("Usage: xl create [options] [vars]\n\n"); printf("Create a domain based on .\n\n"); @@ -742,7 +743,56 @@ } else if(!strcmp(command, "destroy")) { printf("Usage: xl destroy \n\n"); printf("Terminate a domain immediately.\n\n"); + } else if (!strcmp(command, "console")) { + printf("Usage: xl console \n\n"); + printf("Attach to domain's console.\n\n"); } +} + +void console(char *p, int cons_num) +{ + struct libxl_ctx ctx; + uint32_t domid; + + libxl_ctx_init(&ctx); + libxl_ctx_set_log(&ctx, log_callback, NULL); + + if (libxl_param_to_domid(&ctx, p, &domid) < 0) { + fprintf(stderr, "%s is an invalid domain identifier\n", p); + exit(2); + } + libxl_console_attach(&ctx, domid, cons_num); +} + +int main_console(int argc, char **argv) +{ + int opt = 0, cons_num = 0; + char *p = NULL; + + while ((opt = getopt(argc, argv, "hn:")) != -1) { + switch (opt) { + case 'h': + help("console"); + exit(0); + case 'n': + if (optarg) { + cons_num = strtol(optarg, NULL, 10); + } + break; + default: + fprintf(stderr, "option not supported\n"); + break; + } + } + if (optind >= argc) { + help("console"); + exit(2); + } + + p = argv[optind]; + + console(p, cons_num); + exit(0); } void pcilist(char *dom) @@ -1121,6 +1171,8 @@ main_pause(argc - 1, argv + 1); } else if (!strcmp(argv[1], "unpause")) { main_unpause(argc - 1, argv + 1); + } else if (!strcmp(argv[1], "console")) { + main_console(argc - 1, argv + 1); } else if (!strcmp(argv[1], "help")) { if (argc > 2) help(argv[2]);