diff --git a/Dockerfile b/Dockerfile index 5df22555c9317a09ca7e35096d951b3ec8232962..aac2062883956adacb43034f943deb875079e98b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -63,8 +63,11 @@ RUN yum clean all && yum swap -y fakesystemd systemd && \ gmock \ gmock-devel \ cppcheck \ + python3 \ + python3-pip \ python \ python-pip \ + device-mapper-devel \ libcurl-devel \ zlib-devel \ glibc-headers \ diff --git a/docs/build_guide.md b/docs/build_guide.md index 07fbe3c47679df3cfae3888a4337ee952bf38080..e569996894c375a3c6cf5949ee92e5e86457d56d 100644 --- a/docs/build_guide.md +++ b/docs/build_guide.md @@ -23,7 +23,9 @@ $ sudo make $ sudo make install ``` -## Via Docker container +## Trial iSulad Via Docker container + +You can try to use iSulad via Docker container. The following steps guide you how to create a Docker container which can run iSulad inside. #### Build image @@ -45,12 +47,12 @@ $ sudo mkdir -p /var/lib/isulad #### Build iSulad in container -Let's suppose that you built an image called `iSulad:dev`. +Let's suppose that you built an image called `isulad:dev`. Then from the iSulad source root directory you can run the following command: ```sh -$ sudo docker run -tid --name YOUR_CONTAINER_NAME -v /var/lib/isulad:/var/lib/isulad -v `pwd`:/src/isulad --privileged iSulad:dev +$ sudo docker run -tid --name YOUR_CONTAINER_NAME -v /var/lib/isulad:/var/lib/isulad -v `pwd`:/src/isulad --privileged isulad:dev ``` Let's suppose that you run an container named `iSulad_build`. Then you can use the following commands to build iSulad in your container `iSulad_build`: diff --git a/iSulad.spec b/iSulad.spec index a0865312489859702ca24d2a9918ca712c5386ea..d504ffe22e0d3a1549867740403f74edfedacf7d 100644 --- a/iSulad.spec +++ b/iSulad.spec @@ -1,5 +1,5 @@ %global _version 1.1.12 -%global _release 20200306.143730.gitb83d1ed8 +%global _release 20200311.212052.git8d13b09e %global is_systemd 1 %global debug_package %{nil} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0c1b1db8e41a22d6f3d74a3647944d2d1a34a150..7983cafcea3a47ffe07b6a1110a220e32edc83d6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -147,6 +147,7 @@ add_executable(isulad-shim ${ISULAD_SHIM_SRCS} ${CMAKE_BINARY_DIR}/json/shim_client_process_state.c ${CMAKE_BINARY_DIR}/json/json_common.c + ${CMAKE_BINARY_DIR}/json/logger_json_file.c ${commonjsonsrcs} ) target_include_directories(isulad-shim PUBLIC ${ISULAD_SHIM_INCS} ${SHARED_INCS}) diff --git a/src/cmd/isulad-shim/main.c b/src/cmd/isulad-shim/main.c index bda2305ee9bf3a84d4e4bbe7de63255742cbcfe6..7591832b99783f14ee342b32d412a34527891b04 100644 --- a/src/cmd/isulad-shim/main.c +++ b/src/cmd/isulad-shim/main.c @@ -153,10 +153,5 @@ int main(int argc, char **argv) released_timeout_exit(); - ret = process_signal_handle_routine(p); - if (ret != SHIM_OK) { - exit(EXIT_FAILURE); - } - - exit(EXIT_SUCCESS); + return process_signal_handle_routine(p); } diff --git a/src/cmd/isulad-shim/process.c b/src/cmd/isulad-shim/process.c index 0861c5aede9328ab7ce003ef1280055fa0190b3b..e0498f87756fe6af290bac9dbc10ee07e6c1f94f 100644 --- a/src/cmd/isulad-shim/process.c +++ b/src/cmd/isulad-shim/process.c @@ -35,9 +35,11 @@ #include "common.h" #include "process.h" +#include "terminal.h" #define MAX_EVENTS 100 #define DEFAULT_IO_COPY_BUF (16*1024) +#define DEFAULT_LOG_FILE_SIZE (4*1024) extern int g_log_fd; @@ -143,6 +145,10 @@ static int add_io_dispatch(int epfd, io_thread_t *io_thd, int from, int to) return SHIM_ERR; } fn->fd = to; + fn->is_log = false; + if (io_thd->terminal != NULL && to == io_thd->terminal->fd) { + fn->is_log = true; + } fn->next = NULL; pthread_mutex_lock(&(ioc->mutex)); @@ -254,11 +260,15 @@ static void* task_io_copy(void *data) } else { fd_node_t *fn = ioc->fd_to; for (; fn != NULL; fn = fn->next) { - int w_count; - w_count = write_nointr(fn->fd, buf, r_count); - if (w_count < 0) { - // remove the write fd - remove_io_dispatch(io_thd, -1, fn->fd); + if (fn->is_log) { + shim_write_container_log_file(io_thd->terminal, ioc->id == stdid_out ? "stdout" : "stderr", buf, r_count); + } else { + int w_count = 0; + w_count = write_nointr(fn->fd, buf, r_count); + if (w_count < 0) { + // remove the write fd + remove_io_dispatch(io_thd, -1, fn->fd); + } } } } @@ -318,6 +328,8 @@ static int process_io_start(process_t *p, int std_id) io_thd->epfd = p->io_loop_fd; io_thd->ioc = ioc; io_thd->shutdown = false; + io_thd->terminal = std_id != stdid_in ? p->terminal : NULL; + p->io_threads[std_id] = io_thd; ret = pthread_create(&(io_thd->tid), NULL, task_io_copy, io_thd); @@ -398,6 +410,9 @@ static int connect_to_isulad(process_t *p, int std_id, const char *isulad_stdio, } if (*fd_from != -1) { + if (std_id != stdid_in && p->io_threads[std_id]->terminal != NULL) { + (void)add_io_dispatch(p->io_loop_fd, p->io_threads[std_id], *fd_from, p->terminal->fd); + } return add_io_dispatch(p->io_loop_fd, p->io_threads[std_id], *fd_from, *fd_to); } @@ -677,11 +692,61 @@ static void adapt_for_isulad_stdin(process_t *p) } } +static int terminal_init(log_terminal **terminal, shim_client_process_state *p_state) +{ + log_terminal *log_term = NULL; + + log_term = calloc(1, sizeof(log_terminal)); + if (log_term == NULL) { + write_message(g_log_fd, ERR_MSG, "Failed to calloc log_terminal"); + goto clean_out; + } + + if (pthread_rwlock_init(&log_term->log_terminal_rwlock, NULL) != 0) { + write_message(g_log_fd, ERR_MSG, "Failed to init isulad conf rwlock"); + goto clean_out; + } + + if (p_state == NULL) { + goto clean_out; + } + + log_term->log_path = p_state->log_path; + /* Default to disable log. */ + log_term->fd = -1; + log_term->log_maxfile = 1; + /* Default value 4k, the min size of a single log file */ + log_term->log_maxsize = DEFAULT_LOG_FILE_SIZE; + + if (p_state->log_maxfile > log_term->log_maxfile) { + log_term->log_maxfile = (unsigned int)p_state->log_maxfile; + } + + if (p_state->log_maxsize > log_term->log_maxsize) { + log_term->log_maxsize = (uint64_t)p_state->log_maxsize; + } + + if (log_term->log_path != NULL) { + if (shim_create_container_log_file(log_term)) { + goto clean_out; + } + } + + *terminal = log_term; + + return SHIM_OK; +clean_out: + free(log_term); + *terminal = NULL; + return SHIM_ERR; +} + process_t* new_process(char *id, char *bundle, char *runtime) { shim_client_process_state* p_state; process_t* p = NULL; int i; + int ret; p_state = load_process(); if (p_state == NULL) { @@ -692,6 +757,13 @@ process_t* new_process(char *id, char *bundle, char *runtime) if (p == NULL) { return NULL; } + ret = terminal_init(&(p->terminal), p_state); + if (ret != SHIM_OK) { + free(p); + p = NULL; + return p; + } + p->id = id; p->bundle = bundle; p->runtime = runtime; @@ -703,6 +775,7 @@ process_t* new_process(char *id, char *bundle, char *runtime) p->ctr_pid = -1; p->stdio = NULL; p->shim_io = NULL; + for (i = 0; i < 3; i ++) { p->io_threads[i] = NULL; } @@ -726,7 +799,6 @@ int open_io(process_t *p) return open_generic_io(p); } - int process_io_init(process_t *p) { int ret = SHIM_ERR; diff --git a/src/cmd/isulad-shim/process.h b/src/cmd/isulad-shim/process.h index a3671d94d5e63b4c63ea56b342941ece7dde7ba0..6033dbc07107c03b19ae9df8cf334dfacdee990d 100644 --- a/src/cmd/isulad-shim/process.h +++ b/src/cmd/isulad-shim/process.h @@ -20,6 +20,7 @@ #include #include #include "shim_client_process_state.h" +#include "terminal.h" #ifdef __cplusplus extern "C" { @@ -39,6 +40,7 @@ typedef struct { typedef struct fd_node { int fd; + bool is_log; struct fd_node *next; } fd_node_t; @@ -56,6 +58,7 @@ typedef struct { sem_t sem_thd; io_copy_t *ioc; bool shutdown; + log_terminal *terminal; } io_thread_t; typedef struct process { @@ -66,6 +69,7 @@ typedef struct process { int io_loop_fd; int exit_fd; int ctr_pid; + log_terminal *terminal; stdio_t *stdio; stdio_t *shim_io; io_thread_t *io_threads[3];// stdin,stdout,stderr diff --git a/src/cmd/isulad-shim/terminal.c b/src/cmd/isulad-shim/terminal.c new file mode 100644 index 0000000000000000000000000000000000000000..5b094e35d05eb69f34af8767d9fefedd9f2ecdf8 --- /dev/null +++ b/src/cmd/isulad-shim/terminal.c @@ -0,0 +1,318 @@ +/****************************************************************************** + * Copyright (c) Huawei Technologies Co., Ltd. 2020. All rights reserved. + * iSulad licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * http://license.coscl.org.cn/MulanPSL + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR + * PURPOSE. + * See the Mulan PSL v1 for more details. + * Author: gaohuatao + * Create: 2020-3-9 + * Description: container logs ops + ******************************************************************************/ +#define _GNU_SOURCE +#include +#include +#include +#include +#include "terminal.h" +#include "common.h" + +#define BUF_CACHE_SIZE (16 * 1024) + +static ssize_t shim_write_nointr_lock(log_terminal *terminal, const void *buf, size_t count) +{ + ssize_t ret; + + (void)pthread_rwlock_wrlock(&terminal->log_terminal_rwlock); + ret = write_nointr(terminal->fd, buf, count); + (void)pthread_rwlock_unlock(&terminal->log_terminal_rwlock); + + return ret; +} + +static int shim_rename_old_log_file(log_terminal *terminal) +{ + int ret; + unsigned int i; + char tmp[PATH_MAX] = {0}; + char *rename_fname = NULL; + + for (i = terminal->log_maxfile - 1; i > 1; i--) { + ret = snprintf(tmp, PATH_MAX, "%s.%u", terminal->log_path, i); + if (ret < 0 || ret >= PATH_MAX) { + free(rename_fname); + return SHIM_ERR; + } + free(rename_fname); + rename_fname = safe_strdup(tmp); + + ret = snprintf(tmp, PATH_MAX, "%s.%u", terminal->log_path, (i - 1)); + if (ret < 0 || ret >= PATH_MAX) { + free(rename_fname); + return SHIM_ERR; + } + + ret = rename(tmp, rename_fname); + if (ret < 0 && errno != ENOENT) { + free(rename_fname); + return SHIM_ERR; + } + } + + free(rename_fname); + return SHIM_OK; +} + +static int shim_dump_log_file(log_terminal *terminal) +{ + int ret; + char *file_newname; + size_t len_path = strlen(terminal->log_path) + sizeof(".1"); + + /* isulad: rotate old log file first */ + ret = shim_rename_old_log_file(terminal); + if (ret != 0) { + return SHIM_ERR; + } + + file_newname = calloc(len_path, 1); + if (file_newname == NULL) { + return SHIM_ERR; + } + + ret = snprintf(file_newname, len_path, "%s.1", terminal->log_path); + if (ret < 0 || (size_t)ret >= len_path) { + ret = -1; + goto clean_out; + } + + /* + * Rename the file console.log to console.log.1 then create and open console.log again. + * fd points to console.log file always. + */ + close(terminal->fd); + terminal->fd = -1; + (void)rename(terminal->log_path, file_newname); + ret = shim_create_container_log_file(terminal); +clean_out: + free(file_newname); + return ret; +} + +static int64_t get_log_file_size(int fd) +{ + struct stat log_st; + int ret; + + ret = fstat(fd, &log_st); + if (ret < 0) { + return SHIM_ERR; + } + + if (S_IFREG != (log_st.st_mode & S_IFMT)) { + return SHIM_ERR; + } + + return log_st.st_size; +} + +static int shim_json_data_write(log_terminal *terminal, const char *buf, + int read_count) +{ + int ret; + int64_t available_space = -1; + int64_t file_size; + + file_size = get_log_file_size(terminal->fd); + if (file_size < 0) { + return SHIM_ERR; + } + + available_space = terminal->log_maxsize - file_size; + if (read_count <= available_space) { + return shim_write_nointr_lock(terminal, buf, read_count); + } + + ret = shim_dump_log_file(terminal); + if (ret < 0) { + return SHIM_ERR; + } + + /* + * Now file is new, then write the max bytes that will be wrote to log file. + * We have set the log file min size 16k, so the scenario of log_maxsize < read_count + * shouldn't happen, otherwise, discard some last bytes. + */ + ret = shim_write_nointr_lock(terminal, buf, + terminal->log_maxsize < read_count ? terminal->log_maxsize : read_count); + if (ret < 0) { + return SHIM_ERR; + } + + return (read_count - ret); +} + +static bool get_time_buffer(struct timespec *timestamp, char *timebuffer, + size_t maxsize) +{ + struct tm tm_utc = { 0 }; + int32_t nanos = 0; + time_t seconds; + size_t len = 0; + int ret = 0; + + if (!timebuffer || !maxsize) { + return false; + } + + seconds = (time_t)timestamp->tv_sec; + gmtime_r(&seconds, &tm_utc); + strftime(timebuffer, maxsize, "%Y-%m-%dT%H:%M:%S", &tm_utc); + + nanos = (int32_t)timestamp->tv_nsec; + len = strlen(timebuffer); + ret = snprintf(timebuffer + len, (maxsize - len), ".%09dZ", nanos); + if (ret < 0 || ret >= (maxsize - len)) { + return false; + } + + return true; +} + +static bool get_now_time_buffer(char *timebuffer, size_t maxsize) +{ + int err = 0; + struct timespec ts; + + err = clock_gettime(CLOCK_REALTIME, &ts); + if (err != 0) { + return false; + } + + return get_time_buffer(&ts, timebuffer, maxsize); +} + +static ssize_t shim_logger_write(log_terminal *terminal, const char *type, const char *buf, + int read_count) +{ + logger_json_file *msg = NULL; + ssize_t ret = -1; + size_t len; + char *json = NULL; + char timebuffer[64] = { 0 }; + parser_error err = NULL; + struct parser_context ctx = { OPT_GEN_SIMPLIFY | OPT_GEN_NO_VALIDATE_UTF8, stderr }; + + if (read_count < 0 || read_count >= INT_MAX) { + return SHIM_ERR; + } + + msg = calloc(sizeof(logger_json_file), 1); + if (msg == NULL) { + return SHIM_ERR; + } + + msg->log = calloc(read_count, 1); + if (!msg->log) { + goto cleanup; + } + memcpy(msg->log, buf, read_count); + msg->log_len = read_count; + msg->stream = type ? safe_strdup(type) : safe_strdup("stdout"); + + get_now_time_buffer(timebuffer, sizeof(timebuffer)); + msg->time = safe_strdup(timebuffer); + json = logger_json_file_generate_json(msg, &ctx, &err); + if (!json) { + goto cleanup; + } + len = strlen(json); + json[len] = '\n'; + if (terminal->fd < 0) { + goto cleanup; + } + + ret = shim_json_data_write(terminal, json, len + 1); +cleanup: + free(json); + free_logger_json_file(msg); + free(err); + return ret; +} + +void shim_write_container_log_file(log_terminal *terminal, const char *type, char *buf, + int read_count) +{ + static char cache[BUF_CACHE_SIZE]; + static int size = 0; + int upto, index; + int begin = 0, buf_readed = 0, buf_left = 0; + + if (terminal == NULL) { + return; + } + + if (buf != NULL && read_count > 0) { + upto = size + read_count; + if (upto > BUF_CACHE_SIZE) { + upto = BUF_CACHE_SIZE; + } + + if (upto > size) { + buf_readed = upto - size; + memcpy(cache + size, buf, buf_readed); + buf_left = read_count - buf_readed; + size += buf_readed; + } + } + + if (size == 0) { + return; + } + + for (index = 0; index < size; index++) { + if (cache[index] == '\n') { + (void)shim_logger_write(terminal, type, cache + begin, index - begin + 1); + begin = index + 1; + } + } + + if (buf == NULL || (begin == 0 && size == BUF_CACHE_SIZE)) { + if (begin < size) { + (void)shim_logger_write(terminal, type, cache + begin, size - begin); + begin = 0; + size = 0; + } + if (buf == NULL) { + return; + } + } + + if (begin > 0) { + memcpy(cache, cache + begin, size - begin); + size -= begin; + } + + if (buf_left > 0) { + memcpy(cache + size, buf + buf_readed, buf_left); + size += buf_left; + } +} + +int shim_create_container_log_file(log_terminal *terminal) +{ + if (!terminal->log_path) { + return SHIM_ERR; + } + + terminal->fd = open(terminal->log_path, O_CLOEXEC | O_RDWR | O_CREAT | O_APPEND, 0600); + if (terminal->fd < 0) { + return SHIM_ERR; + } + + return SHIM_OK; +} + diff --git a/src/cmd/isulad-shim/terminal.h b/src/cmd/isulad-shim/terminal.h new file mode 100644 index 0000000000000000000000000000000000000000..c66992a0c17a5e284c8e0b20022fdd4bfe9ecf24 --- /dev/null +++ b/src/cmd/isulad-shim/terminal.h @@ -0,0 +1,48 @@ +/****************************************************************************** + * Copyright (c) Huawei Technologies Co., Ltd. 2020. All rights reserved. + * iSulad licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * http://license.coscl.org.cn/MulanPSL + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR + * PURPOSE. + * See the Mulan PSL v1 for more details. + * Author: gaohuatao + * Create: 2020-3-9 + * Description: container logs ops + ******************************************************************************/ + +#ifndef __SHIM_TERMINAL_H +#define __SHIM_TERMINAL_H + +#include +#include +#include "logger_json_file.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef PATH_MAX +#define PATH_MAX 4096 +#endif + +typedef struct { + uint64_t log_maxsize; + char *log_path; + int fd; + unsigned int log_maxfile; + pthread_rwlock_t log_terminal_rwlock; +} log_terminal; + +void shim_write_container_log_file(log_terminal *terminal, const char *type, char *buf, + int bytes_read); + +int shim_create_container_log_file(log_terminal *terminal); + +#ifdef __cplusplus +} +#endif + +#endif /* __SHIM_TERMINAL_H */ diff --git a/src/engines/lcr/lcr_engine.c b/src/engines/lcr/lcr_engine.c index 644c742cb6248ccdda9723c3f4caff0bdc8d8738..fec13a36a0b94cfcab7fa6e63d6b1881d89d7a49 100644 --- a/src/engines/lcr/lcr_engine.c +++ b/src/engines/lcr/lcr_engine.c @@ -262,7 +262,7 @@ struct engine_operation *lcr_engine_init() { void *lcr_handler = NULL; struct engine_operation *eop = NULL; - lcr_handler = dlopen("liblcr.so", RTLD_NOW | RTLD_DEEPBIND); + lcr_handler = dlopen("liblcr.so", RTLD_NOW); if (lcr_handler == NULL) { ERROR("Plugin error: %s", dlerror()); return NULL; diff --git a/src/json/schema/schema/shim/client/process-state.json b/src/json/schema/schema/shim/client/process-state.json index a80393df2845b43e3b93c6b72efac2ba61294764..df2141674b3d99bdf1ede22b2888ab2c5d6ffb16 100644 --- a/src/json/schema/schema/shim/client/process-state.json +++ b/src/json/schema/schema/shim/client/process-state.json @@ -188,6 +188,15 @@ }, "rootGID": { "type": "integer" + }, + "logPath": { + "type": "string" + }, + "logMaxfile": { + "type": "integer" + }, + "logMaxsize": { + "type": "int64" } } } diff --git a/src/runtime/isula/isula_rt_ops.c b/src/runtime/isula/isula_rt_ops.c index 16f78a59e4ba33100cefc74c71dd3349502d0144..a55e44b8e89add83e16ec3418b27ec4bd1661747 100644 --- a/src/runtime/isula/isula_rt_ops.c +++ b/src/runtime/isula/isula_rt_ops.c @@ -28,11 +28,14 @@ #include "shim_client_process_state.h" #include "oci_runtime_state.h" #include "isulad_config.h" +#include "utils_string.h" +#include "libisulad.h" #define SHIM_BINARY "isulad-shim" #define SHIM_LOG_SIZE ((BUFSIZ-100)/2) #define PID_WAIT_TIME 120 + static void copy_process(shim_client_process_state *p, defs_process *dp) { p->args = dp->args; @@ -52,6 +55,31 @@ static void copy_process(shim_client_process_state *p, defs_process *dp) p->rlimits_len = dp->rlimits_len; } +static void copy_annotations(shim_client_process_state *p, json_map_string_string *anno) +{ + size_t i; + if (anno == NULL) { + return; + } + for (i = 0; i < anno->len; i++) { + if (strcmp(anno->keys[i], CONTAINER_LOG_CONFIG_KEY_FILE) == 0) { + p->log_path = anno->values[i]; + } else if (strcmp(anno->keys[i], CONTAINER_LOG_CONFIG_KEY_ROTATE) == 0) { + int tmaxfile = 0; + if (util_safe_int(anno->values[i], &tmaxfile) == 0 && tmaxfile > 0) { + p->log_maxfile = tmaxfile; + } + continue; + } + if (strcmp(anno->keys[i], CONTAINER_LOG_CONFIG_KEY_SIZE) == 0) { + int64_t tmaxsize = 0; + if (util_parse_byte_size_string(anno->values[i], &tmaxsize) == 0 && tmaxsize > 0) { + p->log_maxsize = tmaxsize; + } + } + } +} + static int file_write_int(const char *fname, int val) { char sint[UINT_LEN] = {0}; @@ -731,6 +759,7 @@ int rt_isula_create(const char *id, const char *runtime, p.runtime_args = (char **)runtime_args; p.runtime_args_len = runtime_args_len; copy_process(&p, config->process); + copy_annotations(&p, config->annotations); ret = create_process_json_file(workdir, &p); if (ret != 0) { diff --git a/src/services/execution/execute/execution.c b/src/services/execution/execute/execution.c index 90a3f566ce8c2d29051dc881918574b7606f55fc..0a99965e9da04a227b1a92dfc90f1ac48e681621 100644 --- a/src/services/execution/execute/execution.c +++ b/src/services/execution/execute/execution.c @@ -255,7 +255,7 @@ static int umount_dev_tmpfs_for_system_container(const container_t *cont) ERROR("Out of memory"); return -1; } - if (umount(rootfs_dev_path) < 0 && errno != EINVAL) { + if (umount(rootfs_dev_path) < 0 && errno != ENOENT) { ERROR("Failed to umount dev tmpfs: %s, error: %s", rootfs_dev_path, strerror(errno)); return -1; } diff --git a/src/services/execution/execute/execution_stream.c b/src/services/execution/execute/execution_stream.c index cfa334b5b6b8737181e674ffc40c8e3ef532bf50..03920ba8bd935247b72e1af997747a8d05f13226 100644 --- a/src/services/execution/execute/execution_stream.c +++ b/src/services/execution/execute/execution_stream.c @@ -356,39 +356,49 @@ out: return ret; } -static int merge_exec_process_env(defs_process *spec, const container_config *container_spec, const char **env, - size_t env_len) +static int merge_exec_from_container_env(defs_process *spec, const container_config *container_spec) { int ret = 0; - size_t env_count = 0; size_t i = 0; - if (env_len > LIST_ENV_SIZE_MAX - container_spec->env_len) { + if (container_spec->env_len > LIST_ENV_SIZE_MAX - spec->env_len) { ERROR("The length of envionment variables is too long, the limit is %d", LIST_ENV_SIZE_MAX); isulad_set_error_message("The length of envionment variables is too long, the limit is %d", LIST_ENV_SIZE_MAX); ret = -1; goto out; } - env_count = container_spec->env_len + env_len; - if (env_count == 0) { - ret = 0; - goto out; + + for (i = 0; i < container_spec->env_len; i++) { + ret = util_array_append(&(spec->env), container_spec->env[i]); + if (ret != 0) { + ERROR("Failed to append container env to exec process env"); + goto out; + } + spec->env_len++; } - spec->env = util_common_calloc_s(env_count * sizeof(char *)); - if (spec->env == NULL) { - ERROR("Failed to malloc memory for envionment variables"); +out: + return ret; +} + +static int merge_envs_from_request_env(defs_process *spec, const char **envs, size_t env_len) +{ + int ret = 0; + size_t i = 0; + + if (env_len > LIST_ENV_SIZE_MAX - spec->env_len) { + ERROR("The length of envionment variables is too long, the limit is %d", LIST_ENV_SIZE_MAX); + isulad_set_error_message("The length of envionment variables is too long, the limit is %d", LIST_ENV_SIZE_MAX); ret = -1; goto out; } - for (i = 0; i < container_spec->env_len; i++) { - spec->env[spec->env_len] = util_strdup_s(container_spec->env[i]); - spec->env_len++; - } - for (i = 0; i < env_len; i++) { - spec->env[spec->env_len] = util_strdup_s(env[i]); + ret = util_array_append(&(spec->env), envs[i]); + if (ret != 0) { + ERROR("Failed to append request env to exec process env"); + goto out; + } spec->env_len++; } @@ -433,7 +443,7 @@ out: } static defs_process *make_exec_process_spec(const container_config *container_spec, defs_process_user *puser, - const container_exec_request *request) + const char *runtime, const container_exec_request *request) { int ret = 0; defs_process *spec = NULL; @@ -443,16 +453,26 @@ static defs_process *make_exec_process_spec(const container_config *container_sp return NULL; } - ret = merge_exec_process_env(spec, container_spec, (const char **)request->env, request->env_len); + if (strcasecmp(runtime, "lcr") != 0) { + ret = merge_exec_from_container_env(spec, container_spec); + if (ret != 0) { + ERROR("Failed to dup args for exec process spec"); + goto err_out; + } + } + + ret = merge_envs_from_request_env(spec, (const char **)request->env, request->env_len); if (ret != 0) { ERROR("Failed to dup args for exec process spec"); goto err_out; } - ret = append_necessary_process_env(request->tty, container_spec, spec); - if (ret != 0) { - ERROR("Failed to append necessary for exec process spec"); - goto err_out; + if (strcasecmp(runtime, "lcr") != 0) { + ret = append_necessary_process_env(request->tty, container_spec, spec); + if (ret != 0) { + ERROR("Failed to append necessary for exec process spec"); + goto err_out; + } } ret = dup_array_of_strings((const char **)request->argv, request->argv_len, &(spec->args), &(spec->args_len)); @@ -507,7 +527,7 @@ static int exec_container(container_t *cont, const char *runtime, char * const c goto out; } - process_spec = make_exec_process_spec(cont->common_config->config, puser, request); + process_spec = make_exec_process_spec(cont->common_config->config, puser, runtime, request); if (process_spec == NULL) { ERROR("Exec: Failed to make process spec"); ret = -1; diff --git a/src/types_def.c b/src/types_def.c index bfc17696654115da904d6d322a9aef687b0c01d6..9134976af3eec7fdb7367da784b9ecac68e7acb6 100644 --- a/src/types_def.c +++ b/src/types_def.c @@ -116,6 +116,9 @@ bool get_timestamp(const char *str_time, types_timestamp_t *timestamp) return false; } + // set tm_isdst be kept as -1 to let the system decide if its dst or not + tm_day.tm_isdst = -1; + seconds = (int64_t)mktime(&tm_day); timestamp->has_seconds = true; timestamp->seconds = seconds; @@ -559,7 +562,11 @@ static int64_t get_minmus_time(struct tm *tm1, struct tm *tm2) return -1; } + // set tm_isdst be kept as -1 to let the system decide if its dst or not + tm1->tm_isdst = -1; tmseconds1 = (int64_t)mktime(tm1); + // set tm_isdst be kept as -1 to let the system decide if its dst or not + tm2->tm_isdst = -1; tmseconds2 = (int64_t)mktime(tm2); result = tmseconds1 - tmseconds2; return result; @@ -911,6 +918,10 @@ int to_unix_nanos_from_str(const char *str, int64_t *nanos) ERROR("Transform str to timestamp failed"); return -1; } + + // set tm_isdst be kept as -1 to let the system decide if its dst or not + tm.tm_isdst = -1; + *nanos = mktime(&tm) * Time_Second + nano; return 0; }