XL_OBJS += xl_tmem.o xl_parse.o xl_cpupool.o xl_flask.o
XL_OBJS += xl_vtpm.o xl_block.o xl_nic.o xl_usb.o
XL_OBJS += xl_sched.o xl_pci.o xl_vcpu.o xl_cdrom.o xl_mem.o
-XL_OBJS += xl_psr.o
+XL_OBJS += xl_psr.o xl_info.o
$(XL_OBJS): CFLAGS += $(CFLAGS_libxentoollog)
$(XL_OBJS): CFLAGS += $(CFLAGS_XL)
return rc;
}
-static yajl_gen_status printf_info_one_json(yajl_gen hand, int domid,
- libxl_domain_config *d_config)
-{
- yajl_gen_status s;
-
- s = yajl_gen_map_open(hand);
- if (s != yajl_gen_status_ok)
- goto out;
-
- s = yajl_gen_string(hand, (const unsigned char *)"domid",
- sizeof("domid")-1);
- if (s != yajl_gen_status_ok)
- goto out;
- if (domid != -1)
- s = yajl_gen_integer(hand, domid);
- else
- s = yajl_gen_null(hand);
- if (s != yajl_gen_status_ok)
- goto out;
-
- s = yajl_gen_string(hand, (const unsigned char *)"config",
- sizeof("config")-1);
- if (s != yajl_gen_status_ok)
- goto out;
- s = libxl_domain_config_gen_json(hand, d_config);
- if (s != yajl_gen_status_ok)
- goto out;
-
- s = yajl_gen_map_close(hand);
- if (s != yajl_gen_status_ok)
- goto out;
-
-out:
- return s;
-}
-
-static void printf_info(enum output_format output_format,
- int domid,
- libxl_domain_config *d_config, FILE *fh)
-{
- if (output_format == OUTPUT_FORMAT_SXP)
- return printf_info_sexp(domid, d_config, fh);
-
- const char *buf;
- libxl_yajl_length len = 0;
- yajl_gen_status s;
- yajl_gen hand;
-
- hand = libxl_yajl_gen_alloc(NULL);
- if (!hand) {
- fprintf(stderr, "unable to allocate JSON generator\n");
- return;
- }
-
- s = printf_info_one_json(hand, domid, d_config);
- if (s != yajl_gen_status_ok)
- goto out;
-
- s = yajl_gen_get_buf(hand, (const unsigned char **)&buf, &len);
- if (s != yajl_gen_status_ok)
- goto out;
-
- fputs(buf, fh);
-
-out:
- yajl_gen_free(hand);
-
- if (s != yajl_gen_status_ok)
- fprintf(stderr,
- "unable to format domain config as JSON (YAJL:%d)\n", s);
-
- flush_stream(fh);
-}
-
static int do_daemonize(char *name, const char *pidfile)
{
char *fullname;
}
}
-static void list_domains_details(const libxl_dominfo *info, int nb_domain)
-{
- libxl_domain_config d_config;
-
- int i, rc;
-
- yajl_gen hand = NULL;
- yajl_gen_status s;
- const char *buf;
- libxl_yajl_length yajl_len = 0;
-
- if (default_output_format == OUTPUT_FORMAT_JSON) {
- hand = libxl_yajl_gen_alloc(NULL);
- if (!hand) {
- fprintf(stderr, "unable to allocate JSON generator\n");
- return;
- }
-
- s = yajl_gen_array_open(hand);
- if (s != yajl_gen_status_ok)
- goto out;
- } else
- s = yajl_gen_status_ok;
-
- for (i = 0; i < nb_domain; i++) {
- libxl_domain_config_init(&d_config);
- rc = libxl_retrieve_domain_configuration(ctx, info[i].domid, &d_config);
- if (rc)
- continue;
- if (default_output_format == OUTPUT_FORMAT_JSON)
- s = printf_info_one_json(hand, info[i].domid, &d_config);
- else
- printf_info_sexp(info[i].domid, &d_config, stdout);
- libxl_domain_config_dispose(&d_config);
- if (s != yajl_gen_status_ok)
- goto out;
- }
-
- if (default_output_format == OUTPUT_FORMAT_JSON) {
- s = yajl_gen_array_close(hand);
- if (s != yajl_gen_status_ok)
- goto out;
-
- s = yajl_gen_get_buf(hand, (const unsigned char **)&buf, &yajl_len);
- if (s != yajl_gen_status_ok)
- goto out;
-
- puts(buf);
- }
-
-out:
- if (default_output_format == OUTPUT_FORMAT_JSON) {
- yajl_gen_free(hand);
- if (s != yajl_gen_status_ok)
- fprintf(stderr,
- "unable to format domain config as JSON (YAJL:%d)\n", s);
- }
-}
-
-static void list_domains(bool verbose, bool context, bool claim, bool numa,
- bool cpupool, const libxl_dominfo *info, int nb_domain)
-{
- int i;
- static const char shutdown_reason_letters[]= "-rscwS";
- libxl_bitmap nodemap;
- libxl_physinfo physinfo;
-
- libxl_bitmap_init(&nodemap);
- libxl_physinfo_init(&physinfo);
-
- printf("Name ID Mem VCPUs\tState\tTime(s)");
- if (verbose) printf(" UUID Reason-Code\tSecurity Label");
- if (context && !verbose) printf(" Security Label");
- if (claim) printf(" Claimed");
- if (cpupool) printf(" Cpupool");
- if (numa) {
- if (libxl_node_bitmap_alloc(ctx, &nodemap, 0)) {
- fprintf(stderr, "libxl_node_bitmap_alloc_failed.\n");
- exit(EXIT_FAILURE);
- }
- if (libxl_get_physinfo(ctx, &physinfo) != 0) {
- fprintf(stderr, "libxl_physinfo failed.\n");
- libxl_bitmap_dispose(&nodemap);
- exit(EXIT_FAILURE);
- }
-
- printf(" NODE Affinity");
- }
- printf("\n");
- for (i = 0; i < nb_domain; i++) {
- char *domname;
- libxl_shutdown_reason shutdown_reason;
- domname = libxl_domid_to_name(ctx, info[i].domid);
- shutdown_reason = info[i].shutdown ? info[i].shutdown_reason : 0;
- printf("%-40s %5d %5lu %5d %c%c%c%c%c%c %8.1f",
- domname,
- info[i].domid,
- (unsigned long) ((info[i].current_memkb +
- info[i].outstanding_memkb)/ 1024),
- info[i].vcpu_online,
- info[i].running ? 'r' : '-',
- info[i].blocked ? 'b' : '-',
- info[i].paused ? 'p' : '-',
- info[i].shutdown ? 's' : '-',
- (shutdown_reason >= 0 &&
- shutdown_reason < sizeof(shutdown_reason_letters)-1
- ? shutdown_reason_letters[shutdown_reason] : '?'),
- info[i].dying ? 'd' : '-',
- ((float)info[i].cpu_time / 1e9));
- free(domname);
- if (verbose) {
- printf(" " LIBXL_UUID_FMT, LIBXL_UUID_BYTES(info[i].uuid));
- if (info[i].shutdown) printf(" %8x", shutdown_reason);
- else printf(" %8s", "-");
- }
- if (claim)
- printf(" %5lu", (unsigned long)info[i].outstanding_memkb / 1024);
- if (verbose || context)
- printf(" %16s", info[i].ssid_label ? : "-");
- if (cpupool) {
- char *poolname = libxl_cpupoolid_to_name(ctx, info[i].cpupool);
- printf("%16s", poolname);
- free(poolname);
- }
- if (numa) {
- libxl_domain_get_nodeaffinity(ctx, info[i].domid, &nodemap);
-
- putchar(' ');
- print_bitmap(nodemap.map, physinfo.nr_nodes, stdout);
- }
- putchar('\n');
- }
-
- libxl_bitmap_dispose(&nodemap);
- libxl_physinfo_dispose(&physinfo);
-}
-
-static void list_vm(void)
-{
- libxl_vminfo *info;
- char *domname;
- int nb_vm, i;
-
- info = libxl_list_vm(ctx, &nb_vm);
-
- if (!info) {
- fprintf(stderr, "libxl_list_vm failed.\n");
- exit(EXIT_FAILURE);
- }
- printf("UUID ID name\n");
- for (i = 0; i < nb_vm; i++) {
- domname = libxl_domid_to_name(ctx, info[i].domid);
- printf(LIBXL_UUID_FMT " %d %-30s\n", LIBXL_UUID_BYTES(info[i].uuid),
- info[i].domid, domname);
- free(domname);
- }
- libxl_vminfo_list_free(info, nb_vm);
-}
-
static void core_dump_domain(uint32_t domid, const char *filename)
{
int rc;
return main_shutdown_or_reboot(1, argc, argv);
}
-int main_list(int argc, char **argv)
-{
- int opt;
- bool verbose = false;
- bool context = false;
- bool details = false;
- bool cpupool = false;
- bool numa = false;
- static struct option opts[] = {
- {"long", 0, 0, 'l'},
- {"verbose", 0, 0, 'v'},
- {"context", 0, 0, 'Z'},
- {"cpupool", 0, 0, 'c'},
- {"numa", 0, 0, 'n'},
- COMMON_LONG_OPTS
- };
-
- libxl_dominfo info_buf;
- libxl_dominfo *info, *info_free=0;
- int nb_domain, rc;
-
- SWITCH_FOREACH_OPT(opt, "lvhZcn", opts, "list", 0) {
- case 'l':
- details = true;
- break;
- case 'v':
- verbose = true;
- break;
- case 'Z':
- context = true;
- break;
- case 'c':
- cpupool = true;
- break;
- case 'n':
- numa = true;
- break;
- }
-
- libxl_dominfo_init(&info_buf);
-
- if (optind >= argc) {
- info = libxl_list_domain(ctx, &nb_domain);
- if (!info) {
- fprintf(stderr, "libxl_list_domain failed.\n");
- return EXIT_FAILURE;
- }
- info_free = info;
- } else if (optind == argc-1) {
- uint32_t domid = find_domain(argv[optind]);
- rc = libxl_domain_info(ctx, &info_buf, domid);
- if (rc == ERROR_DOMAIN_NOTFOUND) {
- fprintf(stderr, "Error: Domain \'%s\' does not exist.\n",
- argv[optind]);
- return EXIT_FAILURE;
- }
- if (rc) {
- fprintf(stderr, "libxl_domain_info failed (code %d).\n", rc);
- return EXIT_FAILURE;
- }
- info = &info_buf;
- nb_domain = 1;
- } else {
- help("list");
- return EXIT_FAILURE;
- }
-
- if (details)
- list_domains_details(info, nb_domain);
- else
- list_domains(verbose, context, false /* claim */, numa, cpupool,
- info, nb_domain);
-
- if (info_free)
- libxl_dominfo_list_free(info, nb_domain);
-
- libxl_dominfo_dispose(&info_buf);
-
- return EXIT_SUCCESS;
-}
-
-int main_vm_list(int argc, char **argv)
-{
- int opt;
-
- SWITCH_FOREACH_OPT(opt, "", NULL, "vm-list", 0) {
- /* No options */
- }
-
- list_vm();
- return EXIT_SUCCESS;
-}
-
int main_create(int argc, char **argv)
{
const char *filename = NULL;
return 0;
}
+extern void printf_info(enum output_format output_format,
+ int domid,
+ libxl_domain_config *d_config, FILE *fh);
int main_config_update(int argc, char **argv)
{
uint32_t domid;
return 0;
}
-/* Possibly select a specific piece of `xl info` to print. */
-static const char *info_name;
-static int maybe_printf(const char *fmt, ...) __attribute__((format(printf,1,2)));
-static int maybe_printf(const char *fmt, ...)
-{
- va_list ap;
- char *str;
- int count = 0;
-
- va_start(ap, fmt);
- if (vasprintf(&str, fmt, ap) != -1) {
- if (info_name) {
- char *s;
-
- if (!strncmp(str, info_name, strlen(info_name)) &&
- (s = strchr(str, ':')) && s[1] == ' ')
- count = fputs(&s[2], stdout);
- } else
- count = fputs(str, stdout);
-
- free(str);
- }
- va_end(ap);
-
- return count;
-}
-
-static void output_xeninfo(void)
-{
- const libxl_version_info *info;
- libxl_scheduler sched;
- int rc;
-
- if (!(info = libxl_get_version_info(ctx))) {
- fprintf(stderr, "libxl_get_version_info failed.\n");
- return;
- }
-
- rc = libxl_get_scheduler(ctx);
- if (rc < 0) {
- fprintf(stderr, "get_scheduler sysctl failed.\n");
- return;
- }
- sched = rc;
-
- maybe_printf("xen_major : %d\n", info->xen_version_major);
- maybe_printf("xen_minor : %d\n", info->xen_version_minor);
- maybe_printf("xen_extra : %s\n", info->xen_version_extra);
- maybe_printf("xen_version : %d.%d%s\n", info->xen_version_major,
- info->xen_version_minor, info->xen_version_extra);
- maybe_printf("xen_caps : %s\n", info->capabilities);
- maybe_printf("xen_scheduler : %s\n", libxl_scheduler_to_string(sched));
- maybe_printf("xen_pagesize : %u\n", info->pagesize);
- maybe_printf("platform_params : virt_start=0x%"PRIx64"\n", info->virt_start);
- maybe_printf("xen_changeset : %s\n", info->changeset);
- maybe_printf("xen_commandline : %s\n", info->commandline);
- maybe_printf("cc_compiler : %s\n", info->compiler);
- maybe_printf("cc_compile_by : %s\n", info->compile_by);
- maybe_printf("cc_compile_domain : %s\n", info->compile_domain);
- maybe_printf("cc_compile_date : %s\n", info->compile_date);
- maybe_printf("build_id : %s\n", info->build_id);
-
- return;
-}
-
-static void output_nodeinfo(void)
-{
- struct utsname utsbuf;
-
- if (uname(&utsbuf) < 0)
- return;
-
- maybe_printf("host : %s\n", utsbuf.nodename);
- maybe_printf("release : %s\n", utsbuf.release);
- maybe_printf("version : %s\n", utsbuf.version);
- maybe_printf("machine : %s\n", utsbuf.machine);
-}
-
-static void output_physinfo(void)
-{
- libxl_physinfo info;
- const libxl_version_info *vinfo;
- unsigned int i;
- libxl_bitmap cpumap;
- int n = 0;
-
- if (libxl_get_physinfo(ctx, &info) != 0) {
- fprintf(stderr, "libxl_physinfo failed.\n");
- return;
- }
- maybe_printf("nr_cpus : %d\n", info.nr_cpus);
- maybe_printf("max_cpu_id : %d\n", info.max_cpu_id);
- maybe_printf("nr_nodes : %d\n", info.nr_nodes);
- maybe_printf("cores_per_socket : %d\n", info.cores_per_socket);
- maybe_printf("threads_per_core : %d\n", info.threads_per_core);
- maybe_printf("cpu_mhz : %d\n", info.cpu_khz / 1000);
-
- maybe_printf("hw_caps : %08x:%08x:%08x:%08x:%08x:%08x:%08x:%08x\n",
- info.hw_cap[0], info.hw_cap[1], info.hw_cap[2], info.hw_cap[3],
- info.hw_cap[4], info.hw_cap[5], info.hw_cap[6], info.hw_cap[7]
- );
-
- maybe_printf("virt_caps :%s%s\n",
- info.cap_hvm ? " hvm" : "",
- info.cap_hvm_directio ? " hvm_directio" : ""
- );
-
- vinfo = libxl_get_version_info(ctx);
- if (vinfo) {
- i = (1 << 20) / vinfo->pagesize;
- maybe_printf("total_memory : %"PRIu64"\n", info.total_pages / i);
- maybe_printf("free_memory : %"PRIu64"\n", (info.free_pages - info.outstanding_pages) / i);
- maybe_printf("sharing_freed_memory : %"PRIu64"\n", info.sharing_freed_pages / i);
- maybe_printf("sharing_used_memory : %"PRIu64"\n", info.sharing_used_frames / i);
- maybe_printf("outstanding_claims : %"PRIu64"\n", info.outstanding_pages / i);
- }
- if (!libxl_get_freecpus(ctx, &cpumap)) {
- libxl_for_each_bit(i, cpumap)
- if (libxl_bitmap_test(&cpumap, i))
- n++;
- maybe_printf("free_cpus : %d\n", n);
- free(cpumap.map);
- }
- libxl_physinfo_dispose(&info);
- return;
-}
-
-static void output_numainfo(void)
-{
- libxl_numainfo *info;
- int i, j, nr;
-
- info = libxl_get_numainfo(ctx, &nr);
- if (info == NULL) {
- fprintf(stderr, "libxl_get_numainfo failed.\n");
- return;
- }
-
- printf("numa_info :\n");
- printf("node: memsize memfree distances\n");
-
- for (i = 0; i < nr; i++) {
- if (info[i].size != LIBXL_NUMAINFO_INVALID_ENTRY) {
- printf("%4d: %6"PRIu64" %6"PRIu64" %d", i,
- info[i].size >> 20, info[i].free >> 20,
- info[i].dists[0]);
- for (j = 1; j < info[i].num_dists; j++)
- printf(",%d", info[i].dists[j]);
- printf("\n");
- }
- }
-
- libxl_numainfo_list_free(info, nr);
-
- return;
-}
-
-static void output_topologyinfo(void)
-{
- libxl_cputopology *cpuinfo;
- int i, nr;
- libxl_pcitopology *pciinfo;
- int valid_devs = 0;
-
-
- cpuinfo = libxl_get_cpu_topology(ctx, &nr);
- if (cpuinfo == NULL) {
- fprintf(stderr, "libxl_get_cpu_topology failed.\n");
- return;
- }
-
- printf("cpu_topology :\n");
- printf("cpu: core socket node\n");
-
- for (i = 0; i < nr; i++) {
- if (cpuinfo[i].core != LIBXL_CPUTOPOLOGY_INVALID_ENTRY)
- printf("%3d: %4d %4d %4d\n", i,
- cpuinfo[i].core, cpuinfo[i].socket, cpuinfo[i].node);
- }
-
- libxl_cputopology_list_free(cpuinfo, nr);
-
- pciinfo = libxl_get_pci_topology(ctx, &nr);
- if (pciinfo == NULL) {
- fprintf(stderr, "libxl_get_pci_topology failed.\n");
- return;
- }
-
- printf("device topology :\n");
- printf("device node\n");
- for (i = 0; i < nr; i++) {
- if (pciinfo[i].node != LIBXL_PCITOPOLOGY_INVALID_ENTRY) {
- printf("%04x:%02x:%02x.%01x %d\n", pciinfo[i].seg,
- pciinfo[i].bus,
- ((pciinfo[i].devfn >> 3) & 0x1f), (pciinfo[i].devfn & 7),
- pciinfo[i].node);
- valid_devs++;
- }
- }
-
- if (valid_devs == 0)
- printf("No device topology data available\n");
-
- libxl_pcitopology_list_free(pciinfo, nr);
-
- return;
-}
-
-static void print_info(int numa)
-{
- output_nodeinfo();
-
- output_physinfo();
-
- if (numa) {
- output_topologyinfo();
- output_numainfo();
- }
- output_xeninfo();
-
- maybe_printf("xend_config_format : 4\n");
-
- return;
-}
-
-int main_info(int argc, char **argv)
-{
- int opt;
- static struct option opts[] = {
- {"numa", 0, 0, 'n'},
- COMMON_LONG_OPTS
- };
- int numa = 0;
-
- SWITCH_FOREACH_OPT(opt, "n", opts, "info", 0) {
- case 'n':
- numa = 1;
- break;
- }
-
- /*
- * If an extra argument is provided, filter out a specific piece of
- * information.
- */
- if (numa == 0 && argc > optind)
- info_name = argv[optind];
-
- print_info(numa);
- return 0;
-}
-
-int main_domid(int argc, char **argv)
-{
- uint32_t domid;
- int opt;
- const char *domname = NULL;
-
- SWITCH_FOREACH_OPT(opt, "", NULL, "domid", 1) {
- /* No options */
- }
-
- domname = argv[optind];
-
- if (libxl_name_to_domid(ctx, domname, &domid)) {
- fprintf(stderr, "Can't get domid of domain name '%s', maybe this domain does not exist.\n", domname);
- return EXIT_FAILURE;
- }
-
- printf("%u\n", domid);
-
- return EXIT_SUCCESS;
-}
-
-int main_domname(int argc, char **argv)
-{
- uint32_t domid;
- int opt;
- char *domname = NULL;
- char *endptr = NULL;
-
- SWITCH_FOREACH_OPT(opt, "", NULL, "domname", 1) {
- /* No options */
- }
-
- domid = strtol(argv[optind], &endptr, 10);
- if (domid == 0 && !strcmp(endptr, argv[optind])) {
- /*no digits at all*/
- fprintf(stderr, "Invalid domain id.\n\n");
- return EXIT_FAILURE;
- }
-
- domname = libxl_domid_to_name(ctx, domid);
- if (!domname) {
- fprintf(stderr, "Can't get domain name of domain id '%u', maybe this domain does not exist.\n", domid);
- return EXIT_FAILURE;
- }
-
- printf("%s\n", domname);
- free(domname);
-
- return EXIT_SUCCESS;
-}
-
int main_rename(int argc, char **argv)
{
uint32_t domid;
return EXIT_SUCCESS;
}
-int main_dmesg(int argc, char **argv)
-{
- unsigned int clear = 0;
- libxl_xen_console_reader *cr;
- char *line;
- int opt, ret = 1;
-
- SWITCH_FOREACH_OPT(opt, "c", NULL, "dmesg", 0) {
- case 'c':
- clear = 1;
- break;
- }
-
- cr = libxl_xen_console_read_start(ctx, clear);
- if (!cr)
- goto finish;
-
- while ((ret = libxl_xen_console_read_line(ctx, cr, &line)) > 0)
- printf("%s", line);
-
-finish:
- if (cr)
- libxl_xen_console_read_finish(ctx, cr);
- return ret ? EXIT_FAILURE : EXIT_SUCCESS;
-}
-
-int main_top(int argc, char **argv)
-{
- int opt;
-
- SWITCH_FOREACH_OPT(opt, "", NULL, "top", 0) {
- /* No options */
- }
-
- return system("xentop");
-}
-
int main_channellist(int argc, char **argv)
{
int opt;
return 0;
}
-static char *uptime_to_string(unsigned long uptime, int short_mode)
-{
- int sec, min, hour, day;
- char *time_string;
-
- day = (int)(uptime / 86400);
- uptime -= (day * 86400);
- hour = (int)(uptime / 3600);
- uptime -= (hour * 3600);
- min = (int)(uptime / 60);
- uptime -= (min * 60);
- sec = uptime;
-
- if (short_mode)
- if (day > 1)
- xasprintf(&time_string, "%d days, %2d:%02d", day, hour, min);
- else if (day == 1)
- xasprintf(&time_string, "%d day, %2d:%02d", day, hour, min);
- else
- xasprintf(&time_string, "%2d:%02d", hour, min);
- else
- if (day > 1)
- xasprintf(&time_string, "%d days, %2d:%02d:%02d", day, hour, min, sec);
- else if (day == 1)
- xasprintf(&time_string, "%d day, %2d:%02d:%02d", day, hour, min, sec);
- else
- xasprintf(&time_string, "%2d:%02d:%02d", hour, min, sec);
-
- return time_string;
-}
-
-int main_claims(int argc, char **argv)
-{
- libxl_dominfo *info;
- int opt;
- int nb_domain;
-
- SWITCH_FOREACH_OPT(opt, "", NULL, "claims", 0) {
- /* No options */
- }
-
- if (!claim_mode)
- fprintf(stderr, "claim_mode not enabled (see man xl.conf).\n");
-
- info = libxl_list_domain(ctx, &nb_domain);
- if (!info) {
- fprintf(stderr, "libxl_list_domain failed.\n");
- return 1;
- }
-
- list_domains(false /* verbose */, false /* context */, true /* claim */,
- false /* numa */, false /* cpupool */, info, nb_domain);
-
- libxl_dominfo_list_free(info, nb_domain);
- return 0;
-}
-
-static char *current_time_to_string(time_t now)
-{
- char now_str[100];
- struct tm *tmp;
-
- tmp = localtime(&now);
- if (tmp == NULL) {
- fprintf(stderr, "Get localtime error");
- exit(-1);
- }
- if (strftime(now_str, sizeof(now_str), "%H:%M:%S", tmp) == 0) {
- fprintf(stderr, "strftime returned 0");
- exit(-1);
- }
- return strdup(now_str);
-}
-
-static void print_dom0_uptime(int short_mode, time_t now)
-{
- int fd;
- ssize_t nr;
- char buf[512];
- uint32_t uptime = 0;
- char *uptime_str = NULL;
- char *now_str = NULL;
- char *domname;
-
- fd = open("/proc/uptime", O_RDONLY);
- if (fd == -1)
- goto err;
-
- nr = read(fd, buf, sizeof(buf) - 1);
- if (nr == -1) {
- close(fd);
- goto err;
- }
- close(fd);
-
- buf[nr] = '\0';
-
- strtok(buf, " ");
- uptime = strtoul(buf, NULL, 10);
-
- domname = libxl_domid_to_name(ctx, 0);
- if (short_mode)
- {
- now_str = current_time_to_string(now);
- uptime_str = uptime_to_string(uptime, 1);
- printf(" %s up %s, %s (%d)\n", now_str, uptime_str,
- domname, 0);
- }
- else
- {
- now_str = NULL;
- uptime_str = uptime_to_string(uptime, 0);
- printf("%-33s %4d %s\n", domname,
- 0, uptime_str);
- }
-
- free(now_str);
- free(uptime_str);
- free(domname);
- return;
-err:
- fprintf(stderr, "Can not get Dom0 uptime.\n");
- exit(-1);
-}
-
-static void print_domU_uptime(uint32_t domuid, int short_mode, time_t now)
-{
- uint32_t s_time = 0;
- uint32_t uptime = 0;
- char *uptime_str = NULL;
- char *now_str = NULL;
- char *domname;
-
- s_time = libxl_vm_get_start_time(ctx, domuid);
- if (s_time == -1)
- return;
- uptime = now - s_time;
- domname = libxl_domid_to_name(ctx, domuid);
- if (short_mode)
- {
- now_str = current_time_to_string(now);
- uptime_str = uptime_to_string(uptime, 1);
- printf(" %s up %s, %s (%d)\n", now_str, uptime_str,
- domname, domuid);
- }
- else
- {
- now_str = NULL;
- uptime_str = uptime_to_string(uptime, 0);
- printf("%-33s %4d %s\n", domname,
- domuid, uptime_str);
- }
-
- free(domname);
- free(now_str);
- free(uptime_str);
- return;
-}
-
-static void print_uptime(int short_mode, uint32_t doms[], int nb_doms)
-{
- libxl_vminfo *info;
- time_t now;
- int nb_vm, i;
-
- now = time(NULL);
-
- if (!short_mode)
- printf("%-33s %4s %s\n", "Name", "ID", "Uptime");
-
- if (nb_doms == 0) {
- print_dom0_uptime(short_mode, now);
- info = libxl_list_vm(ctx, &nb_vm);
- if (info == NULL) {
- fprintf(stderr, "Could not list vms.\n");
- return;
- }
- for (i = 0; i < nb_vm; i++) {
- if (info[i].domid == 0) continue;
- print_domU_uptime(info[i].domid, short_mode, now);
- }
- libxl_vminfo_list_free(info, nb_vm);
- } else {
- for (i = 0; i < nb_doms; i++) {
- if (doms[i] == 0)
- print_dom0_uptime(short_mode, now);
- else
- print_domU_uptime(doms[i], short_mode, now);
- }
- }
-}
-
-int main_uptime(int argc, char **argv)
-{
- const char *dom;
- int short_mode = 0;
- uint32_t domains[100];
- int nb_doms = 0;
- int opt;
-
- SWITCH_FOREACH_OPT(opt, "s", NULL, "uptime", 0) {
- case 's':
- short_mode = 1;
- break;
- }
-
- for (;(dom = argv[optind]) != NULL; nb_doms++,optind++)
- domains[nb_doms] = find_domain(dom);
-
- print_uptime(short_mode, domains, nb_doms);
-
- return 0;
-}
-
#ifndef LIBXL_HAVE_NO_SUSPEND_RESUME
int main_remus(int argc, char **argv)
{
--- /dev/null
+/*
+ * Copyright 2009-2017 Citrix Ltd and other contributors
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 only. with the special
+ * exception on linking described in file LICENSE.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ */
+
+#define _GNU_SOURCE
+
+#include <fcntl.h>
+#include <inttypes.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/utsname.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <libxl.h>
+#include <libxl_json.h>
+#include <libxl_utils.h>
+#include <libxlutil.h>
+
+#include "xl.h"
+#include "xl_utils.h"
+
+/* Possibly select a specific piece of `xl info` to print. */
+static const char *info_name;
+static int maybe_printf(const char *fmt, ...) __attribute__((format(printf,1,2)));
+static int maybe_printf(const char *fmt, ...)
+{
+ va_list ap;
+ char *str;
+ int count = 0;
+
+ va_start(ap, fmt);
+ if (vasprintf(&str, fmt, ap) != -1) {
+ if (info_name) {
+ char *s;
+
+ if (!strncmp(str, info_name, strlen(info_name)) &&
+ (s = strchr(str, ':')) && s[1] == ' ')
+ count = fputs(&s[2], stdout);
+ } else
+ count = fputs(str, stdout);
+
+ free(str);
+ }
+ va_end(ap);
+
+ return count;
+}
+
+static yajl_gen_status printf_info_one_json(yajl_gen hand, int domid,
+ libxl_domain_config *d_config)
+{
+ yajl_gen_status s;
+
+ s = yajl_gen_map_open(hand);
+ if (s != yajl_gen_status_ok)
+ goto out;
+
+ s = yajl_gen_string(hand, (const unsigned char *)"domid",
+ sizeof("domid")-1);
+ if (s != yajl_gen_status_ok)
+ goto out;
+ if (domid != -1)
+ s = yajl_gen_integer(hand, domid);
+ else
+ s = yajl_gen_null(hand);
+ if (s != yajl_gen_status_ok)
+ goto out;
+
+ s = yajl_gen_string(hand, (const unsigned char *)"config",
+ sizeof("config")-1);
+ if (s != yajl_gen_status_ok)
+ goto out;
+ s = libxl_domain_config_gen_json(hand, d_config);
+ if (s != yajl_gen_status_ok)
+ goto out;
+
+ s = yajl_gen_map_close(hand);
+ if (s != yajl_gen_status_ok)
+ goto out;
+
+out:
+ return s;
+}
+
+void printf_info(enum output_format output_format,
+ int domid,
+ libxl_domain_config *d_config, FILE *fh);
+void printf_info(enum output_format output_format,
+ int domid,
+ libxl_domain_config *d_config, FILE *fh)
+{
+ if (output_format == OUTPUT_FORMAT_SXP)
+ return printf_info_sexp(domid, d_config, fh);
+
+ const char *buf;
+ libxl_yajl_length len = 0;
+ yajl_gen_status s;
+ yajl_gen hand;
+
+ hand = libxl_yajl_gen_alloc(NULL);
+ if (!hand) {
+ fprintf(stderr, "unable to allocate JSON generator\n");
+ return;
+ }
+
+ s = printf_info_one_json(hand, domid, d_config);
+ if (s != yajl_gen_status_ok)
+ goto out;
+
+ s = yajl_gen_get_buf(hand, (const unsigned char **)&buf, &len);
+ if (s != yajl_gen_status_ok)
+ goto out;
+
+ fputs(buf, fh);
+
+out:
+ yajl_gen_free(hand);
+
+ if (s != yajl_gen_status_ok)
+ fprintf(stderr,
+ "unable to format domain config as JSON (YAJL:%d)\n", s);
+
+ flush_stream(fh);
+}
+
+static void output_xeninfo(void)
+{
+ const libxl_version_info *info;
+ libxl_scheduler sched;
+ int rc;
+
+ if (!(info = libxl_get_version_info(ctx))) {
+ fprintf(stderr, "libxl_get_version_info failed.\n");
+ return;
+ }
+
+ rc = libxl_get_scheduler(ctx);
+ if (rc < 0) {
+ fprintf(stderr, "get_scheduler sysctl failed.\n");
+ return;
+ }
+ sched = rc;
+
+ maybe_printf("xen_major : %d\n", info->xen_version_major);
+ maybe_printf("xen_minor : %d\n", info->xen_version_minor);
+ maybe_printf("xen_extra : %s\n", info->xen_version_extra);
+ maybe_printf("xen_version : %d.%d%s\n", info->xen_version_major,
+ info->xen_version_minor, info->xen_version_extra);
+ maybe_printf("xen_caps : %s\n", info->capabilities);
+ maybe_printf("xen_scheduler : %s\n", libxl_scheduler_to_string(sched));
+ maybe_printf("xen_pagesize : %u\n", info->pagesize);
+ maybe_printf("platform_params : virt_start=0x%"PRIx64"\n", info->virt_start);
+ maybe_printf("xen_changeset : %s\n", info->changeset);
+ maybe_printf("xen_commandline : %s\n", info->commandline);
+ maybe_printf("cc_compiler : %s\n", info->compiler);
+ maybe_printf("cc_compile_by : %s\n", info->compile_by);
+ maybe_printf("cc_compile_domain : %s\n", info->compile_domain);
+ maybe_printf("cc_compile_date : %s\n", info->compile_date);
+ maybe_printf("build_id : %s\n", info->build_id);
+
+ return;
+}
+
+static void output_nodeinfo(void)
+{
+ struct utsname utsbuf;
+
+ if (uname(&utsbuf) < 0)
+ return;
+
+ maybe_printf("host : %s\n", utsbuf.nodename);
+ maybe_printf("release : %s\n", utsbuf.release);
+ maybe_printf("version : %s\n", utsbuf.version);
+ maybe_printf("machine : %s\n", utsbuf.machine);
+}
+
+static void output_physinfo(void)
+{
+ libxl_physinfo info;
+ const libxl_version_info *vinfo;
+ unsigned int i;
+ libxl_bitmap cpumap;
+ int n = 0;
+
+ if (libxl_get_physinfo(ctx, &info) != 0) {
+ fprintf(stderr, "libxl_physinfo failed.\n");
+ return;
+ }
+ maybe_printf("nr_cpus : %d\n", info.nr_cpus);
+ maybe_printf("max_cpu_id : %d\n", info.max_cpu_id);
+ maybe_printf("nr_nodes : %d\n", info.nr_nodes);
+ maybe_printf("cores_per_socket : %d\n", info.cores_per_socket);
+ maybe_printf("threads_per_core : %d\n", info.threads_per_core);
+ maybe_printf("cpu_mhz : %d\n", info.cpu_khz / 1000);
+
+ maybe_printf("hw_caps : %08x:%08x:%08x:%08x:%08x:%08x:%08x:%08x\n",
+ info.hw_cap[0], info.hw_cap[1], info.hw_cap[2], info.hw_cap[3],
+ info.hw_cap[4], info.hw_cap[5], info.hw_cap[6], info.hw_cap[7]
+ );
+
+ maybe_printf("virt_caps :%s%s\n",
+ info.cap_hvm ? " hvm" : "",
+ info.cap_hvm_directio ? " hvm_directio" : ""
+ );
+
+ vinfo = libxl_get_version_info(ctx);
+ if (vinfo) {
+ i = (1 << 20) / vinfo->pagesize;
+ maybe_printf("total_memory : %"PRIu64"\n", info.total_pages / i);
+ maybe_printf("free_memory : %"PRIu64"\n", (info.free_pages - info.outstanding_pages) / i);
+ maybe_printf("sharing_freed_memory : %"PRIu64"\n", info.sharing_freed_pages / i);
+ maybe_printf("sharing_used_memory : %"PRIu64"\n", info.sharing_used_frames / i);
+ maybe_printf("outstanding_claims : %"PRIu64"\n", info.outstanding_pages / i);
+ }
+ if (!libxl_get_freecpus(ctx, &cpumap)) {
+ libxl_for_each_bit(i, cpumap)
+ if (libxl_bitmap_test(&cpumap, i))
+ n++;
+ maybe_printf("free_cpus : %d\n", n);
+ free(cpumap.map);
+ }
+ libxl_physinfo_dispose(&info);
+ return;
+}
+
+static void output_numainfo(void)
+{
+ libxl_numainfo *info;
+ int i, j, nr;
+
+ info = libxl_get_numainfo(ctx, &nr);
+ if (info == NULL) {
+ fprintf(stderr, "libxl_get_numainfo failed.\n");
+ return;
+ }
+
+ printf("numa_info :\n");
+ printf("node: memsize memfree distances\n");
+
+ for (i = 0; i < nr; i++) {
+ if (info[i].size != LIBXL_NUMAINFO_INVALID_ENTRY) {
+ printf("%4d: %6"PRIu64" %6"PRIu64" %d", i,
+ info[i].size >> 20, info[i].free >> 20,
+ info[i].dists[0]);
+ for (j = 1; j < info[i].num_dists; j++)
+ printf(",%d", info[i].dists[j]);
+ printf("\n");
+ }
+ }
+
+ libxl_numainfo_list_free(info, nr);
+
+ return;
+}
+
+static void output_topologyinfo(void)
+{
+ libxl_cputopology *cpuinfo;
+ int i, nr;
+ libxl_pcitopology *pciinfo;
+ int valid_devs = 0;
+
+
+ cpuinfo = libxl_get_cpu_topology(ctx, &nr);
+ if (cpuinfo == NULL) {
+ fprintf(stderr, "libxl_get_cpu_topology failed.\n");
+ return;
+ }
+
+ printf("cpu_topology :\n");
+ printf("cpu: core socket node\n");
+
+ for (i = 0; i < nr; i++) {
+ if (cpuinfo[i].core != LIBXL_CPUTOPOLOGY_INVALID_ENTRY)
+ printf("%3d: %4d %4d %4d\n", i,
+ cpuinfo[i].core, cpuinfo[i].socket, cpuinfo[i].node);
+ }
+
+ libxl_cputopology_list_free(cpuinfo, nr);
+
+ pciinfo = libxl_get_pci_topology(ctx, &nr);
+ if (pciinfo == NULL) {
+ fprintf(stderr, "libxl_get_pci_topology failed.\n");
+ return;
+ }
+
+ printf("device topology :\n");
+ printf("device node\n");
+ for (i = 0; i < nr; i++) {
+ if (pciinfo[i].node != LIBXL_PCITOPOLOGY_INVALID_ENTRY) {
+ printf("%04x:%02x:%02x.%01x %d\n", pciinfo[i].seg,
+ pciinfo[i].bus,
+ ((pciinfo[i].devfn >> 3) & 0x1f), (pciinfo[i].devfn & 7),
+ pciinfo[i].node);
+ valid_devs++;
+ }
+ }
+
+ if (valid_devs == 0)
+ printf("No device topology data available\n");
+
+ libxl_pcitopology_list_free(pciinfo, nr);
+
+ return;
+}
+
+static void print_info(int numa)
+{
+ output_nodeinfo();
+
+ output_physinfo();
+
+ if (numa) {
+ output_topologyinfo();
+ output_numainfo();
+ }
+ output_xeninfo();
+
+ maybe_printf("xend_config_format : 4\n");
+
+ return;
+}
+
+static void list_vm(void)
+{
+ libxl_vminfo *info;
+ char *domname;
+ int nb_vm, i;
+
+ info = libxl_list_vm(ctx, &nb_vm);
+
+ if (!info) {
+ fprintf(stderr, "libxl_list_vm failed.\n");
+ exit(EXIT_FAILURE);
+ }
+ printf("UUID ID name\n");
+ for (i = 0; i < nb_vm; i++) {
+ domname = libxl_domid_to_name(ctx, info[i].domid);
+ printf(LIBXL_UUID_FMT " %d %-30s\n", LIBXL_UUID_BYTES(info[i].uuid),
+ info[i].domid, domname);
+ free(domname);
+ }
+ libxl_vminfo_list_free(info, nb_vm);
+}
+
+static void list_domains(bool verbose, bool context, bool claim, bool numa,
+ bool cpupool, const libxl_dominfo *info, int nb_domain)
+{
+ int i;
+ static const char shutdown_reason_letters[]= "-rscwS";
+ libxl_bitmap nodemap;
+ libxl_physinfo physinfo;
+
+ libxl_bitmap_init(&nodemap);
+ libxl_physinfo_init(&physinfo);
+
+ printf("Name ID Mem VCPUs\tState\tTime(s)");
+ if (verbose) printf(" UUID Reason-Code\tSecurity Label");
+ if (context && !verbose) printf(" Security Label");
+ if (claim) printf(" Claimed");
+ if (cpupool) printf(" Cpupool");
+ if (numa) {
+ if (libxl_node_bitmap_alloc(ctx, &nodemap, 0)) {
+ fprintf(stderr, "libxl_node_bitmap_alloc_failed.\n");
+ exit(EXIT_FAILURE);
+ }
+ if (libxl_get_physinfo(ctx, &physinfo) != 0) {
+ fprintf(stderr, "libxl_physinfo failed.\n");
+ libxl_bitmap_dispose(&nodemap);
+ exit(EXIT_FAILURE);
+ }
+
+ printf(" NODE Affinity");
+ }
+ printf("\n");
+ for (i = 0; i < nb_domain; i++) {
+ char *domname;
+ libxl_shutdown_reason shutdown_reason;
+ domname = libxl_domid_to_name(ctx, info[i].domid);
+ shutdown_reason = info[i].shutdown ? info[i].shutdown_reason : 0;
+ printf("%-40s %5d %5lu %5d %c%c%c%c%c%c %8.1f",
+ domname,
+ info[i].domid,
+ (unsigned long) ((info[i].current_memkb +
+ info[i].outstanding_memkb)/ 1024),
+ info[i].vcpu_online,
+ info[i].running ? 'r' : '-',
+ info[i].blocked ? 'b' : '-',
+ info[i].paused ? 'p' : '-',
+ info[i].shutdown ? 's' : '-',
+ (shutdown_reason >= 0 &&
+ shutdown_reason < sizeof(shutdown_reason_letters)-1
+ ? shutdown_reason_letters[shutdown_reason] : '?'),
+ info[i].dying ? 'd' : '-',
+ ((float)info[i].cpu_time / 1e9));
+ free(domname);
+ if (verbose) {
+ printf(" " LIBXL_UUID_FMT, LIBXL_UUID_BYTES(info[i].uuid));
+ if (info[i].shutdown) printf(" %8x", shutdown_reason);
+ else printf(" %8s", "-");
+ }
+ if (claim)
+ printf(" %5lu", (unsigned long)info[i].outstanding_memkb / 1024);
+ if (verbose || context)
+ printf(" %16s", info[i].ssid_label ? : "-");
+ if (cpupool) {
+ char *poolname = libxl_cpupoolid_to_name(ctx, info[i].cpupool);
+ printf("%16s", poolname);
+ free(poolname);
+ }
+ if (numa) {
+ libxl_domain_get_nodeaffinity(ctx, info[i].domid, &nodemap);
+
+ putchar(' ');
+ print_bitmap(nodemap.map, physinfo.nr_nodes, stdout);
+ }
+ putchar('\n');
+ }
+
+ libxl_bitmap_dispose(&nodemap);
+ libxl_physinfo_dispose(&physinfo);
+}
+
+static void list_domains_details(const libxl_dominfo *info, int nb_domain)
+{
+ libxl_domain_config d_config;
+
+ int i, rc;
+
+ yajl_gen hand = NULL;
+ yajl_gen_status s;
+ const char *buf;
+ libxl_yajl_length yajl_len = 0;
+
+ if (default_output_format == OUTPUT_FORMAT_JSON) {
+ hand = libxl_yajl_gen_alloc(NULL);
+ if (!hand) {
+ fprintf(stderr, "unable to allocate JSON generator\n");
+ return;
+ }
+
+ s = yajl_gen_array_open(hand);
+ if (s != yajl_gen_status_ok)
+ goto out;
+ } else
+ s = yajl_gen_status_ok;
+
+ for (i = 0; i < nb_domain; i++) {
+ libxl_domain_config_init(&d_config);
+ rc = libxl_retrieve_domain_configuration(ctx, info[i].domid, &d_config);
+ if (rc)
+ continue;
+ if (default_output_format == OUTPUT_FORMAT_JSON)
+ s = printf_info_one_json(hand, info[i].domid, &d_config);
+ else
+ printf_info_sexp(info[i].domid, &d_config, stdout);
+ libxl_domain_config_dispose(&d_config);
+ if (s != yajl_gen_status_ok)
+ goto out;
+ }
+
+ if (default_output_format == OUTPUT_FORMAT_JSON) {
+ s = yajl_gen_array_close(hand);
+ if (s != yajl_gen_status_ok)
+ goto out;
+
+ s = yajl_gen_get_buf(hand, (const unsigned char **)&buf, &yajl_len);
+ if (s != yajl_gen_status_ok)
+ goto out;
+
+ puts(buf);
+ }
+
+out:
+ if (default_output_format == OUTPUT_FORMAT_JSON) {
+ yajl_gen_free(hand);
+ if (s != yajl_gen_status_ok)
+ fprintf(stderr,
+ "unable to format domain config as JSON (YAJL:%d)\n", s);
+ }
+}
+
+
+int main_list(int argc, char **argv)
+{
+ int opt;
+ bool verbose = false;
+ bool context = false;
+ bool details = false;
+ bool cpupool = false;
+ bool numa = false;
+ static struct option opts[] = {
+ {"long", 0, 0, 'l'},
+ {"verbose", 0, 0, 'v'},
+ {"context", 0, 0, 'Z'},
+ {"cpupool", 0, 0, 'c'},
+ {"numa", 0, 0, 'n'},
+ COMMON_LONG_OPTS
+ };
+
+ libxl_dominfo info_buf;
+ libxl_dominfo *info, *info_free=0;
+ int nb_domain, rc;
+
+ SWITCH_FOREACH_OPT(opt, "lvhZcn", opts, "list", 0) {
+ case 'l':
+ details = true;
+ break;
+ case 'v':
+ verbose = true;
+ break;
+ case 'Z':
+ context = true;
+ break;
+ case 'c':
+ cpupool = true;
+ break;
+ case 'n':
+ numa = true;
+ break;
+ }
+
+ libxl_dominfo_init(&info_buf);
+
+ if (optind >= argc) {
+ info = libxl_list_domain(ctx, &nb_domain);
+ if (!info) {
+ fprintf(stderr, "libxl_list_domain failed.\n");
+ return EXIT_FAILURE;
+ }
+ info_free = info;
+ } else if (optind == argc-1) {
+ uint32_t domid = find_domain(argv[optind]);
+ rc = libxl_domain_info(ctx, &info_buf, domid);
+ if (rc == ERROR_DOMAIN_NOTFOUND) {
+ fprintf(stderr, "Error: Domain \'%s\' does not exist.\n",
+ argv[optind]);
+ return EXIT_FAILURE;
+ }
+ if (rc) {
+ fprintf(stderr, "libxl_domain_info failed (code %d).\n", rc);
+ return EXIT_FAILURE;
+ }
+ info = &info_buf;
+ nb_domain = 1;
+ } else {
+ help("list");
+ return EXIT_FAILURE;
+ }
+
+ if (details)
+ list_domains_details(info, nb_domain);
+ else
+ list_domains(verbose, context, false /* claim */, numa, cpupool,
+ info, nb_domain);
+
+ if (info_free)
+ libxl_dominfo_list_free(info, nb_domain);
+
+ libxl_dominfo_dispose(&info_buf);
+
+ return EXIT_SUCCESS;
+}
+
+int main_vm_list(int argc, char **argv)
+{
+ int opt;
+
+ SWITCH_FOREACH_OPT(opt, "", NULL, "vm-list", 0) {
+ /* No options */
+ }
+
+ list_vm();
+ return EXIT_SUCCESS;
+}
+
+int main_info(int argc, char **argv)
+{
+ int opt;
+ static struct option opts[] = {
+ {"numa", 0, 0, 'n'},
+ COMMON_LONG_OPTS
+ };
+ int numa = 0;
+
+ SWITCH_FOREACH_OPT(opt, "n", opts, "info", 0) {
+ case 'n':
+ numa = 1;
+ break;
+ }
+
+ /*
+ * If an extra argument is provided, filter out a specific piece of
+ * information.
+ */
+ if (numa == 0 && argc > optind)
+ info_name = argv[optind];
+
+ print_info(numa);
+ return 0;
+}
+
+int main_domid(int argc, char **argv)
+{
+ uint32_t domid;
+ int opt;
+ const char *domname = NULL;
+
+ SWITCH_FOREACH_OPT(opt, "", NULL, "domid", 1) {
+ /* No options */
+ }
+
+ domname = argv[optind];
+
+ if (libxl_name_to_domid(ctx, domname, &domid)) {
+ fprintf(stderr, "Can't get domid of domain name '%s', maybe this domain does not exist.\n", domname);
+ return EXIT_FAILURE;
+ }
+
+ printf("%u\n", domid);
+
+ return EXIT_SUCCESS;
+}
+
+int main_domname(int argc, char **argv)
+{
+ uint32_t domid;
+ int opt;
+ char *domname = NULL;
+ char *endptr = NULL;
+
+ SWITCH_FOREACH_OPT(opt, "", NULL, "domname", 1) {
+ /* No options */
+ }
+
+ domid = strtol(argv[optind], &endptr, 10);
+ if (domid == 0 && !strcmp(endptr, argv[optind])) {
+ /*no digits at all*/
+ fprintf(stderr, "Invalid domain id.\n\n");
+ return EXIT_FAILURE;
+ }
+
+ domname = libxl_domid_to_name(ctx, domid);
+ if (!domname) {
+ fprintf(stderr, "Can't get domain name of domain id '%u', maybe this domain does not exist.\n", domid);
+ return EXIT_FAILURE;
+ }
+
+ printf("%s\n", domname);
+ free(domname);
+
+ return EXIT_SUCCESS;
+}
+
+static char *uptime_to_string(unsigned long uptime, int short_mode)
+{
+ int sec, min, hour, day;
+ char *time_string;
+
+ day = (int)(uptime / 86400);
+ uptime -= (day * 86400);
+ hour = (int)(uptime / 3600);
+ uptime -= (hour * 3600);
+ min = (int)(uptime / 60);
+ uptime -= (min * 60);
+ sec = uptime;
+
+ if (short_mode)
+ if (day > 1)
+ xasprintf(&time_string, "%d days, %2d:%02d", day, hour, min);
+ else if (day == 1)
+ xasprintf(&time_string, "%d day, %2d:%02d", day, hour, min);
+ else
+ xasprintf(&time_string, "%2d:%02d", hour, min);
+ else
+ if (day > 1)
+ xasprintf(&time_string, "%d days, %2d:%02d:%02d", day, hour, min, sec);
+ else if (day == 1)
+ xasprintf(&time_string, "%d day, %2d:%02d:%02d", day, hour, min, sec);
+ else
+ xasprintf(&time_string, "%2d:%02d:%02d", hour, min, sec);
+
+ return time_string;
+}
+
+int main_claims(int argc, char **argv)
+{
+ libxl_dominfo *info;
+ int opt;
+ int nb_domain;
+
+ SWITCH_FOREACH_OPT(opt, "", NULL, "claims", 0) {
+ /* No options */
+ }
+
+ if (!claim_mode)
+ fprintf(stderr, "claim_mode not enabled (see man xl.conf).\n");
+
+ info = libxl_list_domain(ctx, &nb_domain);
+ if (!info) {
+ fprintf(stderr, "libxl_list_domain failed.\n");
+ return 1;
+ }
+
+ list_domains(false /* verbose */, false /* context */, true /* claim */,
+ false /* numa */, false /* cpupool */, info, nb_domain);
+
+ libxl_dominfo_list_free(info, nb_domain);
+ return 0;
+}
+
+static char *current_time_to_string(time_t now)
+{
+ char now_str[100];
+ struct tm *tmp;
+
+ tmp = localtime(&now);
+ if (tmp == NULL) {
+ fprintf(stderr, "Get localtime error");
+ exit(-1);
+ }
+ if (strftime(now_str, sizeof(now_str), "%H:%M:%S", tmp) == 0) {
+ fprintf(stderr, "strftime returned 0");
+ exit(-1);
+ }
+ return strdup(now_str);
+}
+
+static void print_dom0_uptime(int short_mode, time_t now)
+{
+ int fd;
+ ssize_t nr;
+ char buf[512];
+ uint32_t uptime = 0;
+ char *uptime_str = NULL;
+ char *now_str = NULL;
+ char *domname;
+
+ fd = open("/proc/uptime", O_RDONLY);
+ if (fd == -1)
+ goto err;
+
+ nr = read(fd, buf, sizeof(buf) - 1);
+ if (nr == -1) {
+ close(fd);
+ goto err;
+ }
+ close(fd);
+
+ buf[nr] = '\0';
+
+ strtok(buf, " ");
+ uptime = strtoul(buf, NULL, 10);
+
+ domname = libxl_domid_to_name(ctx, 0);
+ if (short_mode)
+ {
+ now_str = current_time_to_string(now);
+ uptime_str = uptime_to_string(uptime, 1);
+ printf(" %s up %s, %s (%d)\n", now_str, uptime_str,
+ domname, 0);
+ }
+ else
+ {
+ now_str = NULL;
+ uptime_str = uptime_to_string(uptime, 0);
+ printf("%-33s %4d %s\n", domname,
+ 0, uptime_str);
+ }
+
+ free(now_str);
+ free(uptime_str);
+ free(domname);
+ return;
+err:
+ fprintf(stderr, "Can not get Dom0 uptime.\n");
+ exit(-1);
+}
+
+static void print_domU_uptime(uint32_t domuid, int short_mode, time_t now)
+{
+ uint32_t s_time = 0;
+ uint32_t uptime = 0;
+ char *uptime_str = NULL;
+ char *now_str = NULL;
+ char *domname;
+
+ s_time = libxl_vm_get_start_time(ctx, domuid);
+ if (s_time == -1)
+ return;
+ uptime = now - s_time;
+ domname = libxl_domid_to_name(ctx, domuid);
+ if (short_mode)
+ {
+ now_str = current_time_to_string(now);
+ uptime_str = uptime_to_string(uptime, 1);
+ printf(" %s up %s, %s (%d)\n", now_str, uptime_str,
+ domname, domuid);
+ }
+ else
+ {
+ now_str = NULL;
+ uptime_str = uptime_to_string(uptime, 0);
+ printf("%-33s %4d %s\n", domname,
+ domuid, uptime_str);
+ }
+
+ free(domname);
+ free(now_str);
+ free(uptime_str);
+ return;
+}
+
+static void print_uptime(int short_mode, uint32_t doms[], int nb_doms)
+{
+ libxl_vminfo *info;
+ time_t now;
+ int nb_vm, i;
+
+ now = time(NULL);
+
+ if (!short_mode)
+ printf("%-33s %4s %s\n", "Name", "ID", "Uptime");
+
+ if (nb_doms == 0) {
+ print_dom0_uptime(short_mode, now);
+ info = libxl_list_vm(ctx, &nb_vm);
+ if (info == NULL) {
+ fprintf(stderr, "Could not list vms.\n");
+ return;
+ }
+ for (i = 0; i < nb_vm; i++) {
+ if (info[i].domid == 0) continue;
+ print_domU_uptime(info[i].domid, short_mode, now);
+ }
+ libxl_vminfo_list_free(info, nb_vm);
+ } else {
+ for (i = 0; i < nb_doms; i++) {
+ if (doms[i] == 0)
+ print_dom0_uptime(short_mode, now);
+ else
+ print_domU_uptime(doms[i], short_mode, now);
+ }
+ }
+}
+
+int main_uptime(int argc, char **argv)
+{
+ const char *dom;
+ int short_mode = 0;
+ uint32_t domains[100];
+ int nb_doms = 0;
+ int opt;
+
+ SWITCH_FOREACH_OPT(opt, "s", NULL, "uptime", 0) {
+ case 's':
+ short_mode = 1;
+ break;
+ }
+
+ for (;(dom = argv[optind]) != NULL; nb_doms++,optind++)
+ domains[nb_doms] = find_domain(dom);
+
+ print_uptime(short_mode, domains, nb_doms);
+
+ return 0;
+}
+
+int main_dmesg(int argc, char **argv)
+{
+ unsigned int clear = 0;
+ libxl_xen_console_reader *cr;
+ char *line;
+ int opt, ret = 1;
+
+ SWITCH_FOREACH_OPT(opt, "c", NULL, "dmesg", 0) {
+ case 'c':
+ clear = 1;
+ break;
+ }
+
+ cr = libxl_xen_console_read_start(ctx, clear);
+ if (!cr)
+ goto finish;
+
+ while ((ret = libxl_xen_console_read_line(ctx, cr, &line)) > 0)
+ printf("%s", line);
+
+finish:
+ if (cr)
+ libxl_xen_console_read_finish(ctx, cr);
+ return ret ? EXIT_FAILURE : EXIT_SUCCESS;
+}
+
+int main_top(int argc, char **argv)
+{
+ int opt;
+
+ SWITCH_FOREACH_OPT(opt, "", NULL, "top", 0) {
+ /* No options */
+ }
+
+ return system("xentop");
+}
+
+
+/*
+ * Local variables:
+ * mode: C
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */