Misc: life_mngr: system reboot support

Now reuse allow_trigger_s5 in life_mngr_config to allow WAAG to trigger
system reboot.

Tracked-On: #7215
Signed-off-by: Xiangyang Wu <xiangyang.wu@intel.com>
Signed-off-by: Fei Li <fei1.li@intel.com>
This commit is contained in:
Fei Li 2022-03-24 17:20:52 +08:00 committed by acrnsi-robot
parent 6ea861affc
commit 25d5f2452e
7 changed files with 118 additions and 6 deletions

View File

@ -36,6 +36,7 @@
GEN_CMD_OBJ(REQ_USER_VM_REBOOT, REQ_USER_VM_REBOOT_ID), \
GEN_CMD_OBJ(USER_VM_REBOOT, USER_VM_REBOOT_ID),\
GEN_CMD_OBJ(ACK_USER_VM_REBOOT, ACK_USER_VM_REBOOT_ID),\
GEN_CMD_OBJ(REQ_SYS_REBOOT, REQ_SYS_REBOOT_ID), \
struct command dm_command_list[CMD_END] = {CMD_OBJS};

View File

@ -19,6 +19,8 @@
#define USER_VM_SHUTDOWN "user_vm_shutdown"
#define REQ_USER_VM_REBOOT "req_user_vm_reboot"
#define USER_VM_REBOOT "user_vm_reboot"
#define REQ_SYS_REBOOT "req_sys_reboot"
#define ACK_REQ_SYS_REBOOT "ack_req_sys_reboot"
#define ACK_REQ_USER_VM_SHUTDOWN "ack_req_user_vm_shutdown"
#define ACK_USER_VM_SHUTDOWN "ack_user_vm_shutdown"
@ -49,6 +51,7 @@ enum command_id {
REQ_USER_VM_REBOOT_ID,
USER_VM_REBOOT_ID,
ACK_USER_VM_REBOOT_ID,
REQ_SYS_REBOOT_ID,
CMD_END,
};

View File

