diff --git a/misc/services/life_mngr/config.c b/misc/services/life_mngr/config.c new file mode 100644 index 000000000..d44231566 --- /dev/null +++ b/misc/services/life_mngr/config.c @@ -0,0 +1,96 @@ +/* + * Copyright (C)2021 Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "log.h" +#include "config.h" + +struct life_mngr_config life_conf; + +int check_dir(const char *path, int flags) +{ + struct stat st; + + if (stat(path, &st)) { + if (flags) { + if (mkdir(path, 0666)) { + LOG_PRINTF("Failed to create folder (%s)\n", path); + return -1; + } + return 0; + } else { + LOG_PRINTF("%s doesn't exist!\n", path); + return -1; + } + } + + if (S_ISDIR(st.st_mode)) + return 0; + + fprintf(stderr, "%s exists, and is not a directory!\n", path); + return -1; +} +bool load_config(char *conf_path) +{ + int pos; + char buf[MAX_FILE_LINE_LEN]; + char *key_str, *value_str; + FILE *fd; + int ret; + + ret = check_dir(LIFE_MNGR_CONFIG_FOLDER, CHK_CREAT); + if (ret) { + LOG_PRINTF("%s %d\r\n", __func__, __LINE__); + return false; + } + fd = fopen(conf_path, "r"); + if (fd == NULL) { + LOG_PRINTF("Failed to open config file: %s", conf_path); + return false; + } + while (fgets(buf, MAX_FILE_LINE_LEN, fd) != NULL) { + pos = 0; + while (buf[pos] == ' ') + pos++; + + key_str = &buf[pos]; + if (key_str[0] == '#' || key_str[0] == '\n') + continue; + + (void) strtok_r(key_str, "=", &value_str); + if (strlen(value_str) == 0) { + LOG_PRINTF("Config file: config item (%s) is invalid\n", buf); + continue; + } + value_str[strlen(value_str) - 1] = '\0'; + LOG_PRINTF("Config file: key=%s, value=%s\n", key_str, value_str); + if (strncmp(VM_TYPE, (const char *)key_str, sizeof(VM_TYPE)) == 0) + memcpy(life_conf.vm_type, value_str, strlen(value_str)); + else if (strncmp(VM_NAME, (const char *)key_str, sizeof(VM_NAME)) == 0) + memcpy(life_conf.vm_name, value_str, strlen(value_str)); + else if (strncmp(DEV_NAME, (const char *)key_str, sizeof(DEV_NAME)) == 0) + memcpy(life_conf.dev_names, value_str, strlen(value_str)); + else if (strncmp(ALLOW_TRIGGER_S5, (const char *)key_str, + sizeof(ALLOW_TRIGGER_S5)) == 0) + memcpy(life_conf.allow_trigger_s5, value_str, strlen(value_str)); + else + LOG_PRINTF("Invalid item in the configuration file, key=%s, value=%s\n", + key_str, value_str); + } + if (strlen(life_conf.vm_name) == 0) { + LOG_WRITE("Invalid VM name in configuration file\n"); + return false; + } + return true; +} diff --git a/misc/services/life_mngr/config.h b/misc/services/life_mngr/config.h new file mode 100644 index 000000000..c5dc5271b --- /dev/null +++ b/misc/services/life_mngr/config.h @@ -0,0 +1,62 @@ +/* + * Copyright (C)2021 Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef _CONFIG_H_ +#define _CONFIG_H_ +/** + * @brief Number of seconds we're willing to retry to send shutdown request to a guest. + * If this is 0, then there is no retry (use with caution, as guests might miss shutdown + * command from service VM). The default value is 3. + */ +#define VM_SHUTDOWN_RETRY_TIMES 5 +/** + * @brief Number of seconds we're willing to wait for all guests to shutdown. If this is 0, + * then there is no time out (use with caution, as guests might not respond to a shutdown + * request). The default value is 300 seconds (5 minutes). + */ +#define SHUTDOWN_TIMEOUT 300 + +#define LIFE_MNGR_CONFIG_PATH "/etc/life_mngr/life_mngr.conf" +#define LIFE_MNGR_CONFIG_FOLDER "/etc/life_mngr" +#define MAX_FILE_LINE_LEN 120 +#define VM_TYPE "VM_TYPE" +#define VM_NAME "VM_NAME" +#define DEV_NAME "DEV_NAME" +#define ALLOW_TRIGGER_S5 "ALLOW_TRIGGER_S5" +#define MAX_CONFIG_VALUE_LEN 128 + +#define CHK_CREAT 1 /* create a directory, if it does not exist */ +#define CHK_ONLY 0 /* check if the directory exist only */ + +struct life_mngr_config { + char vm_type[MAX_CONFIG_VALUE_LEN]; + char vm_name[MAX_CONFIG_VALUE_LEN]; + char dev_names[MAX_CONFIG_VALUE_LEN]; + char allow_trigger_s5[MAX_CONFIG_VALUE_LEN]; +}; +extern struct life_mngr_config life_conf; + +/** + * @brief Get the name of the device which is allowed to trigger system shutdown + */ +static inline char *get_allow_s5_config(struct life_mngr_config *conf) +{ + return conf->allow_trigger_s5; +} +/** + * @brief Load configuration item from config file + * + * @param conf_path config file path + * @return true Load configuration items successfully + * @return false fail to load configuration items + */ +bool load_config(char *conf_path); +/** + * @brief Check folder exist or not, if not, create the folder + * + * @param path the folder path + * @param flags the folder attribute + */ +int check_dir(const char *path, int flags); +#endif diff --git a/misc/services/life_mngr/life_mngr.conf b/misc/services/life_mngr/life_mngr.conf new file mode 100644 index 000000000..d8fb040f7 --- /dev/null +++ b/misc/services/life_mngr/life_mngr.conf @@ -0,0 +1,26 @@ +# The VM type of a VM which lifecycle manager will run on +# -service_vm the lifecycle manager will be run on the service VM +# -user_vm the lifecycle manager will be run on the user VM +VM_TYPE=service_vm + +# The VM name of a VM which lifecycle manager will run on, the name should +# be unique in the whole system, this name will be embedded log message to +# help user to do system debugging. +VM_NAME=service_VM + +# The device type and device names of the devices which are used to +# communicate with other VMs in lifecycle manager. +# For user VM, the default value is tty:/dev/ttyS1; +# +# For service VM, the default setting rule of this field: /dev/ttyS8 is to +# communicate with VM1 (VM ID in hypervisor = 1), /dev/ttyS9 is for VM2 (VM ID is 2), +# /dev/ttyS10 is for VM3 (VM ID is 3) ... /dev/ttyS14 is for VM7 (VM ID is 7) +# note: need to double check related communication vuarts are valid in hypervisor scenario config +# file. +DEV_NAME=tty:/dev/ttyS8,/dev/ttyS9,/dev/ttyS10,/dev/ttyS11,/dev/ttyS12,/dev/ttyS13,/dev/ttyS14 + +# The device name of the device which is used to communicate with the VM, +# and this VM is allowed to trigger system shutdown through executing +# s5_trigger.sh. +# For user VM, this field is useless. +ALLOW_TRIGGER_S5=/dev/ttyS10