From 2ea2716cd9960b1c3d265d84f8ac2e73846f9214 Mon Sep 17 00:00:00 2001 From: fuyanX Date: Wed, 11 Sep 2019 23:44:14 +0800 Subject: [PATCH] Misc: lifemngr-daemon-on-UOS For cross-VM S5 notify via vUART, life_mngr service is running on UOS. It is listening on /dev/ttyS1 to get SOS's commands. The protocol is: SOS send "shutdown", UOS feedback "acked". When SOS triggle shutdown, SOS can 1) check VM's status until UOS stopped, 2) retry shutdown UOS normally with timeout. So, no matter life_mngr server is running, SOS's shutdown procedure will properly finish. Tracked-On: #3564 Signed-off-by: fuyanX Acked-by: Yan, Like --- misc/life_mngr/life_mngr.c | 113 +++++++++++++++++++++++++++++++ misc/life_mngr/life_mngr.service | 13 ++++ 2 files changed, 126 insertions(+) create mode 100644 misc/life_mngr/life_mngr.c create mode 100644 misc/life_mngr/life_mngr.service diff --git a/misc/life_mngr/life_mngr.c b/misc/life_mngr/life_mngr.c new file mode 100644 index 000000000..0a0e7153b --- /dev/null +++ b/misc/life_mngr/life_mngr.c @@ -0,0 +1,113 @@ +/* + * Copyright (C)2019 Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include + +#define SOS_REQ "shutdown" +#define UOS_ACK "acked" +#define BUFF_SIZE 16U +#define MSG_SIZE 8U +#define NODE_SIZE 3U + +enum nodetype { + NODE_UNKNOWN = 0, + NODE_UOS_SERVER, + NODE_SOS_CLIENT, +}; + +int set_serial_interface_attributes(int fd, int speed) +{ + struct termios tty; + + if (tcgetattr(fd, &tty) < 0) { + printf("Error from tcgetattr: %s\n", strerror(errno)); + return errno; + } + + cfsetospeed(&tty, (speed_t)speed); + cfsetispeed(&tty, (speed_t)speed); + + /* set input-mode */ + tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON); + + /* set output-mode */ + tty.c_oflag &= ~OPOST; + + /* set control-mode */ + tty.c_cflag |= (CLOCAL | CREAD); + tty.c_cflag &= ~CSIZE; + tty.c_cflag |= CS8; + tty.c_cflag &= ~PARENB; + tty.c_cflag &= ~CSTOPB; + tty.c_cflag &= ~CRTSCTS; + + /* set local-mode */ + tty.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); + + /* block until one char read, set next char's timeout */ + tty.c_cc[VMIN] = 1; + tty.c_cc[VTIME] = 1; + + if (tcsetattr(fd, TCSANOW, &tty) != 0) { + printf("Error from tcsetattr: %s\n", strerror(errno)); + return errno; + } + return 0; +} + +int main(int argc, char *argv[]) +{ + char *devname_uos = ""; + int fd_uos = 0; + unsigned char recvbuf[BUFF_SIZE]; + enum nodetype node = NODE_UNKNOWN; + + if (argc <= 2) { + printf("Too few options. Example: [./life_mngr uos /dev/ttyS1].\n"); + return -EINVAL; + } + + if (strncmp("uos", argv[1], NODE_SIZE) == 0) { + node = NODE_UOS_SERVER; + } else if (strncmp("sos", argv[1], NODE_SIZE) == 0) { + node = NODE_SOS_CLIENT; + } else { + printf("Invalid param. Example: [./life_mngr uos /dev/ttyS1].\n"); + return -EINVAL; + } + + if (node == NODE_UOS_SERVER) { + devname_uos = argv[2]; + fd_uos = open(devname_uos, O_RDWR | O_NOCTTY | O_SYNC); + if (fd_uos < 0) { + printf("Error opening %s: %s\n", devname_uos, strerror(errno)); + return errno; + } + set_serial_interface_attributes(fd_uos, B115200); + } + + /* UOS-server wait for shutdown from SOS */ + do { + if (node == NODE_UOS_SERVER) { + memset(recvbuf, 0, sizeof(recvbuf)); + read(fd_uos, recvbuf, sizeof(recvbuf)); + + if (strncmp(SOS_REQ, recvbuf, MSG_SIZE) == 0) { + write(fd_uos, UOS_ACK, sizeof(UOS_ACK)); + printf("SOS start shutdown\n"); + system("poweroff"); + break; + } + } + } while (1); + + return 0; +} diff --git a/misc/life_mngr/life_mngr.service b/misc/life_mngr/life_mngr.service new file mode 100644 index 000000000..c8c2dd3d8 --- /dev/null +++ b/misc/life_mngr/life_mngr.service @@ -0,0 +1,13 @@ +[Unit] +Description=ACRN lifemngr daemon +After=systemd-resolved.service + +[Service] +Type=simple +ExecStart=/usr/bin/life_mngr uos /dev/ttyS1 +StandardOutput=journal +StandardError=journal +Restart=yes + +[Install] +WantedBy=multi-user.target