@ -26,10 +26,13 @@ bool get_system_shutdown_flag(void)
}
bool user_vm_reboot_flag;
bool get_user_vm_reboot_flag(void)
bool system_reboot_flag;
bool system_reboot_request_flag;
bool get_vm_reboot_flag(void)
{
return user_vm_reboot_flag;
return user_vm_reboot_flag | system_reboot_flag;
}
/**
* @brief check whether all acrn-dm instance have been exit or not
*
@ -65,6 +68,23 @@ static bool wait_post_vms_shutdown(void)
} while (check_time > 0);
return all_done;
}
static void start_system_reboot(void)
{
static bool platform_reboot;
if (is_uart_channel_connection_list_empty(channel) && (!platform_reboot)) {
platform_reboot = true;
LOG_WRITE("UART connection list is empty, will trigger system reboot\n");
close_socket(sock_server);
stop_listen_uart_channel_dev(channel);
if (wait_post_vms_shutdown()) {
LOG_WRITE("Service VM starts to reboot.\n");
system_reboot_flag = true;
} else {
LOG_WRITE("Some User VMs failed to power off, cancelled the platform reboot process.\n");
}
}
}
static void start_system_shutdown(void)
{
static bool platform_shutdown;
@ -78,7 +98,7 @@ static void start_system_shutdown(void)
LOG_WRITE("Service VM starts to power off.\n");
system_shutdown_flag = true;
} else {
LOG_WRITE("Some User VMs failed to power off, cancelled the platform shut down process.\n");
LOG_WRITE("Some User VMs failed to power off, cancelled the platform shutdown process.\n");
}
}
}
@ -207,6 +227,35 @@ int sync_cmd_handler(void *arg, int fd)
usleep(2 * WAIT_RECV);
return 0;
}
int req_reboot_handler(void *arg, int fd)
{
int ret;
struct channel_dev *c_dev = NULL;
struct uart_channel *c = (struct uart_channel *)arg;
c_dev = find_uart_channel_dev(c, fd);
if (c_dev == NULL)
return 0;
if (is_allowed_s5_channel_dev(&life_conf, c_dev)) {
LOG_PRINTF("The user VM (%s) is not allowed to trigger system reboot\n",
c_dev->name);
return 0;
}
LOG_PRINTF("Receive reboot request from user VM (%s)\n", c_dev->name);
ret = send_message_by_uart(c_dev->uart_device, ACK_REQ_SYS_REBOOT,
strlen(ACK_REQ_SYS_REBOOT));
if (ret < 0)
LOG_WRITE("Send acked message to user VM fail\n");
system_reboot_request_flag = true;
usleep(SECOND_TO_US);
LOG_PRINTF("Send acked shutdown request message to user VM (%s)\n", c_dev->name);
start_all_uart_channel_dev_resend(c, POWEROFF_CMD, VM_SHUTDOWN_RETRY_TIMES);
notify_all_connected_uart_channel_dev(c, POWEROFF_CMD);
usleep(2 * WAIT_RECV);
return ret;
}
/**
* @brief The handler of system shutdown request command of lifecycle manager in service VM
*
@ -261,7 +310,11 @@ int ack_poweroff_handler(void *arg, int fd)
stop_uart_channel_dev_resend(c_dev);
disconnect_uart_channel_dev(c_dev, c);
usleep(WAIT_USER_VM_POWEROFF);
start_system_shutdown();
if (system_reboot_request_flag) {
start_system_reboot();
} else {
start_system_shutdown();
}
return 0;
}
/**

View File

@ -16,7 +16,7 @@ bool get_system_shutdown_flag(void);
/**
* @brief Get the reboot flag
*/
bool get_user_vm_reboot_flag(void);
bool get_vm_reboot_flag(void);
/**
* @brief The handler of request system shutdown command on socket in service VM
*/
@ -50,6 +50,14 @@ int sync_cmd_handler(void *arg, int fd);
* @return indicate this command is handled successful or not
*/
int req_shutdown_handler(void *arg, int fd);
/**
* @brief The handler of system reboot request command of lifecycle manager in service VM
*
* @param arg uart channel device instance
* @param fd the file directory of the uart which receives message
* @return indicate this command is handled successful or not
*/
int req_reboot_handler(void *arg, int fd);
/**
* @brief The handler of acked poweroff command of lifecycle manager in service VM
*

View File

@ -20,6 +20,8 @@
#define ACK_USER_VM_SHUTDOWN "ack_user_vm_shutdown"
#define USER_VM_REBOOT "user_vm_reboot"
#define ACK_USER_VM_REBOOT "ack_user_vm_reboot"
#define REQ_SYS_REBOOT "req_sys_reboot"
#define ACK_REQ_SYS_REBOOT "ack_req_sys_reboot"
#define SYNC_FMT "sync:%s"
#define S5_REJECTED "system shutdown request is rejected"
@ -122,6 +124,10 @@ DWORD WINAPI open_socket_server(LPVOID lpParam)
handle_socket_request(sClient, REQ_SYS_SHUTDOWN);
break;
}
if (strncmp(revData, REQ_SYS_REBOOT, sizeof(REQ_SYS_REBOOT)) == 0) {
handle_socket_request(sClient, REQ_SYS_REBOOT);
break;
}
} while (1);
closesocket(sClient);
sock_exit:
@ -234,6 +240,9 @@ int main()
} else if (strncmp(recvbuf, ACK_REQ_SYS_SHUTDOWN, sizeof(ACK_REQ_SYS_SHUTDOWN)) == 0) {
stop_uart_resend();
printf("Received acked system shutdown request from service VM\n");
} else if (strncmp(recvbuf, ACK_REQ_SYS_REBOOT, sizeof(ACK_REQ_SYS_REBOOT)) == 0) {
stop_uart_resend();
printf("Received acked system reboot request from service VM\n");
} else if (strncmp(recvbuf, POWEROFF_CMD, sizeof(POWEROFF_CMD)) == 0) {
printf("Received system shutdown message from service VM\n");
send_message_by_uart(hCom2, ACK_POWEROFF, sizeof(ACK_POWEROFF));

View File

@ -117,6 +117,7 @@ int init_uart_channel_devs_and_shutdown_commands(bool service_vm, char *uart_dev
if (service_vm) {
register_command_handler(sync_cmd_handler, channel, SYNC_CMD);
register_command_handler(req_shutdown_handler, channel, REQ_SYS_SHUTDOWN);
register_command_handler(req_reboot_handler, channel, REQ_SYS_REBOOT);
register_command_handler(ack_poweroff_handler, channel, ACK_POWEROFF);
register_command_handler(ack_timeout_handler, channel, ACK_TIMEOUT);
register_command_handler(ack_user_vm_shutdown_cmd_handler, channel, ACK_USER_VM_SHUTDOWN);
@ -219,7 +220,7 @@ int main(int argc, char *argv[])
ret = system(POWEROFF);
} while (ret < 0);
}
if (get_user_vm_reboot_flag()) {
if (get_vm_reboot_flag()) {
do {
ret = system(REBOOT);
} while (ret < 0);

View File

@ -0,0 +1,37 @@
#!/usr/bin/env python3
#
# Copyright (C) 2022 Intel Corporation.
#
# SPDX-License-Identifier: BSD-3-Clause
#
import socket
import sys
if __name__ == "__main__":
HOST = '127.0.0.1'
PORT = 8193
SYS_REBOOT_REQ = 'req_sys_reboot'
MSG_LEN = 32
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print(["Socket Created"])
try:
s.connect((HOST,PORT))
print("[Connection established]")
except Exception:
print('[Connection error: ' + HOST + ":" + str(PORT)+']')
s.close()
try:
s.send(SYS_REBOOT_REQ.encode('utf-8'))
except Exception as _:
raise _
print(["System reboot request sent\n"])
try:
data_input = (s.recv(MSG_LEN).decode("UTF-8"))
except Exception:
pass
print("Waiting for ACK message...: ", data_input)
s.close()