xref: /dpdk/examples/vm_power_manager/vm_power_cli.c (revision 567997b977c29345a1ecb3ab17496b1d4e79ed57)
13842bf24SAlan Carew /*-
23842bf24SAlan Carew  *   BSD LICENSE
33842bf24SAlan Carew  *
43842bf24SAlan Carew  *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
53842bf24SAlan Carew  *   All rights reserved.
63842bf24SAlan Carew  *
73842bf24SAlan Carew  *   Redistribution and use in source and binary forms, with or without
83842bf24SAlan Carew  *   modification, are permitted provided that the following conditions
93842bf24SAlan Carew  *   are met:
103842bf24SAlan Carew  *
113842bf24SAlan Carew  *     * Redistributions of source code must retain the above copyright
123842bf24SAlan Carew  *       notice, this list of conditions and the following disclaimer.
133842bf24SAlan Carew  *     * Redistributions in binary form must reproduce the above copyright
143842bf24SAlan Carew  *       notice, this list of conditions and the following disclaimer in
153842bf24SAlan Carew  *       the documentation and/or other materials provided with the
163842bf24SAlan Carew  *       distribution.
173842bf24SAlan Carew  *     * Neither the name of Intel Corporation nor the names of its
183842bf24SAlan Carew  *       contributors may be used to endorse or promote products derived
193842bf24SAlan Carew  *       from this software without specific prior written permission.
203842bf24SAlan Carew  *
213842bf24SAlan Carew  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
223842bf24SAlan Carew  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
233842bf24SAlan Carew  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
243842bf24SAlan Carew  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
253842bf24SAlan Carew  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
263842bf24SAlan Carew  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
273842bf24SAlan Carew  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
283842bf24SAlan Carew  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
293842bf24SAlan Carew  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
303842bf24SAlan Carew  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
313842bf24SAlan Carew  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
323842bf24SAlan Carew  */
333842bf24SAlan Carew 
343842bf24SAlan Carew #include <stdlib.h>
353842bf24SAlan Carew #include <stdint.h>
363842bf24SAlan Carew #include <inttypes.h>
373842bf24SAlan Carew #include <stdio.h>
383842bf24SAlan Carew #include <string.h>
393842bf24SAlan Carew #include <termios.h>
403842bf24SAlan Carew #include <errno.h>
413842bf24SAlan Carew 
423842bf24SAlan Carew #include <cmdline_rdline.h>
433842bf24SAlan Carew #include <cmdline_parse.h>
443842bf24SAlan Carew #include <cmdline_parse_string.h>
453842bf24SAlan Carew #include <cmdline_parse_num.h>
463842bf24SAlan Carew #include <cmdline_socket.h>
473842bf24SAlan Carew #include <cmdline.h>
483842bf24SAlan Carew 
493842bf24SAlan Carew #include "vm_power_cli.h"
503842bf24SAlan Carew #include "channel_manager.h"
513842bf24SAlan Carew #include "channel_monitor.h"
523842bf24SAlan Carew #include "power_manager.h"
533842bf24SAlan Carew #include "channel_commands.h"
543842bf24SAlan Carew 
553842bf24SAlan Carew struct cmd_quit_result {
563842bf24SAlan Carew 	cmdline_fixed_string_t quit;
573842bf24SAlan Carew };
583842bf24SAlan Carew 
593842bf24SAlan Carew static void cmd_quit_parsed(__attribute__((unused)) void *parsed_result,
603842bf24SAlan Carew 		struct cmdline *cl,
613842bf24SAlan Carew 		__attribute__((unused)) void *data)
623842bf24SAlan Carew {
633842bf24SAlan Carew 	channel_monitor_exit();
643842bf24SAlan Carew 	channel_manager_exit();
653842bf24SAlan Carew 	power_manager_exit();
663842bf24SAlan Carew 	cmdline_quit(cl);
673842bf24SAlan Carew }
683842bf24SAlan Carew 
693842bf24SAlan Carew cmdline_parse_token_string_t cmd_quit_quit =
703842bf24SAlan Carew 	TOKEN_STRING_INITIALIZER(struct cmd_quit_result, quit, "quit");
713842bf24SAlan Carew 
723842bf24SAlan Carew cmdline_parse_inst_t cmd_quit = {
733842bf24SAlan Carew 	.f = cmd_quit_parsed,  /* function to call */
743842bf24SAlan Carew 	.data = NULL,      /* 2nd arg of func */
753842bf24SAlan Carew 	.help_str = "close the application",
763842bf24SAlan Carew 	.tokens = {        /* token list, NULL terminated */
773842bf24SAlan Carew 		(void *)&cmd_quit_quit,
783842bf24SAlan Carew 		NULL,
793842bf24SAlan Carew 	},
803842bf24SAlan Carew };
813842bf24SAlan Carew 
823842bf24SAlan Carew /* *** VM operations *** */
833842bf24SAlan Carew struct cmd_show_vm_result {
843842bf24SAlan Carew 	cmdline_fixed_string_t show_vm;
853842bf24SAlan Carew 	cmdline_fixed_string_t vm_name;
863842bf24SAlan Carew };
873842bf24SAlan Carew 
883842bf24SAlan Carew static void
893842bf24SAlan Carew cmd_show_vm_parsed(void *parsed_result, struct cmdline *cl,
903842bf24SAlan Carew 		__attribute__((unused)) void *data)
913842bf24SAlan Carew {
923842bf24SAlan Carew 	struct cmd_show_vm_result *res = parsed_result;
933842bf24SAlan Carew 	struct vm_info info;
943842bf24SAlan Carew 	unsigned i;
953842bf24SAlan Carew 
963842bf24SAlan Carew 	if (get_info_vm(res->vm_name, &info) != 0)
973842bf24SAlan Carew 		return;
983842bf24SAlan Carew 	cmdline_printf(cl, "VM: '%s', status = ", info.name);
993842bf24SAlan Carew 	if (info.status == CHANNEL_MGR_VM_ACTIVE)
1003842bf24SAlan Carew 		cmdline_printf(cl, "ACTIVE\n");
1013842bf24SAlan Carew 	else
1023842bf24SAlan Carew 		cmdline_printf(cl, "INACTIVE\n");
1033842bf24SAlan Carew 	cmdline_printf(cl, "Channels %u\n", info.num_channels);
1043842bf24SAlan Carew 	for (i = 0; i < info.num_channels; i++) {
1053842bf24SAlan Carew 		cmdline_printf(cl, "  [%u]: %s, status = ", i,
1063842bf24SAlan Carew 				info.channels[i].channel_path);
1073842bf24SAlan Carew 		switch (info.channels[i].status) {
1083842bf24SAlan Carew 		case CHANNEL_MGR_CHANNEL_CONNECTED:
1093842bf24SAlan Carew 			cmdline_printf(cl, "CONNECTED\n");
1103842bf24SAlan Carew 			break;
1113842bf24SAlan Carew 		case CHANNEL_MGR_CHANNEL_DISCONNECTED:
1123842bf24SAlan Carew 			cmdline_printf(cl, "DISCONNECTED\n");
1133842bf24SAlan Carew 			break;
1143842bf24SAlan Carew 		case CHANNEL_MGR_CHANNEL_DISABLED:
1153842bf24SAlan Carew 			cmdline_printf(cl, "DISABLED\n");
1163842bf24SAlan Carew 			break;
1173842bf24SAlan Carew 		case CHANNEL_MGR_CHANNEL_PROCESSING:
1183842bf24SAlan Carew 			cmdline_printf(cl, "PROCESSING\n");
1193842bf24SAlan Carew 			break;
1203842bf24SAlan Carew 		default:
1213842bf24SAlan Carew 			cmdline_printf(cl, "UNKNOWN\n");
1223842bf24SAlan Carew 			break;
1233842bf24SAlan Carew 		}
1243842bf24SAlan Carew 	}
1253842bf24SAlan Carew 	cmdline_printf(cl, "Virtual CPU(s): %u\n", info.num_vcpus);
1263842bf24SAlan Carew 	for (i = 0; i < info.num_vcpus; i++) {
1273842bf24SAlan Carew 		cmdline_printf(cl, "  [%u]: Physical CPU Mask 0x%"PRIx64"\n", i,
1283842bf24SAlan Carew 				info.pcpu_mask[i]);
1293842bf24SAlan Carew 	}
1303842bf24SAlan Carew }
1313842bf24SAlan Carew 
1323842bf24SAlan Carew 
1333842bf24SAlan Carew 
1343842bf24SAlan Carew cmdline_parse_token_string_t cmd_vm_show =
1353842bf24SAlan Carew 	TOKEN_STRING_INITIALIZER(struct cmd_show_vm_result,
1363842bf24SAlan Carew 				show_vm, "show_vm");
1373842bf24SAlan Carew cmdline_parse_token_string_t cmd_show_vm_name =
1383842bf24SAlan Carew 	TOKEN_STRING_INITIALIZER(struct cmd_show_vm_result,
1393842bf24SAlan Carew 			vm_name, NULL);
1403842bf24SAlan Carew 
1413842bf24SAlan Carew cmdline_parse_inst_t cmd_show_vm_set = {
1423842bf24SAlan Carew 	.f = cmd_show_vm_parsed,
1433842bf24SAlan Carew 	.data = NULL,
1443842bf24SAlan Carew 	.help_str = "show_vm <vm_name>, prints the information on the "
1453842bf24SAlan Carew 			"specified VM(s), the information lists the number of vCPUS, the "
1463842bf24SAlan Carew 			"pinning to pCPU(s) as a bit mask, along with any communication "
1473842bf24SAlan Carew 			"channels associated with each VM",
1483842bf24SAlan Carew 	.tokens = {
1493842bf24SAlan Carew 		(void *)&cmd_vm_show,
1503842bf24SAlan Carew 		(void *)&cmd_show_vm_name,
1513842bf24SAlan Carew 		NULL,
1523842bf24SAlan Carew 	},
1533842bf24SAlan Carew };
1543842bf24SAlan Carew 
1553842bf24SAlan Carew /* *** vCPU to pCPU mapping operations *** */
1563842bf24SAlan Carew struct cmd_set_pcpu_mask_result {
1573842bf24SAlan Carew 	cmdline_fixed_string_t set_pcpu_mask;
1583842bf24SAlan Carew 	cmdline_fixed_string_t vm_name;
1593842bf24SAlan Carew 	uint8_t vcpu;
1603842bf24SAlan Carew 	uint64_t core_mask;
1613842bf24SAlan Carew };
1623842bf24SAlan Carew 
1633842bf24SAlan Carew static void
1643842bf24SAlan Carew cmd_set_pcpu_mask_parsed(void *parsed_result, struct cmdline *cl,
1653842bf24SAlan Carew 		__attribute__((unused)) void *data)
1663842bf24SAlan Carew {
1673842bf24SAlan Carew 	struct cmd_set_pcpu_mask_result *res = parsed_result;
1683842bf24SAlan Carew 
1693842bf24SAlan Carew 	if (set_pcpus_mask(res->vm_name, res->vcpu, res->core_mask) == 0)
1703842bf24SAlan Carew 		cmdline_printf(cl, "Pinned vCPU(%"PRId8") to pCPU core "
1713842bf24SAlan Carew 				"mask(0x%"PRIx64")\n", res->vcpu, res->core_mask);
1723842bf24SAlan Carew 	else
1733842bf24SAlan Carew 		cmdline_printf(cl, "Unable to pin vCPU(%"PRId8") to pCPU core "
1743842bf24SAlan Carew 				"mask(0x%"PRIx64")\n", res->vcpu, res->core_mask);
1753842bf24SAlan Carew }
1763842bf24SAlan Carew 
1773842bf24SAlan Carew cmdline_parse_token_string_t cmd_set_pcpu_mask =
1783842bf24SAlan Carew 		TOKEN_STRING_INITIALIZER(struct cmd_set_pcpu_mask_result,
1793842bf24SAlan Carew 				set_pcpu_mask, "set_pcpu_mask");
1803842bf24SAlan Carew cmdline_parse_token_string_t cmd_set_pcpu_mask_vm_name =
1813842bf24SAlan Carew 		TOKEN_STRING_INITIALIZER(struct cmd_set_pcpu_mask_result,
1823842bf24SAlan Carew 				vm_name, NULL);
1833842bf24SAlan Carew cmdline_parse_token_num_t set_pcpu_mask_vcpu =
1843842bf24SAlan Carew 		TOKEN_NUM_INITIALIZER(struct cmd_set_pcpu_mask_result,
1853842bf24SAlan Carew 				vcpu, UINT8);
1863842bf24SAlan Carew cmdline_parse_token_num_t set_pcpu_mask_core_mask =
1873842bf24SAlan Carew 		TOKEN_NUM_INITIALIZER(struct cmd_set_pcpu_mask_result,
1883842bf24SAlan Carew 				core_mask, UINT64);
1893842bf24SAlan Carew 
1903842bf24SAlan Carew 
1913842bf24SAlan Carew cmdline_parse_inst_t cmd_set_pcpu_mask_set = {
1923842bf24SAlan Carew 		.f = cmd_set_pcpu_mask_parsed,
1933842bf24SAlan Carew 		.data = NULL,
1943842bf24SAlan Carew 		.help_str = "set_pcpu_mask <vm_name> <vcpu> <pcpu>, Set the binding "
1953842bf24SAlan Carew 				"of Virtual CPU on VM to the Physical CPU mask.",
1963842bf24SAlan Carew 				.tokens = {
1973842bf24SAlan Carew 						(void *)&cmd_set_pcpu_mask,
1983842bf24SAlan Carew 						(void *)&cmd_set_pcpu_mask_vm_name,
1993842bf24SAlan Carew 						(void *)&set_pcpu_mask_vcpu,
2003842bf24SAlan Carew 						(void *)&set_pcpu_mask_core_mask,
2013842bf24SAlan Carew 						NULL,
2023842bf24SAlan Carew 		},
2033842bf24SAlan Carew };
2043842bf24SAlan Carew 
2053842bf24SAlan Carew struct cmd_set_pcpu_result {
2063842bf24SAlan Carew 	cmdline_fixed_string_t set_pcpu;
2073842bf24SAlan Carew 	cmdline_fixed_string_t vm_name;
2083842bf24SAlan Carew 	uint8_t vcpu;
2093842bf24SAlan Carew 	uint8_t core;
2103842bf24SAlan Carew };
2113842bf24SAlan Carew 
2123842bf24SAlan Carew static void
2133842bf24SAlan Carew cmd_set_pcpu_parsed(void *parsed_result, struct cmdline *cl,
2143842bf24SAlan Carew 		__attribute__((unused)) void *data)
2153842bf24SAlan Carew {
2163842bf24SAlan Carew 	struct cmd_set_pcpu_result *res = parsed_result;
2173842bf24SAlan Carew 
2183842bf24SAlan Carew 	if (set_pcpu(res->vm_name, res->vcpu, res->core) == 0)
2193842bf24SAlan Carew 		cmdline_printf(cl, "Pinned vCPU(%"PRId8") to pCPU core "
2203842bf24SAlan Carew 				"%"PRId8")\n", res->vcpu, res->core);
2213842bf24SAlan Carew 	else
2223842bf24SAlan Carew 		cmdline_printf(cl, "Unable to pin vCPU(%"PRId8") to pCPU core "
2233842bf24SAlan Carew 				"%"PRId8")\n", res->vcpu, res->core);
2243842bf24SAlan Carew }
2253842bf24SAlan Carew 
2263842bf24SAlan Carew cmdline_parse_token_string_t cmd_set_pcpu =
2273842bf24SAlan Carew 		TOKEN_STRING_INITIALIZER(struct cmd_set_pcpu_result,
2283842bf24SAlan Carew 				set_pcpu, "set_pcpu");
2293842bf24SAlan Carew cmdline_parse_token_string_t cmd_set_pcpu_vm_name =
2303842bf24SAlan Carew 		TOKEN_STRING_INITIALIZER(struct cmd_set_pcpu_result,
2313842bf24SAlan Carew 				vm_name, NULL);
2323842bf24SAlan Carew cmdline_parse_token_num_t set_pcpu_vcpu =
2333842bf24SAlan Carew 		TOKEN_NUM_INITIALIZER(struct cmd_set_pcpu_result,
2343842bf24SAlan Carew 				vcpu, UINT8);
2353842bf24SAlan Carew cmdline_parse_token_num_t set_pcpu_core =
2363842bf24SAlan Carew 		TOKEN_NUM_INITIALIZER(struct cmd_set_pcpu_result,
2373842bf24SAlan Carew 				core, UINT64);
2383842bf24SAlan Carew 
2393842bf24SAlan Carew 
2403842bf24SAlan Carew cmdline_parse_inst_t cmd_set_pcpu_set = {
2413842bf24SAlan Carew 		.f = cmd_set_pcpu_parsed,
2423842bf24SAlan Carew 		.data = NULL,
2433842bf24SAlan Carew 		.help_str = "set_pcpu <vm_name> <vcpu> <pcpu>, Set the binding "
2443842bf24SAlan Carew 				"of Virtual CPU on VM to the Physical CPU.",
2453842bf24SAlan Carew 				.tokens = {
2463842bf24SAlan Carew 						(void *)&cmd_set_pcpu,
2473842bf24SAlan Carew 						(void *)&cmd_set_pcpu_vm_name,
2483842bf24SAlan Carew 						(void *)&set_pcpu_vcpu,
2493842bf24SAlan Carew 						(void *)&set_pcpu_core,
2503842bf24SAlan Carew 						NULL,
2513842bf24SAlan Carew 		},
2523842bf24SAlan Carew };
2533842bf24SAlan Carew 
2543842bf24SAlan Carew struct cmd_vm_op_result {
2553842bf24SAlan Carew 	cmdline_fixed_string_t op_vm;
2563842bf24SAlan Carew 	cmdline_fixed_string_t vm_name;
2573842bf24SAlan Carew };
2583842bf24SAlan Carew 
2593842bf24SAlan Carew static void
2603842bf24SAlan Carew cmd_vm_op_parsed(void *parsed_result, struct cmdline *cl,
2613842bf24SAlan Carew 		__attribute__((unused)) void *data)
2623842bf24SAlan Carew {
2633842bf24SAlan Carew 	struct cmd_vm_op_result *res = parsed_result;
2643842bf24SAlan Carew 
2653842bf24SAlan Carew 	if (!strcmp(res->op_vm, "add_vm")) {
2663842bf24SAlan Carew 		if (add_vm(res->vm_name) < 0)
2673842bf24SAlan Carew 			cmdline_printf(cl, "Unable to add VM '%s'\n", res->vm_name);
2683842bf24SAlan Carew 	} else if (remove_vm(res->vm_name) < 0)
2693842bf24SAlan Carew 		cmdline_printf(cl, "Unable to remove VM '%s'\n", res->vm_name);
2703842bf24SAlan Carew }
2713842bf24SAlan Carew 
2723842bf24SAlan Carew cmdline_parse_token_string_t cmd_vm_op =
2733842bf24SAlan Carew 	TOKEN_STRING_INITIALIZER(struct cmd_vm_op_result,
2743842bf24SAlan Carew 			op_vm, "add_vm#rm_vm");
2753842bf24SAlan Carew cmdline_parse_token_string_t cmd_vm_name =
2763842bf24SAlan Carew 	TOKEN_STRING_INITIALIZER(struct cmd_vm_op_result,
2773842bf24SAlan Carew 			vm_name, NULL);
2783842bf24SAlan Carew 
2793842bf24SAlan Carew cmdline_parse_inst_t cmd_vm_op_set = {
2803842bf24SAlan Carew 	.f = cmd_vm_op_parsed,
2813842bf24SAlan Carew 	.data = NULL,
2823842bf24SAlan Carew 	.help_str = "add_vm|rm_vm <name>, add a VM for "
2833842bf24SAlan Carew 			"subsequent operations with the CLI or remove a previously added "
2843842bf24SAlan Carew 			"VM from the VM Power Manager",
2853842bf24SAlan Carew 	.tokens = {
2863842bf24SAlan Carew 		(void *)&cmd_vm_op,
2873842bf24SAlan Carew 		(void *)&cmd_vm_name,
2883842bf24SAlan Carew 	NULL,
2893842bf24SAlan Carew 	},
2903842bf24SAlan Carew };
2913842bf24SAlan Carew 
2923842bf24SAlan Carew /* *** VM channel operations *** */
2933842bf24SAlan Carew struct cmd_channels_op_result {
2943842bf24SAlan Carew 	cmdline_fixed_string_t op;
2953842bf24SAlan Carew 	cmdline_fixed_string_t vm_name;
2963842bf24SAlan Carew 	cmdline_fixed_string_t channel_list;
2973842bf24SAlan Carew };
2983842bf24SAlan Carew static void
2993842bf24SAlan Carew cmd_channels_op_parsed(void *parsed_result, struct cmdline *cl,
3003842bf24SAlan Carew 			__attribute__((unused)) void *data)
3013842bf24SAlan Carew {
3023842bf24SAlan Carew 	unsigned num_channels = 0, channel_num, i;
3033842bf24SAlan Carew 	int channels_added;
3043842bf24SAlan Carew 	unsigned channel_list[CHANNEL_CMDS_MAX_VM_CHANNELS];
3053842bf24SAlan Carew 	char *token, *remaining, *tail_ptr;
3063842bf24SAlan Carew 	struct cmd_channels_op_result *res = parsed_result;
3073842bf24SAlan Carew 
3083842bf24SAlan Carew 	if (!strcmp(res->channel_list, "all")) {
3093842bf24SAlan Carew 		channels_added = add_all_channels(res->vm_name);
3103842bf24SAlan Carew 		cmdline_printf(cl, "Added %d channels for VM '%s'\n",
3113842bf24SAlan Carew 				channels_added, res->vm_name);
3123842bf24SAlan Carew 		return;
3133842bf24SAlan Carew 	}
3143842bf24SAlan Carew 
3153842bf24SAlan Carew 	remaining = res->channel_list;
3163842bf24SAlan Carew 	while (1) {
3173842bf24SAlan Carew 		if (remaining == NULL || remaining[0] == '\0')
3183842bf24SAlan Carew 			break;
3193842bf24SAlan Carew 
3203842bf24SAlan Carew 		token = strsep(&remaining, ",");
3213842bf24SAlan Carew 		if (token == NULL)
3223842bf24SAlan Carew 			break;
3233842bf24SAlan Carew 		errno = 0;
3243842bf24SAlan Carew 		channel_num = (unsigned)strtol(token, &tail_ptr, 10);
3255b628fe1SBruce Richardson 		if ((errno != 0) || tail_ptr == NULL || (*tail_ptr != '\0'))
3263842bf24SAlan Carew 			break;
3273842bf24SAlan Carew 
3283842bf24SAlan Carew 		if (channel_num == CHANNEL_CMDS_MAX_VM_CHANNELS) {
3293842bf24SAlan Carew 			cmdline_printf(cl, "Channel number '%u' exceeds the maximum number "
3303842bf24SAlan Carew 					"of allowable channels(%u) for VM '%s'\n", channel_num,
3313842bf24SAlan Carew 					CHANNEL_CMDS_MAX_VM_CHANNELS, res->vm_name);
3323842bf24SAlan Carew 			return;
3333842bf24SAlan Carew 		}
3343842bf24SAlan Carew 		channel_list[num_channels++] = channel_num;
3353842bf24SAlan Carew 	}
3363842bf24SAlan Carew 	for (i = 0; i < num_channels; i++)
3373842bf24SAlan Carew 		cmdline_printf(cl, "[%u]: Adding channel %u\n", i, channel_list[i]);
3383842bf24SAlan Carew 
3393842bf24SAlan Carew 	channels_added = add_channels(res->vm_name, channel_list,
3403842bf24SAlan Carew 			num_channels);
3413842bf24SAlan Carew 	cmdline_printf(cl, "Enabled %d channels for '%s'\n", channels_added,
3423842bf24SAlan Carew 			res->vm_name);
3433842bf24SAlan Carew }
3443842bf24SAlan Carew 
3453842bf24SAlan Carew cmdline_parse_token_string_t cmd_channels_op =
3463842bf24SAlan Carew 	TOKEN_STRING_INITIALIZER(struct cmd_channels_op_result,
3473842bf24SAlan Carew 				op, "add_channels");
3483842bf24SAlan Carew cmdline_parse_token_string_t cmd_channels_vm_name =
3493842bf24SAlan Carew 	TOKEN_STRING_INITIALIZER(struct cmd_channels_op_result,
3503842bf24SAlan Carew 			vm_name, NULL);
3513842bf24SAlan Carew cmdline_parse_token_string_t cmd_channels_list =
3523842bf24SAlan Carew 	TOKEN_STRING_INITIALIZER(struct cmd_channels_op_result,
3533842bf24SAlan Carew 			channel_list, NULL);
3543842bf24SAlan Carew 
3553842bf24SAlan Carew cmdline_parse_inst_t cmd_channels_op_set = {
3563842bf24SAlan Carew 	.f = cmd_channels_op_parsed,
3573842bf24SAlan Carew 	.data = NULL,
3583842bf24SAlan Carew 	.help_str = "add_channels <vm_name> <list>|all, add "
3593842bf24SAlan Carew 			"communication channels for the specified VM, the "
3603842bf24SAlan Carew 			"virtio channels must be enabled in the VM "
3613842bf24SAlan Carew 			"configuration(qemu/libvirt) and the associated VM must be active. "
3623842bf24SAlan Carew 			"<list> is a comma-separated list of channel numbers to add, using "
3633842bf24SAlan Carew 			"the keyword 'all' will attempt to add all channels for the VM",
3643842bf24SAlan Carew 	.tokens = {
3653842bf24SAlan Carew 		(void *)&cmd_channels_op,
3663842bf24SAlan Carew 		(void *)&cmd_channels_vm_name,
3673842bf24SAlan Carew 		(void *)&cmd_channels_list,
3683842bf24SAlan Carew 		NULL,
3693842bf24SAlan Carew 	},
3703842bf24SAlan Carew };
3713842bf24SAlan Carew 
3723842bf24SAlan Carew struct cmd_channels_status_op_result {
3733842bf24SAlan Carew 	cmdline_fixed_string_t op;
3743842bf24SAlan Carew 	cmdline_fixed_string_t vm_name;
3753842bf24SAlan Carew 	cmdline_fixed_string_t channel_list;
3763842bf24SAlan Carew 	cmdline_fixed_string_t status;
3773842bf24SAlan Carew };
3783842bf24SAlan Carew 
3793842bf24SAlan Carew static void
3803842bf24SAlan Carew cmd_channels_status_op_parsed(void *parsed_result, struct cmdline *cl,
3813842bf24SAlan Carew 		       __attribute__((unused)) void *data)
3823842bf24SAlan Carew {
3833842bf24SAlan Carew 	unsigned num_channels = 0, channel_num;
3843842bf24SAlan Carew 	int changed;
3853842bf24SAlan Carew 	unsigned channel_list[CHANNEL_CMDS_MAX_VM_CHANNELS];
3863842bf24SAlan Carew 	char *token, *remaining, *tail_ptr;
3873842bf24SAlan Carew 	struct cmd_channels_status_op_result *res = parsed_result;
3883842bf24SAlan Carew 	enum channel_status status;
3893842bf24SAlan Carew 
3903842bf24SAlan Carew 	if (!strcmp(res->status, "enabled"))
3913842bf24SAlan Carew 		status = CHANNEL_MGR_CHANNEL_CONNECTED;
3923842bf24SAlan Carew 	else
3933842bf24SAlan Carew 		status = CHANNEL_MGR_CHANNEL_DISABLED;
3943842bf24SAlan Carew 
3953842bf24SAlan Carew 	if (!strcmp(res->channel_list, "all")) {
3963842bf24SAlan Carew 		changed = set_channel_status_all(res->vm_name, status);
3973842bf24SAlan Carew 		cmdline_printf(cl, "Updated status of %d channels "
3983842bf24SAlan Carew 				"for VM '%s'\n", changed, res->vm_name);
3993842bf24SAlan Carew 		return;
4003842bf24SAlan Carew 	}
4013842bf24SAlan Carew 	remaining = res->channel_list;
4023842bf24SAlan Carew 	while (1) {
4033842bf24SAlan Carew 		if (remaining == NULL || remaining[0] == '\0')
4043842bf24SAlan Carew 			break;
4053842bf24SAlan Carew 		token = strsep(&remaining, ",");
4063842bf24SAlan Carew 		if (token == NULL)
4073842bf24SAlan Carew 			break;
4083842bf24SAlan Carew 		errno = 0;
4093842bf24SAlan Carew 		channel_num = (unsigned)strtol(token, &tail_ptr, 10);
4105b628fe1SBruce Richardson 		if ((errno != 0) || tail_ptr == NULL || (*tail_ptr != '\0'))
4113842bf24SAlan Carew 			break;
4123842bf24SAlan Carew 
4133842bf24SAlan Carew 		if (channel_num == CHANNEL_CMDS_MAX_VM_CHANNELS) {
4143842bf24SAlan Carew 			cmdline_printf(cl, "%u exceeds the maximum number of allowable "
4153842bf24SAlan Carew 					"channels(%u) for VM '%s'\n", channel_num,
4163842bf24SAlan Carew 					CHANNEL_CMDS_MAX_VM_CHANNELS, res->vm_name);
4173842bf24SAlan Carew 			return;
4183842bf24SAlan Carew 		}
4193842bf24SAlan Carew 		channel_list[num_channels++] = channel_num;
4203842bf24SAlan Carew 	}
4213842bf24SAlan Carew 	changed = set_channel_status(res->vm_name, channel_list, num_channels,
4223842bf24SAlan Carew 			status);
4233842bf24SAlan Carew 	cmdline_printf(cl, "Updated status of %d channels "
4243842bf24SAlan Carew 					"for VM '%s'\n", changed, res->vm_name);
4253842bf24SAlan Carew }
4263842bf24SAlan Carew 
4273842bf24SAlan Carew cmdline_parse_token_string_t cmd_channels_status_op =
4283842bf24SAlan Carew 	TOKEN_STRING_INITIALIZER(struct cmd_channels_status_op_result,
4293842bf24SAlan Carew 				op, "set_channel_status");
4303842bf24SAlan Carew cmdline_parse_token_string_t cmd_channels_status_vm_name =
4313842bf24SAlan Carew 	TOKEN_STRING_INITIALIZER(struct cmd_channels_status_op_result,
4323842bf24SAlan Carew 			vm_name, NULL);
4333842bf24SAlan Carew cmdline_parse_token_string_t cmd_channels_status_list =
4343842bf24SAlan Carew 	TOKEN_STRING_INITIALIZER(struct cmd_channels_status_op_result,
4353842bf24SAlan Carew 			channel_list, NULL);
4363842bf24SAlan Carew cmdline_parse_token_string_t cmd_channels_status =
4373842bf24SAlan Carew 	TOKEN_STRING_INITIALIZER(struct cmd_channels_status_op_result,
4383842bf24SAlan Carew 			status, "enabled#disabled");
4393842bf24SAlan Carew 
4403842bf24SAlan Carew cmdline_parse_inst_t cmd_channels_status_op_set = {
4413842bf24SAlan Carew 	.f = cmd_channels_status_op_parsed,
4423842bf24SAlan Carew 	.data = NULL,
4433842bf24SAlan Carew 	.help_str = "set_channel_status <vm_name> <list>|all enabled|disabled, "
4443842bf24SAlan Carew 			" enable or disable the communication channels in "
4453842bf24SAlan Carew 			"list(comma-separated) for the specified VM, alternatively "
4463842bf24SAlan Carew 			"list can be replaced with keyword 'all'. "
4473842bf24SAlan Carew 			"Disabled channels will still receive packets on the host, "
4483842bf24SAlan Carew 			"however the commands they specify will be ignored. "
4493842bf24SAlan Carew 			"Set status to 'enabled' to begin processing requests again.",
4503842bf24SAlan Carew 	.tokens = {
4513842bf24SAlan Carew 		(void *)&cmd_channels_status_op,
4523842bf24SAlan Carew 		(void *)&cmd_channels_status_vm_name,
4533842bf24SAlan Carew 		(void *)&cmd_channels_status_list,
4543842bf24SAlan Carew 		(void *)&cmd_channels_status,
4553842bf24SAlan Carew 		NULL,
4563842bf24SAlan Carew 	},
4573842bf24SAlan Carew };
4583842bf24SAlan Carew 
4593842bf24SAlan Carew /* *** CPU Frequency operations *** */
4603842bf24SAlan Carew struct cmd_show_cpu_freq_mask_result {
4613842bf24SAlan Carew 	cmdline_fixed_string_t show_cpu_freq_mask;
4623842bf24SAlan Carew 	uint64_t core_mask;
4633842bf24SAlan Carew };
4643842bf24SAlan Carew 
4653842bf24SAlan Carew static void
4663842bf24SAlan Carew cmd_show_cpu_freq_mask_parsed(void *parsed_result, struct cmdline *cl,
4673842bf24SAlan Carew 		       __attribute__((unused)) void *data)
4683842bf24SAlan Carew {
4693842bf24SAlan Carew 	struct cmd_show_cpu_freq_mask_result *res = parsed_result;
4703842bf24SAlan Carew 	unsigned i;
4713842bf24SAlan Carew 	uint64_t mask = res->core_mask;
4723842bf24SAlan Carew 	uint32_t freq;
4733842bf24SAlan Carew 
4743842bf24SAlan Carew 	for (i = 0; mask; mask &= ~(1ULL << i++)) {
4753842bf24SAlan Carew 		if ((mask >> i) & 1) {
4763842bf24SAlan Carew 			freq = power_manager_get_current_frequency(i);
4773842bf24SAlan Carew 			if (freq > 0)
4783842bf24SAlan Carew 				cmdline_printf(cl, "Core %u: %"PRId32"\n", i, freq);
4793842bf24SAlan Carew 		}
4803842bf24SAlan Carew 	}
4813842bf24SAlan Carew }
4823842bf24SAlan Carew 
4833842bf24SAlan Carew cmdline_parse_token_string_t cmd_show_cpu_freq_mask =
4843842bf24SAlan Carew 	TOKEN_STRING_INITIALIZER(struct cmd_show_cpu_freq_mask_result,
4853842bf24SAlan Carew 			show_cpu_freq_mask, "show_cpu_freq_mask");
4863842bf24SAlan Carew cmdline_parse_token_num_t cmd_show_cpu_freq_mask_core_mask =
4873842bf24SAlan Carew 	TOKEN_NUM_INITIALIZER(struct cmd_show_cpu_freq_mask_result,
4883842bf24SAlan Carew 			core_mask, UINT64);
4893842bf24SAlan Carew 
4903842bf24SAlan Carew cmdline_parse_inst_t cmd_show_cpu_freq_mask_set = {
4913842bf24SAlan Carew 	.f = cmd_show_cpu_freq_mask_parsed,
4923842bf24SAlan Carew 	.data = NULL,
4933842bf24SAlan Carew 	.help_str = "show_cpu_freq_mask <mask>, Get the current frequency for each "
4943842bf24SAlan Carew 			"core specified in the mask",
4953842bf24SAlan Carew 	.tokens = {
4963842bf24SAlan Carew 		(void *)&cmd_show_cpu_freq_mask,
4973842bf24SAlan Carew 		(void *)&cmd_show_cpu_freq_mask_core_mask,
4983842bf24SAlan Carew 		NULL,
4993842bf24SAlan Carew 	},
5003842bf24SAlan Carew };
5013842bf24SAlan Carew 
5023842bf24SAlan Carew struct cmd_set_cpu_freq_mask_result {
5033842bf24SAlan Carew 	cmdline_fixed_string_t set_cpu_freq_mask;
5043842bf24SAlan Carew 	uint64_t core_mask;
5053842bf24SAlan Carew 	cmdline_fixed_string_t cmd;
5063842bf24SAlan Carew };
5073842bf24SAlan Carew 
5083842bf24SAlan Carew static void
5093842bf24SAlan Carew cmd_set_cpu_freq_mask_parsed(void *parsed_result, struct cmdline *cl,
5103842bf24SAlan Carew 			__attribute__((unused)) void *data)
5113842bf24SAlan Carew {
5123842bf24SAlan Carew 	struct cmd_set_cpu_freq_mask_result *res = parsed_result;
5133842bf24SAlan Carew 	int ret = -1;
5143842bf24SAlan Carew 
5153842bf24SAlan Carew 	if (!strcmp(res->cmd , "up"))
5163842bf24SAlan Carew 		ret = power_manager_scale_mask_up(res->core_mask);
5173842bf24SAlan Carew 	else if (!strcmp(res->cmd , "down"))
5183842bf24SAlan Carew 		ret = power_manager_scale_mask_down(res->core_mask);
5193842bf24SAlan Carew 	else if (!strcmp(res->cmd , "min"))
5203842bf24SAlan Carew 		ret = power_manager_scale_mask_min(res->core_mask);
5213842bf24SAlan Carew 	else if (!strcmp(res->cmd , "max"))
5223842bf24SAlan Carew 		ret = power_manager_scale_mask_max(res->core_mask);
523*567997b9SDavid Hunt 	else if (!strcmp(res->cmd, "enable_turbo"))
524*567997b9SDavid Hunt 		ret = power_manager_enable_turbo_mask(res->core_mask);
525*567997b9SDavid Hunt 	else if (!strcmp(res->cmd, "disable_turbo"))
526*567997b9SDavid Hunt 		ret = power_manager_disable_turbo_mask(res->core_mask);
5273842bf24SAlan Carew 	if (ret < 0) {
5283842bf24SAlan Carew 		cmdline_printf(cl, "Error scaling core_mask(0x%"PRIx64") '%s' , not "
5293842bf24SAlan Carew 				"all cores specified have been scaled\n",
5303842bf24SAlan Carew 				res->core_mask, res->cmd);
5313842bf24SAlan Carew 	};
5323842bf24SAlan Carew }
5333842bf24SAlan Carew 
5343842bf24SAlan Carew cmdline_parse_token_string_t cmd_set_cpu_freq_mask =
5353842bf24SAlan Carew 	TOKEN_STRING_INITIALIZER(struct cmd_set_cpu_freq_mask_result,
5363842bf24SAlan Carew 			set_cpu_freq_mask, "set_cpu_freq_mask");
5373842bf24SAlan Carew cmdline_parse_token_num_t cmd_set_cpu_freq_mask_core_mask =
5383842bf24SAlan Carew 	TOKEN_NUM_INITIALIZER(struct cmd_set_cpu_freq_mask_result,
5393842bf24SAlan Carew 			core_mask, UINT64);
5403842bf24SAlan Carew cmdline_parse_token_string_t cmd_set_cpu_freq_mask_result =
5413842bf24SAlan Carew 	TOKEN_STRING_INITIALIZER(struct cmd_set_cpu_freq_mask_result,
542*567997b9SDavid Hunt 			cmd, "up#down#min#max#enable_turbo#disable_turbo");
5433842bf24SAlan Carew 
5443842bf24SAlan Carew cmdline_parse_inst_t cmd_set_cpu_freq_mask_set = {
5453842bf24SAlan Carew 	.f = cmd_set_cpu_freq_mask_parsed,
5463842bf24SAlan Carew 	.data = NULL,
547*567997b9SDavid Hunt 	.help_str = "set_cpu_freq <core_mask> <up|down|min|max|enable_turbo|disable_turbo>, adjust the current "
548*567997b9SDavid Hunt 			"frequency for the cores specified in <core_mask>",
5493842bf24SAlan Carew 	.tokens = {
5503842bf24SAlan Carew 		(void *)&cmd_set_cpu_freq_mask,
5513842bf24SAlan Carew 		(void *)&cmd_set_cpu_freq_mask_core_mask,
5523842bf24SAlan Carew 		(void *)&cmd_set_cpu_freq_mask_result,
5533842bf24SAlan Carew 		NULL,
5543842bf24SAlan Carew 	},
5553842bf24SAlan Carew };
5563842bf24SAlan Carew 
5573842bf24SAlan Carew 
5583842bf24SAlan Carew 
5593842bf24SAlan Carew struct cmd_show_cpu_freq_result {
5603842bf24SAlan Carew 	cmdline_fixed_string_t show_cpu_freq;
5613842bf24SAlan Carew 	uint8_t core_num;
5623842bf24SAlan Carew };
5633842bf24SAlan Carew 
5643842bf24SAlan Carew static void
5653842bf24SAlan Carew cmd_show_cpu_freq_parsed(void *parsed_result, struct cmdline *cl,
5663842bf24SAlan Carew 		       __attribute__((unused)) void *data)
5673842bf24SAlan Carew {
5683842bf24SAlan Carew 	struct cmd_show_cpu_freq_result *res = parsed_result;
5693842bf24SAlan Carew 	uint32_t curr_freq = power_manager_get_current_frequency(res->core_num);
5703842bf24SAlan Carew 
5713842bf24SAlan Carew 	if (curr_freq == 0) {
5723842bf24SAlan Carew 		cmdline_printf(cl, "Unable to get frequency for core %u\n",
5733842bf24SAlan Carew 				res->core_num);
5743842bf24SAlan Carew 		return;
5753842bf24SAlan Carew 	}
5763842bf24SAlan Carew 	cmdline_printf(cl, "Core %u frequency: %"PRId32"\n", res->core_num,
5773842bf24SAlan Carew 			curr_freq);
5783842bf24SAlan Carew }
5793842bf24SAlan Carew 
5803842bf24SAlan Carew cmdline_parse_token_string_t cmd_show_cpu_freq =
5813842bf24SAlan Carew 	TOKEN_STRING_INITIALIZER(struct cmd_show_cpu_freq_result,
5823842bf24SAlan Carew 			show_cpu_freq, "show_cpu_freq");
5833842bf24SAlan Carew 
5843842bf24SAlan Carew cmdline_parse_token_num_t cmd_show_cpu_freq_core_num =
5853842bf24SAlan Carew 	TOKEN_NUM_INITIALIZER(struct cmd_show_cpu_freq_result,
5863842bf24SAlan Carew 			core_num, UINT8);
5873842bf24SAlan Carew 
5883842bf24SAlan Carew cmdline_parse_inst_t cmd_show_cpu_freq_set = {
5893842bf24SAlan Carew 	.f = cmd_show_cpu_freq_parsed,
5903842bf24SAlan Carew 	.data = NULL,
5913842bf24SAlan Carew 	.help_str = "Get the current frequency for the specified core",
5923842bf24SAlan Carew 	.tokens = {
5933842bf24SAlan Carew 		(void *)&cmd_show_cpu_freq,
5943842bf24SAlan Carew 		(void *)&cmd_show_cpu_freq_core_num,
5953842bf24SAlan Carew 		NULL,
5963842bf24SAlan Carew 	},
5973842bf24SAlan Carew };
5983842bf24SAlan Carew 
5993842bf24SAlan Carew struct cmd_set_cpu_freq_result {
6003842bf24SAlan Carew 	cmdline_fixed_string_t set_cpu_freq;
6013842bf24SAlan Carew 	uint8_t core_num;
6023842bf24SAlan Carew 	cmdline_fixed_string_t cmd;
6033842bf24SAlan Carew };
6043842bf24SAlan Carew 
6053842bf24SAlan Carew static void
6063842bf24SAlan Carew cmd_set_cpu_freq_parsed(void *parsed_result, struct cmdline *cl,
6073842bf24SAlan Carew 		       __attribute__((unused)) void *data)
6083842bf24SAlan Carew {
6093842bf24SAlan Carew 	int ret = -1;
6103842bf24SAlan Carew 	struct cmd_set_cpu_freq_result *res = parsed_result;
6113842bf24SAlan Carew 
6123842bf24SAlan Carew 	if (!strcmp(res->cmd , "up"))
6133842bf24SAlan Carew 		ret = power_manager_scale_core_up(res->core_num);
6143842bf24SAlan Carew 	else if (!strcmp(res->cmd , "down"))
6153842bf24SAlan Carew 		ret = power_manager_scale_core_down(res->core_num);
6163842bf24SAlan Carew 	else if (!strcmp(res->cmd , "min"))
6173842bf24SAlan Carew 		ret = power_manager_scale_core_min(res->core_num);
6183842bf24SAlan Carew 	else if (!strcmp(res->cmd , "max"))
6193842bf24SAlan Carew 		ret = power_manager_scale_core_max(res->core_num);
620*567997b9SDavid Hunt 	else if (!strcmp(res->cmd, "enable_turbo"))
621*567997b9SDavid Hunt 		ret = power_manager_enable_turbo_core(res->core_num);
622*567997b9SDavid Hunt 	else if (!strcmp(res->cmd, "disable_turbo"))
623*567997b9SDavid Hunt 		ret = power_manager_disable_turbo_core(res->core_num);
6243842bf24SAlan Carew 	if (ret < 0) {
6253842bf24SAlan Carew 		cmdline_printf(cl, "Error scaling core(%u) '%s'\n", res->core_num,
6263842bf24SAlan Carew 				res->cmd);
6273842bf24SAlan Carew 	}
6283842bf24SAlan Carew }
6293842bf24SAlan Carew 
6303842bf24SAlan Carew cmdline_parse_token_string_t cmd_set_cpu_freq =
6313842bf24SAlan Carew 	TOKEN_STRING_INITIALIZER(struct cmd_set_cpu_freq_result,
6323842bf24SAlan Carew 			set_cpu_freq, "set_cpu_freq");
633b68bc0b8SOlivier Matz cmdline_parse_token_num_t cmd_set_cpu_freq_core_num =
6343842bf24SAlan Carew 	TOKEN_NUM_INITIALIZER(struct cmd_set_cpu_freq_result,
6353842bf24SAlan Carew 			core_num, UINT8);
6363842bf24SAlan Carew cmdline_parse_token_string_t cmd_set_cpu_freq_cmd_cmd =
6373842bf24SAlan Carew 	TOKEN_STRING_INITIALIZER(struct cmd_set_cpu_freq_result,
638*567997b9SDavid Hunt 			cmd, "up#down#min#max#enable_turbo#disable_turbo");
6393842bf24SAlan Carew 
6403842bf24SAlan Carew cmdline_parse_inst_t cmd_set_cpu_freq_set = {
6413842bf24SAlan Carew 	.f = cmd_set_cpu_freq_parsed,
6423842bf24SAlan Carew 	.data = NULL,
643*567997b9SDavid Hunt 	.help_str = "set_cpu_freq <core_num> <up|down|min|max|enable_turbo|disable_turbo>, adjust the current "
644*567997b9SDavid Hunt 			"frequency for the specified core",
6453842bf24SAlan Carew 	.tokens = {
6463842bf24SAlan Carew 		(void *)&cmd_set_cpu_freq,
6473842bf24SAlan Carew 		(void *)&cmd_set_cpu_freq_core_num,
6483842bf24SAlan Carew 		(void *)&cmd_set_cpu_freq_cmd_cmd,
6493842bf24SAlan Carew 		NULL,
6503842bf24SAlan Carew 	},
6513842bf24SAlan Carew };
6523842bf24SAlan Carew 
6533842bf24SAlan Carew cmdline_parse_ctx_t main_ctx[] = {
6543842bf24SAlan Carew 		(cmdline_parse_inst_t *)&cmd_quit,
6553842bf24SAlan Carew 		(cmdline_parse_inst_t *)&cmd_vm_op_set,
6563842bf24SAlan Carew 		(cmdline_parse_inst_t *)&cmd_channels_op_set,
6573842bf24SAlan Carew 		(cmdline_parse_inst_t *)&cmd_channels_status_op_set,
6583842bf24SAlan Carew 		(cmdline_parse_inst_t *)&cmd_show_vm_set,
6593842bf24SAlan Carew 		(cmdline_parse_inst_t *)&cmd_show_cpu_freq_mask_set,
6603842bf24SAlan Carew 		(cmdline_parse_inst_t *)&cmd_set_cpu_freq_mask_set,
6613842bf24SAlan Carew 		(cmdline_parse_inst_t *)&cmd_show_cpu_freq_set,
6623842bf24SAlan Carew 		(cmdline_parse_inst_t *)&cmd_set_cpu_freq_set,
6633842bf24SAlan Carew 		(cmdline_parse_inst_t *)&cmd_set_pcpu_mask_set,
6643842bf24SAlan Carew 		(cmdline_parse_inst_t *)&cmd_set_pcpu_set,
6653842bf24SAlan Carew 		NULL,
6663842bf24SAlan Carew };
6673842bf24SAlan Carew 
6683842bf24SAlan Carew void
6693842bf24SAlan Carew run_cli(__attribute__((unused)) void *arg)
6703842bf24SAlan Carew {
6713842bf24SAlan Carew 	struct cmdline *cl;
6723842bf24SAlan Carew 
6733842bf24SAlan Carew 	cl = cmdline_stdin_new(main_ctx, "vmpower> ");
6743842bf24SAlan Carew 	if (cl == NULL)
6753842bf24SAlan Carew 		return;
6763842bf24SAlan Carew 
6773842bf24SAlan Carew 	cmdline_interact(cl);
6783842bf24SAlan Carew 	cmdline_stdin_exit(cl);
6793842bf24SAlan Carew }
680