From b44856778470d9b30ab4721700807fe924f219c7 Mon Sep 17 00:00:00 2001 From: Xiangyang Wu Date: Thu, 20 Jan 2022 09:15:32 +0800 Subject: [PATCH] DM: add command handler for command monitor The command handler is to implement handlers for each command, currently, two handler is implemented for command monitor: user_vm_destroy_handler: the handler is for user VM destroy command, which shuts down to standard post-launched user VM forcefully. user_vm_blkrescan_handler: the handler is for user VM blkrescan command, which rescan virtio-blk device to revalidate and update the backend file for user VM. v1--v2: Update log message format. Generate JSON format ack message using libcjson lib APIs. v2-->v3: Update ACK message to {"ack": 0} or {"ack": -1} Tracked-On: #5921 Signed-off-by: Xiangyang Wu Acked-by: Wang, Yu1 --- devicemodel/Makefile | 1 + .../core/cmd_monitor/command_handler.c | 124 ++++++++++++++++++ .../core/cmd_monitor/command_handler.h | 12 ++ 3 files changed, 137 insertions(+) create mode 100644 devicemodel/core/cmd_monitor/command_handler.c create mode 100644 devicemodel/core/cmd_monitor/command_handler.h diff --git a/devicemodel/Makefile b/devicemodel/Makefile index e0b59958e..bc1a68099 100644 --- a/devicemodel/Makefile +++ b/devicemodel/Makefile @@ -81,6 +81,7 @@ LIBS += -lpciaccess LIBS += -luuid LIBS += -lusb-1.0 LIBS += -lacrn-mngr +LIBS += -lcjson # lib SRCS += lib/dm_string.c diff --git a/devicemodel/core/cmd_monitor/command_handler.c b/devicemodel/core/cmd_monitor/command_handler.c new file mode 100644 index 000000000..01960e7f4 --- /dev/null +++ b/devicemodel/core/cmd_monitor/command_handler.c @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2022 Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "command.h" +#include "socket.h" +#include "command_handler.h" +#include "dm.h" +#include "pm.h" +#include "vmmapi.h" +#include "log.h" +#include "monitor.h" + +#define SUCCEEDED 0 +#define FAILED -1 + +static char *generate_ack_message(int ret_val) +{ + char *ack_msg; + cJSON *val; + cJSON *ret_obj = cJSON_CreateObject(); + + if (ret_obj == NULL) + return NULL; + val = cJSON_CreateNumber(ret_val); + if (val == NULL) + return NULL; + cJSON_AddItemToObject(ret_obj, "ack", val); + ack_msg = cJSON_Print(ret_obj); + if (ack_msg == NULL) + fprintf(stderr, "Failed to generate ACK message.\n"); + cJSON_Delete(ret_obj); + return ack_msg; +} +static int send_socket_ack(struct socket_dev *sock, int fd, bool normal) +{ + int ret = 0, val; + char *ack_message; + struct socket_client *client = NULL; + + client = find_socket_client(sock, fd); + if (client == NULL) + return -1; + val = normal ? SUCCEEDED : FAILED; + ack_message = generate_ack_message(val); + + if (ack_message != NULL) { + memset(client->buf, 0, CLIENT_BUF_LEN); + memcpy(client->buf, ack_message, strlen(ack_message)); + client->len = strlen(ack_message); + ret = write_socket_char(client); + free(ack_message); + } else { + pr_err("Failed to generate ACK message.\n"); + ret = -1; + } + return ret; +} + +int user_vm_destroy_handler(void *arg, void *command_para) +{ + int ret; + struct command_parameters *cmd_para = (struct command_parameters *)command_para; + struct handler_args *hdl_arg = (struct handler_args *)arg; + struct socket_dev *sock = (struct socket_dev *)hdl_arg->channel_arg; + struct socket_client *client = NULL; + bool cmd_completed = false; + + client = find_socket_client(sock, cmd_para->fd); + if (client == NULL) + return -1; + + if (!is_rtvm) { + pr_info("%s: setting VM state to %s.\n", __func__, vm_state_to_str(VM_SUSPEND_POWEROFF)); + vm_set_suspend_mode(VM_SUSPEND_POWEROFF); + cmd_completed = true; + } else { + pr_err("Failed to destroy post-launched RTVM.\n"); + ret = -1; + } + + ret = send_socket_ack(sock, cmd_para->fd, cmd_completed); + if (ret < 0) { + pr_err("Failed to send ACK message by socket.\n"); + } + return ret; +} + +int user_vm_blkrescan_handler(void *arg, void *command_para) +{ + int ret = 0; + struct command_parameters *cmd_para = (struct command_parameters *)command_para; + struct handler_args *hdl_arg = (struct handler_args *)arg; + struct socket_dev *sock = (struct socket_dev *)hdl_arg->channel_arg; + struct socket_client *client = NULL; + bool cmd_completed = false; + + client = find_socket_client(sock, cmd_para->fd); + if (client == NULL) + return -1; + + ret = vm_monitor_blkrescan(hdl_arg->ctx_arg, cmd_para->option); + if (ret >= 0) { + cmd_completed = true; + } else { + pr_err("Failed to rescan virtio-blk device.\n"); + } + + ret = send_socket_ack(sock, cmd_para->fd, cmd_completed); + if (ret < 0) { + pr_err("Failed to send ACK by socket.\n"); + } + return ret; +} diff --git a/devicemodel/core/cmd_monitor/command_handler.h b/devicemodel/core/cmd_monitor/command_handler.h new file mode 100644 index 000000000..1ed713310 --- /dev/null +++ b/devicemodel/core/cmd_monitor/command_handler.h @@ -0,0 +1,12 @@ +/* + * Copyright (C) 2022 Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef _COMMAND_HANDLER_H_ +#define _COMMAND_HANDLER_H_ + +extern struct socket_dev *sock_server; + +int user_vm_destroy_handler(void *arg, void *command_para); +int user_vm_blkrescan_handler(void *arg, void *command_para); +#endif