Index: usr.sbin/bhyvectl/bhyvectl.c =================================================================== --- usr.sbin/bhyvectl/bhyvectl.c +++ usr.sbin/bhyvectl/bhyvectl.c @@ -36,10 +36,10 @@ #include #include +#include #include #include #include -#include #include #include #include @@ -77,6 +77,7 @@ " [--cpu=]\n" " [--create]\n" " [--destroy]\n" + " [--list]\n" " [--get-all]\n" " [--get-stats]\n" " [--set-desc-ds]\n" @@ -239,7 +240,7 @@ static int inject_nmi, assert_lapic_lvt; static int force_reset, force_poweroff; static const char *capname; -static int create, destroy, get_memmap, get_memseg; +static int create, destroy, list, get_memmap, get_memseg; static int get_intinfo; static int get_active_cpus, get_suspended_cpus; static uint64_t memsize; @@ -585,6 +586,25 @@ printf("\n"); } +/* + * Parse the number of CPU specified to a VM and + * return the total number of it. + */ +static int +count_vcpus(const cpuset_t *cpus) +{ + int i, count = 0; + + if (!CPU_EMPTY(cpus)) { + for (i = 0; i < CPU_SETSIZE; i++) { + if (CPU_ISSET(count, cpus)) + count++; + } + } + + return count; +} + static void print_intinfo(const char *banner, uint64_t info) { @@ -1376,6 +1396,7 @@ { "run", NO_ARG, &run, 1 }, { "create", NO_ARG, &create, 1 }, { "destroy", NO_ARG, &destroy, 1 }, + { "list", NO_ARG, &list, 1}, { "inject-nmi", NO_ARG, &inject_nmi, 1 }, { "force-reset", NO_ARG, &force_reset, 1 }, { "force-poweroff", NO_ARG, &force_poweroff, 1 }, @@ -1523,6 +1544,67 @@ return ("UNK"); } +static void +list_vm(char *vmname) +{ + DIR *path_vmm; + struct dirent *dir; + struct vmctx *ctx; + int error, vcpus = 0; + cpuset_t cpus; + char numbuf[8]; + vm_paddr_t gpa; + vm_ooffset_t segoff; + int segid, flags, prot; + size_t maplen; + + printf("NAME\t\t MEM\t\t\t VCPU\n"); + + path_vmm = opendir("/dev/vmm"); + if (path_vmm) { + while ((dir = readdir(path_vmm)) != NULL) { + gpa = 0; + if (strcmp(".", dir->d_name) != 0 && + strcmp("..", dir->d_name) !=0 && + strstr(dir->d_name, "bootrom") == NULL) { + + ctx = vm_open(dir->d_name); + if (ctx == NULL) { + printf("You have no permission to open: %s\n", vmname); + exit (1); + } + + error = vm_mmap_getnext(ctx, &gpa, &segid, &segoff, &maplen, + &prot, &flags); + if (error) { + printf("Error to get memory segment information.\n"); + exit (1); + } + + humanize_number(numbuf, sizeof(numbuf), maplen, "B", + HN_AUTOSCALE, HN_NOSPACE); + + error = vm_active_cpus(ctx, &cpus); + if (!error) + vcpus = count_vcpus(&cpus); + else { + printf("Error to get the number of vcpus.\n"); + exit (1); + } + + if (vmname && strcmp(vmname, dir->d_name) == 0) { + printf("%s\t\t %s\t\t\t %d\n", dir->d_name, + numbuf, vcpus); + break; + } else if (!vmname) + printf("%s\t\t %s\t\t\t %d\n", dir->d_name, + numbuf, vcpus); + } + } + } +} + + static int show_memmap(struct vmctx *ctx) { @@ -1763,7 +1845,16 @@ argc -= optind; argv += optind; - if (vmname == NULL) + if (list) { + if (vmname) + list_vm(vmname); + else + list_vm(NULL); + + exit (0); + } + + if (vmname == NULL && !list) usage(cpu_intel); error = 0;