Index: usr.sbin/bhyve/Makefile =================================================================== --- usr.sbin/bhyve/Makefile +++ usr.sbin/bhyve/Makefile @@ -70,7 +70,7 @@ .PATH: ${BHYVE_SYSDIR}/sys/amd64/vmm SRCS+= vmm_instruction_emul.c -LIBADD= vmmapi md pthread z util sbuf cam +LIBADD= vmmapi md pthread z util sbuf cam xo .if ${MK_OPENSSL} == "no" CFLAGS+=-DNO_OPENSSL Index: usr.sbin/bhyve/bhyverun.c =================================================================== --- usr.sbin/bhyve/bhyverun.c +++ usr.sbin/bhyve/bhyverun.c @@ -58,6 +58,7 @@ #include #include #include +#include #include #ifndef WITHOUT_CAPSICUM @@ -141,7 +142,7 @@ { fprintf(stderr, - "Usage: %s [-abehuwxACHPSWY]\n" + "Usage: %s [-abefhuwxACHPSWY]\n" " %*s [-c [[cpus=]numcpus][,sockets=n][,cores=n][,threads=n]]\n" " %*s [-g ] [-l ]\n" " %*s [-m mem] [-p vcpu:hostcpu] [-s ] [-U uuid] \n" @@ -150,6 +151,7 @@ " -c: number of cpus and/or topology specification\n" " -C: include guest memory in core file\n" " -e: exit on unhandled I/O access\n" + " -f: show supported emulator features\n" " -g: gdb port\n" " -h: help\n" " -H: vmexit from the guest on hlt\n" @@ -171,6 +173,85 @@ exit(code); } +static void +show_emulator_features() +{ + /* top-level container */ + xo_open_container("bhyve"); + xo_emit("{L:Schema version}: {:schema_version}\n", "1.0"); + /* features collection container */ + xo_open_container("features"); + + /* rtc_utc */ + xo_open_container("feature"); + xo_open_container("rtc_utc"); + xo_emit("\n{T:rtc_utc}\n"); + xo_emit("{L:Description}: {:description}\n", "RTC keeps UTC time"); + + xo_open_container("cmd"); + xo_emit("{L:Command line switch}: {:switch}\n", "-u"); + xo_close_container("cmd"); + + xo_close_container("rtc_utc"); + xo_close_container("feature"); + + /* wire_guest_memory */ + xo_open_container("feature"); + xo_open_container("wire_guest_memory"); + xo_emit("\n{T:wire_guest_memory}\n"); + xo_emit("{L:Description}: {:description}\n", "Wire guest memory"); + + xo_open_container("cmd"); + xo_emit("{L:Command line switch}: {:switch}\n", "-S"); + xo_close_container("cmd"); + + xo_close_container("wire_guest_memory"); + xo_close_container("feature"); + + /* devices */ + xo_open_container("feature"); + xo_open_container("devices"); + xo_emit("\n{T:devices}\n"); + xo_emit("{L:Description}: {:description}\n", "Devices support"); + + xo_open_container("cmd"); + xo_emit("{L:Command line switch}: {:switch}\n", "-s"); + + xo_open_list("arguments"); + + /* virtio-net */ + xo_open_instance("arguments"); + xo_emit("{L:Arguments}: {:options/%s} {L:Description}: {:description/%s}\n", + "virtio-net,tapN,mac=xx:xx:xx:xx:xx:xx", + "Virtio network device"); + xo_close_instance("arguments"); + + /* virtio-block */ + xo_open_instance("arguments"); + xo_emit("{L:Arguments}: {:options/%s} {L:Description}: {:description/%s}\n", + "virtio-blk,path,nocache,direct,ro,sectorsize=logical/physical", + "Virtio block device"); + xo_close_instance("arguments"); + + /* fbuf */ + xo_open_instance("arguments"); + xo_emit("{L:Arguments}: '{:options/%s}' {L:Description}: {:description/%s}\n", + "fbuf,rfb,rfb=IP:port,w=width,h=heigh,vga=vgaconf,wait,password=password", + "Framebuffer device"); + xo_close_instance("arguments"); + + xo_close_list("arguments"); + + xo_close_container("cmd"); + + xo_close_container("devices"); + xo_close_container("feature"); + + xo_close_container("features"); + xo_close_container("bhyve"); + xo_finish(); +} + /* * XXX This parser is known to have the following issues: * 1. It accepts null key=value tokens ",,". @@ -922,7 +1003,11 @@ rtc_localtime = 1; memflags = 0; - optstr = "abehuwxACHIPSWYp:g:G:c:s:m:l:U:"; + argc = xo_parse_args(argc, argv); + if (argc < 0) + exit(1); + + optstr = "abefhuwxACHIPSWYp:g:G:c:s:m:l:U:"; while ((c = getopt(argc, argv, optstr)) != -1) { switch (c) { case 'a': @@ -949,6 +1034,10 @@ case 'C': memflags |= VM_MEM_F_INCORE; break; + case 'f': + show_emulator_features(); + exit(0); + break; case 'g': dbg_port = atoi(optarg); break;