From 3fa5ff4e27ce491f9640788e1352d357e6931120 Mon Sep 17 00:00:00 2001 From: gaohuatao Date: Thu, 12 Nov 2020 19:13:08 +0800 Subject: [PATCH] update from v2.0.5 to v2.0.6 Signed-off-by: gaohuatao --- CI/Dockerfile | 2 +- CI/install_depends.sh | 1 + CI/make-and-install.sh | 4 +- CI/test.sh | 2 +- CI/test_cases/container_cases/blkio_iops.sh | 74 + CI/test_cases/container_cases/blkio_weight.sh | 76 + .../container_cases/dev_cgroup_rule.sh | 98 ++ CI/test_cases/container_cases/nano_cpus.sh | 113 ++ CI/test_cases/container_cases/run.sh | 2 +- .../container_cases/storage_opts_dm.sh | 2 +- .../image_cases/image_load_multiplex.sh | 83 ++ .../image_cases/multiplex_busybox.tar | Bin 0 -> 20480 bytes CI/test_cases/image_cases/registry.sh | 22 +- CMakeLists.txt | 12 +- Dockerfile | 2 +- README.md | 85 +- cmake/checker.cmake | 16 +- cmake/options.cmake | 9 +- docs/build_guide.md | 6 +- iSulad.spec | 26 +- release_notes | 62 + src/CMakeLists.txt | 4 +- src/client/connect/CMakeLists.txt | 2 +- .../connect/grpc/grpc_containers_client.cc | 95 +- src/client/connect/isula_connect.h | 2 +- .../{libisula.c => connect/protocol_type.c} | 209 +-- .../{libisula.h => connect/protocol_type.h} | 204 +-- .../connect/rest/rest_containers_client.c | 94 +- src/cmd/CMakeLists.txt | 10 +- src/cmd/command_parser.c | 57 +- src/cmd/command_parser.h | 6 +- src/cmd/isula/base/create.c | 675 +++++---- src/cmd/isula/base/create.h | 826 ++++++----- src/cmd/isula/base/kill.c | 2 +- src/cmd/isula/base/rename.c | 1 - src/cmd/isula/base/restart.c | 1 - src/cmd/isula/base/rm.c | 3 +- src/cmd/isula/base/run.c | 59 +- src/cmd/isula/base/start.c | 1 - src/cmd/isula/base/start.h | 2 +- src/cmd/isula/base/stop.c | 1 - src/cmd/isula/client_arguments.c | 18 + src/cmd/isula/client_arguments.h | 25 +- src/cmd/isula/client_console.c | 319 ++++ src/cmd/isula/client_console.h | 52 + src/cmd/isula/extend/events.c | 8 +- src/cmd/isula/extend/export.c | 1 - src/cmd/isula/extend/pause.c | 1 - src/cmd/isula/extend/resume.c | 1 - src/cmd/isula/extend/stats.c | 9 +- src/cmd/isula/extend/update.c | 92 +- src/cmd/isula/extend/update.h | 34 +- src/cmd/isula/images/images.c | 2 +- src/cmd/isula/images/import.c | 2 +- src/cmd/isula/images/load.c | 1 - src/cmd/isula/images/login.c | 3 +- src/cmd/isula/images/login.h | 4 +- src/cmd/isula/images/logout.c | 1 - src/cmd/isula/images/pull.c | 1 - src/cmd/isula/images/rmi.c | 1 - src/cmd/isula/images/tag.c | 2 +- src/cmd/isula/information/health.c | 1 - src/cmd/isula/information/info.c | 1 - src/cmd/isula/information/inspect.c | 1 - src/cmd/isula/information/logs.c | 8 +- src/cmd/isula/information/logs.h | 16 +- src/cmd/isula/information/ps.c | 18 +- src/cmd/isula/information/top.c | 1 - src/cmd/isula/information/version.c | 1 - src/cmd/isula/information/wait.c | 2 +- src/cmd/isula/isula_commands.c | 239 +-- src/cmd/isula/isula_commands.h | 27 +- src/cmd/isula/isula_container_spec.c | 486 +++++++ src/cmd/isula/isula_container_spec.h | 92 ++ .../isula/isula_host_spec.c} | 1296 +++++------------ src/cmd/isula/isula_host_spec.h | 156 ++ src/cmd/isula/stream/attach.c | 1 - src/cmd/isula/stream/cp.c | 6 +- src/cmd/isula/stream/exec.c | 148 +- src/cmd/isulad-shim/main.c | 22 +- src/cmd/isulad-shim/process.c | 291 ++-- src/cmd/isulad-shim/terminal.c | 8 +- src/cmd/isulad/isulad_commands.c | 176 +-- src/cmd/isulad/isulad_commands.h | 4 +- src/cmd/isulad/main.c | 13 +- src/cmd/options/CMakeLists.txt | 5 + src/cmd/options/opt_ulimit.c | 190 +++ .../options/opt_ulimit.h} | 23 +- src/common/constants.h | 3 - src/contrib/config/config.json | 1 - src/contrib/config/daemon.json | 2 +- .../config/systemcontainer_config.json | 1 - src/daemon/common/CMakeLists.txt | 11 +- src/daemon/common/selinux_label.c | 2 +- src/daemon/common/sysinfo.c | 9 +- src/daemon/common/sysinfo.h | 2 +- src/daemon/config/daemon_arguments.c | 4 +- src/daemon/config/isulad_config.c | 216 +-- src/daemon/config/isulad_config.h | 4 +- .../connect/grpc/grpc_server_tls_auth.cc | 4 +- src/daemon/entry/cri/cni_network_plugin.cc | 63 +- src/daemon/entry/cri/cri_container.cc | 37 +- src/daemon/entry/cri/cri_helpers.cc | 45 +- src/daemon/entry/cri/cri_sandbox.cc | 62 +- src/daemon/entry/cri/cri_security_context.cc | 5 +- src/daemon/executor/container_cb/execution.c | 4 +- .../executor/container_cb/execution_create.c | 227 ++- .../executor/container_cb/execution_extend.c | 50 +- .../container_cb/execution_information.c | 8 +- .../executor/container_cb/execution_network.c | 10 +- .../executor/container_cb/execution_stream.c | 26 +- src/daemon/executor/container_cb/list.c | 4 +- src/daemon/executor/image_cb/image_cb.c | 4 +- .../container/container_events_handler.c | 2 +- .../container/container_gc/containers_gc.c | 6 +- .../modules/container/container_state.c | 8 +- .../container/health_check/health_check.c | 22 +- .../modules/container/restore/restore.c | 2 +- .../modules/container/supervisor/supervisor.c | 2 +- src/daemon/modules/events/collector.c | 24 +- src/daemon/modules/events/monitord.c | 44 +- src/daemon/modules/events/monitord.h | 6 +- .../modules/events_sender/event_sender.c | 2 +- src/daemon/modules/image/CMakeLists.txt | 2 + src/daemon/modules/image/embedded/db/db_all.c | 8 +- .../modules/image/embedded/db/sqlite_common.c | 14 +- .../image/embedded/embedded_config_merge.c | 57 +- .../image/embedded/embedded_config_merge.h | 3 +- src/daemon/modules/image/embedded/lim.c | 14 +- src/daemon/modules/image/embedded/lim.h | 2 +- src/daemon/modules/image/image.c | 24 +- .../modules/image/image_rootfs_handler.c | 45 +- src/daemon/modules/image/image_spec_merge.c | 84 ++ src/daemon/modules/image/image_spec_merge.h | 30 + .../modules/image/oci/oci_common_operators.c | 10 +- .../modules/image/oci/oci_config_merge.c | 50 +- src/daemon/modules/image/oci/oci_image.c | 8 +- src/daemon/modules/image/oci/oci_import.c | 34 +- src/daemon/modules/image/oci/oci_load.c | 331 +++-- src/daemon/modules/image/oci/oci_load.h | 5 +- src/daemon/modules/image/oci/oci_pull.c | 5 +- src/daemon/modules/image/oci/registry/auths.c | 36 +- src/daemon/modules/image/oci/registry/auths.h | 2 +- src/daemon/modules/image/oci/registry/certs.c | 4 +- .../modules/image/oci/registry/http_request.c | 2 +- .../modules/image/oci/registry/registry.c | 66 +- .../image/oci/registry/registry_apiv2.c | 15 +- src/daemon/modules/image/oci/registry_type.c | 8 +- src/daemon/modules/image/oci/registry_type.h | 2 +- .../oci/storage/image_store/image_store.c | 323 ++-- .../graphdriver/devmapper/deviceset.c | 8 +- .../storage/layer_store/graphdriver/driver.c | 4 +- .../storage/layer_store/graphdriver/driver.h | 7 +- .../graphdriver/overlay2/driver_overlay2.c | 40 +- .../graphdriver/overlay2/driver_overlay2.h | 2 +- .../graphdriver/quota/project_quota.c | 4 +- .../image/oci/storage/layer_store/layer.h | 2 +- .../oci/storage/layer_store/layer_store.c | 84 +- .../oci/storage/layer_store/layer_store.h | 5 +- .../oci/storage/rootfs_store/rootfs_store.c | 326 ++--- .../oci/storage/rootfs_store/rootfs_store.h | 3 - .../modules/image/oci/storage/storage.c | 48 +- .../modules/image/oci/storage/storage.h | 4 +- src/daemon/modules/image/oci/utils_images.c | 28 +- src/daemon/modules/image/oci/utils_images.h | 2 - src/daemon/modules/plugin/plugin.c | 8 +- src/daemon/modules/runtime/engines/engine.h | 2 + .../modules/runtime/engines/lcr/lcr_engine.c | 2 + .../modules/runtime/engines/lcr/lcr_rt_ops.c | 12 + .../modules/runtime/isula/isula_rt_ops.c | 6 +- .../modules/service/service_container.c | 6 +- src/daemon/modules/spec/specs.c | 136 +- src/daemon/modules/spec/specs_extend.c | 50 +- src/daemon/modules/spec/specs_mount.c | 528 +++++-- src/daemon/modules/spec/specs_namespace.c | 10 +- src/daemon/modules/spec/specs_security.c | 57 +- src/daemon/modules/spec/specs_security.h | 4 +- src/daemon/modules/spec/verify.c | 147 +- src/utils/cutils/map/rb_tree.c | 8 +- src/utils/cutils/namespace.c | 6 +- src/utils/cutils/namespace.h | 12 +- src/utils/cutils/path.c | 56 +- src/utils/cutils/path.h | 25 +- src/utils/cutils/utils.c | 430 +----- src/utils/cutils/utils.h | 66 +- src/utils/cutils/utils_convert.c | 52 + src/utils/cutils/utils_convert.h | 4 +- src/utils/cutils/utils_file.c | 24 +- src/utils/cutils/utils_file.h | 8 +- src/utils/cutils/utils_fs.c | 41 +- src/utils/cutils/utils_fs.h | 3 +- src/utils/cutils/utils_regex.c | 5 +- src/utils/cutils/utils_string.c | 61 +- src/utils/cutils/utils_string.h | 22 +- src/utils/cutils/utils_timestamp.c | 145 +- src/utils/cutils/utils_timestamp.h | 47 +- src/utils/cutils/utils_verify.c | 101 +- src/utils/cutils/utils_verify.h | 17 + src/utils/http/parser.c | 2 +- src/utils/http/rest_common.c | 5 +- src/utils/sha256/sha256.c | 2 +- src/utils/sha256/sha256.h | 2 +- src/utils/tar/isulad_tar.c | 28 +- src/utils/tar/util_archive.c | 4 +- test/cmd/isula/CMakeLists.txt | 2 +- test/cmd/isula/extend/pause/CMakeLists.txt | 2 +- test/cmd/isula/extend/pause/pause_ut.cc | 2 +- test/cmd/isula/extend/resume/CMakeLists.txt | 2 +- test/cmd/isula/extend/resume/resume_ut.cc | 2 +- .../CMakeLists.txt | 0 .../info/CMakeLists.txt | 2 +- .../info/info_ut.cc | 2 +- .../ps/CMakeLists.txt | 2 +- .../{infomation => information}/ps/ps_ut.cc | 2 +- test/cutils/utils_string/utils_string_ut.cc | 136 +- .../image/oci/oci_config_merge/CMakeLists.txt | 3 + test/image/oci/registry/registry_ut.cc | 15 +- .../oci/storage/images/storage_images_ut.cc | 10 +- .../oci/storage/layers/storage_driver_ut.cc | 4 +- .../oci/storage/layers/storage_layers_ut.cc | 8 +- .../oci/storage/rootfs/storage_rootfs_ut.cc | 22 +- test/mocks/namespace_mock.cc | 2 +- test/mocks/storage_mock.cc | 12 +- test/mocks/storage_mock.h | 3 +- test/path/path_ut.cc | 102 +- test/runtime/isula/CMakeLists.txt | 1 + test/runtime/lcr/CMakeLists.txt | 1 + test/specs/specs/CMakeLists.txt | 1 + test/specs/specs_extend/CMakeLists.txt | 1 + 229 files changed, 6590 insertions(+), 5326 deletions(-) create mode 100644 CI/test_cases/container_cases/blkio_iops.sh create mode 100644 CI/test_cases/container_cases/blkio_weight.sh create mode 100644 CI/test_cases/container_cases/dev_cgroup_rule.sh create mode 100644 CI/test_cases/container_cases/nano_cpus.sh create mode 100755 CI/test_cases/image_cases/image_load_multiplex.sh create mode 100644 CI/test_cases/image_cases/multiplex_busybox.tar rename src/client/{libisula.c => connect/protocol_type.c} (84%) rename src/client/{libisula.h => connect/protocol_type.h} (80%) create mode 100644 src/cmd/isula/client_console.c create mode 100644 src/cmd/isula/client_console.h create mode 100644 src/cmd/isula/isula_container_spec.c create mode 100644 src/cmd/isula/isula_container_spec.h rename src/{client/connect/pack_config.c => cmd/isula/isula_host_spec.c} (51%) create mode 100644 src/cmd/isula/isula_host_spec.h create mode 100644 src/cmd/options/CMakeLists.txt create mode 100644 src/cmd/options/opt_ulimit.c rename src/{client/connect/pack_config.h => cmd/options/opt_ulimit.h} (65%) create mode 100644 src/daemon/modules/image/image_spec_merge.c create mode 100644 src/daemon/modules/image/image_spec_merge.h rename test/cmd/isula/{infomation => information}/CMakeLists.txt (100%) rename test/cmd/isula/{infomation => information}/info/CMakeLists.txt (97%) rename test/cmd/isula/{infomation => information}/info/info_ut.cc (98%) rename test/cmd/isula/{infomation => information}/ps/CMakeLists.txt (97%) rename test/cmd/isula/{infomation => information}/ps/ps_ut.cc (99%) diff --git a/CI/Dockerfile b/CI/Dockerfile index d953da9..b6f2e2c 100644 --- a/CI/Dockerfile +++ b/CI/Dockerfile @@ -8,7 +8,7 @@ # - IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR # - PURPOSE. # - See the Mulan PSL v2 for more details. -##- @Description: prepare compile container envrionment +##- @Description: prepare compile container environment ##- @Author: lifeng ##- @Create: 2020-01-10 ####################################################################### diff --git a/CI/install_depends.sh b/CI/install_depends.sh index 97fefa7..61dd67d 100755 --- a/CI/install_depends.sh +++ b/CI/install_depends.sh @@ -113,6 +113,7 @@ if [ -d ./runc ];then fi git clone https://gitee.com/src-openeuler/runc.git cd runc +git checkout -q origin/openEuler-20.03-LTS ./apply-patch mkdir -p .gopath/src/github.com/opencontainers export GOPATH=`pwd`/.gopath diff --git a/CI/make-and-install.sh b/CI/make-and-install.sh index a3d4888..c53cdc6 100755 --- a/CI/make-and-install.sh +++ b/CI/make-and-install.sh @@ -89,7 +89,7 @@ cmake -DLIB_INSTALL_DIR=${restbuilddir}/lib -DCMAKE_INSTALL_PREFIX=${restbuilddi make -j $(nproc) make install sed -i 's/"log-driver": "stdout"/"log-driver": "file"/g' ${restbuilddir}/etc/isulad/daemon.json -sed -i "/registry-mirrors/a\ \"https://hub-mirror.c.163.com\"" ${restbuilddir}/etc/isulad/daemon.json +sed -i "/registry-mirrors/a\ \"https://3laho3y3.mirror.aliyuncs.com\"" ${restbuilddir}/etc/isulad/daemon.json #build grpc version cd $ISULAD_COPY_PATH @@ -104,4 +104,4 @@ fi make -j $(nproc) make install sed -i 's/"log-driver": "stdout"/"log-driver": "file"/g' ${builddir}/etc/isulad/daemon.json -sed -i "/registry-mirrors/a\ \"https://hub-mirror.c.163.com\"" ${builddir}/etc/isulad/daemon.json +sed -i "/registry-mirrors/a\ \"https://3laho3y3.mirror.aliyuncs.com\"" ${builddir}/etc/isulad/daemon.json diff --git a/CI/test.sh b/CI/test.sh index d21ca89..36427b9 100755 --- a/CI/test.sh +++ b/CI/test.sh @@ -42,6 +42,6 @@ elif [ "x$subcmd" == "xget" ];then sleep 2 done else - echo "unknwon subcmd $subcmd" + echo "unknown subcmd $subcmd" exit 1 fi diff --git a/CI/test_cases/container_cases/blkio_iops.sh b/CI/test_cases/container_cases/blkio_iops.sh new file mode 100644 index 0000000..58d3d7f --- /dev/null +++ b/CI/test_cases/container_cases/blkio_iops.sh @@ -0,0 +1,74 @@ +#!/bin/bash +# +# attributes: isulad basic blkio iops +# concurrent: NA +# spend time: 5 + +####################################################################### +##- @Copyright (C) Huawei Technologies., Ltd. 2020. All rights reserved. +# - iSulad licensed under the Mulan PSL v2. +# - You can use this software according to the terms and conditions of the Mulan PSL v2. +# - You may obtain a copy of Mulan PSL v2 at: +# - http://license.coscl.org.cn/MulanPSL2 +# - 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 v2 for more details. +##- @Description:CI +##- @Author: lifeng +##- @Create: 2020-09-03 +####################################################################### + +declare -r curr_path=$(dirname $(readlink -f "$0")) +source ../helpers.sh + +function test_blkio_iops_spec() +{ + local ret=0 + local image="busybox" + local test="container blkio iops test => (${FUNCNAME[@]})" + + msg_info "${test} starting..." + + isula pull ${image} + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to pull image: ${image}" && return ${FAILURE} + + isula images | grep busybox + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - missing list image: ${image}" && ((ret++)) + + isula run -itd --device-read-iops /dev/loop0:-1 $image /bin/sh 2>&1 | grep "Number must be unsigned 64 bytes integer" + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to check Number must be unsigned 64 bytes integer" && ((ret++)) + + isula run -itd --device-write-iops /dev/loop0:-1 $image /bin/sh 2>&1 | grep "Number must be unsigned 64 bytes integer" + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to check Number must be unsigned 64 bytes integer" && ((ret++)) + + isula run -itd --device-write-iops /dev/loop0:2b $image /bin/sh 2>&1 | grep "Number must be unsigned 64 bytes integer" + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to check Number must be unsigned 64 bytes integer" && ((ret++)) + + c_id=`isula run -itd --device-read-iops /dev/loop0:123 --device-read-iops /dev/zero:111 --device-write-iops /dev/loop0:567 --device-write-iops /dev/zero:321 busybox sh` + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to run container with image: ${image}" && ((ret++)) + + isula exec -it $c_id sh -c "cat /sys/fs/cgroup/blkio/blkio.throttle.read_iops_device" | grep "7:0 123" + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to check container with image: ${image}" && ((ret++)) + + isula exec -it $c_id sh -c "cat /sys/fs/cgroup/blkio/blkio.throttle.read_iops_device" | grep "1:5 111" + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to check container with image: ${image}" && ((ret++)) + + isula exec -it $c_id sh -c "cat /sys/fs/cgroup/blkio/blkio.throttle.write_iops_device" | grep "7:0 567" + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to check container with image: ${image}" && ((ret++)) + + isula exec -it $c_id sh -c "cat /sys/fs/cgroup/blkio/blkio.throttle.write_iops_device" | grep "1:5 321" + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to check container with image: ${image}" && ((ret++)) + + isula rm -f $c_id + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to rm container ${c_id}" && ((ret++)) + + msg_info "${test} finished with return ${ret}..." + return ${ret} +} + +declare -i ans=0 + +test_blkio_iops_spec || ((ans++)) + +show_result ${ans} "${curr_path}/${0}" diff --git a/CI/test_cases/container_cases/blkio_weight.sh b/CI/test_cases/container_cases/blkio_weight.sh new file mode 100644 index 0000000..6d69960 --- /dev/null +++ b/CI/test_cases/container_cases/blkio_weight.sh @@ -0,0 +1,76 @@ +#!/bin/bash +# +# attributes: isulad basic blkio weight +# concurrent: NA +# spend time: 5 + +####################################################################### +##- @Copyright (C) Huawei Technologies., Ltd. 2020. All rights reserved. +# - iSulad licensed under the Mulan PSL v2. +# - You can use this software according to the terms and conditions of the Mulan PSL v2. +# - You may obtain a copy of Mulan PSL v2 at: +# - http://license.coscl.org.cn/MulanPSL2 +# - 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 v2 for more details. +##- @Description:CI +##- @Author: lifeng +##- @Create: 2020-09-03 +####################################################################### + +declare -r curr_path=$(dirname $(readlink -f "$0")) +source ../helpers.sh + +function test_blkio_weight_spec() +{ + local ret=0 + local image="busybox" + local test="container blkio weight test => (${FUNCNAME[@]})" + + msg_info "${test} starting..." + + isula pull ${image} + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to pull image: ${image}" && return ${FAILURE} + + isula images | grep busybox + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - missing list image: ${image}" && ((ret++)) + + isula run -itd --blkio-weight 1001 $image /bin/sh 2>&1 | grep "Range of blkio weight is from 10 to 1000" + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to check Range of blkio weight is from 10 to 1000" && ((ret++)) + + isula run -itd --blkio-weight -1 $image /bin/sh 2>&1 | grep "Numerical result out of range" + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to check Range of blkio weight is from 10 to 1000" && ((ret++)) + + isula run -itd --blkio-weight-device /dev/zero:1001 $image /bin/sh 2>&1 | grep "Invalid weight for device" + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - Invalid weight for device" && ((ret++)) + + isula run -itd --blkio-weight-device /dev/zero:-1 $image /bin/sh 2>&1 | grep "Invalid weight for device" + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - Invalid weight for device" && ((ret++)) + + c_id=`isula run -itd --blkio-weight 200 ${image} sh` + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to run container with image: ${image}" && ((ret++)) + + isula exec -it $c_id sh -c "cat /sys/fs/cgroup/blkio/blkio.weight" | grep "200" + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to check container blkio.weight: 200" && ((ret++)) + + isula update --blkio-weight 300 $c_id + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to update container blkio.weight" && ((ret++)) + + isula exec -it $c_id sh -c "cat /sys/fs/cgroup/blkio/blkio.weight" | grep "300" + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to check container blkio.weight: 300" && ((ret++)) + + isula rm -f $c_id + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to rm container ${c_id}" && ((ret++)) + + msg_info "${test} finished with return ${ret}..." + return ${ret} +} + +declare -i ans=0 + +if [ -f "/sys/fs/cgroup/blkio/blkio.weight" ];then + test_blkio_weight_spec || ((ans++)) +fi + +show_result ${ans} "${curr_path}/${0}" diff --git a/CI/test_cases/container_cases/dev_cgroup_rule.sh b/CI/test_cases/container_cases/dev_cgroup_rule.sh new file mode 100644 index 0000000..46f0a2a --- /dev/null +++ b/CI/test_cases/container_cases/dev_cgroup_rule.sh @@ -0,0 +1,98 @@ +#!/bin/bash +# +# attributes: isulad basic device cgroup rule +# concurrent: NA +# spend time: 5 + +####################################################################### +##- @Copyright (C) Huawei Technologies., Ltd. 2020. All rights reserved. +# - iSulad licensed under the Mulan PSL v2. +# - You can use this software according to the terms and conditions of the Mulan PSL v2. +# - You may obtain a copy of Mulan PSL v2 at: +# - http://license.coscl.org.cn/MulanPSL2 +# - 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 v2 for more details. +##- @Description:CI +##- @Author: lifeng +##- @Create: 2020-09-03 +####################################################################### + +declare -r curr_path=$(dirname $(readlink -f "$0")) +source ../helpers.sh + +function test_cpu_dev_cgoup_rule_spec() +{ + local ret=0 + local image="busybox" + local test="container device cgroup rule test => (${FUNCNAME[@]})" + + msg_info "${test} starting..." + + isula pull ${image} + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to pull image: ${image}" && return ${FAILURE} + + isula images | grep busybox + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - missing list image: ${image}" && ((ret++)) + + isula run -itd --device-cgroup-rule='b *:*' busybox 2>&1 | grep "Invalid value" + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - Invalid value" && ((ret++)) + + isula run -itd --device-cgroup-rule='d *:*' busybox 2>&1 | grep "Invalid value" + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - Invalid value" && ((ret++)) + + isula run -itd --device-cgroup-rule='d *:* xxx' busybox 2>&1 | grep "Invalid value" + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - Invalid value" && ((ret++)) + + c_id=`isula run -itd --device-cgroup-rule='b 11:22 rmw' --device-cgroup-rule='c *:23 rmw' --device-cgroup-rule='c 33:* rm' busybox sh` + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to run container with image: ${image}" && ((ret++)) + + isula exec -it $c_id sh -c "cat /sys/fs/cgroup/devices/devices.list" | grep "b 11:22 rwm" + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to check b 11:22 rmw: ${image}" && ((ret++)) + + isula exec -it $c_id sh -c "cat /sys/fs/cgroup/devices/devices.list" | grep "c \*:23 rwm" + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to check c *:23 rmw: ${image}" && ((ret++)) + + isula exec -it $c_id sh -c "cat /sys/fs/cgroup/devices/devices.list" | grep "c 33:\* rm" + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to check c 33:* rm: ${image}" && ((ret++)) + + isula restart -t 0 $c_id + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to restart container: $c_id" && ((ret++)) + + isula exec -it $c_id sh -c "cat /sys/fs/cgroup/devices/devices.list" | grep "b 11:22 rwm" + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to check b 11:22 rmw: ${image}" && ((ret++)) + + isula exec -it $c_id sh -c "cat /sys/fs/cgroup/devices/devices.list" | grep "c \*:23 rwm" + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to check c *:23 rmw: ${image}" && ((ret++)) + + isula exec -it $c_id sh -c "cat /sys/fs/cgroup/devices/devices.list" | grep "c 33:\* rm" + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to check c 33:* rm: ${image}" && ((ret++)) + + isula rm -f $c_id + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to rm container ${c_id}" && ((ret++)) + + c_id=`isula run -itd --device-cgroup-rule='a 11:22 rmw' busybox sh` + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to run container with image: ${image}" && ((ret++)) + + isula exec -it $c_id sh -c "cat /sys/fs/cgroup/devices/devices.list" | grep "a \*:\* rwm" + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to check a *:* rwm: ${image}" && ((ret++)) + + isula restart -t 0 $c_id + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to restart container: $c_id" && ((ret++)) + + isula exec -it $c_id sh -c "cat /sys/fs/cgroup/devices/devices.list" | grep "a \*:\* rwm" + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to check a *:* rwm: ${image}" && ((ret++)) + + isula rm -f $c_id + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to rm container ${c_id}" && ((ret++)) + + msg_info "${test} finished with return ${ret}..." + return ${ret} +} + +declare -i ans=0 + +test_cpu_dev_cgoup_rule_spec || ((ans++)) + +show_result ${ans} "${curr_path}/${0}" diff --git a/CI/test_cases/container_cases/nano_cpus.sh b/CI/test_cases/container_cases/nano_cpus.sh new file mode 100644 index 0000000..fd69c5d --- /dev/null +++ b/CI/test_cases/container_cases/nano_cpus.sh @@ -0,0 +1,113 @@ +#!/bin/bash +# +# attributes: isulad basic nano iops +# concurrent: NA +# spend time: 5 + +####################################################################### +##- @Copyright (C) Huawei Technologies., Ltd. 2020. All rights reserved. +# - iSulad licensed under the Mulan PSL v2. +# - You can use this software according to the terms and conditions of the Mulan PSL v2. +# - You may obtain a copy of Mulan PSL v2 at: +# - http://license.coscl.org.cn/MulanPSL2 +# - 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 v2 for more details. +##- @Description:CI +##- @Author: lifeng +##- @Create: 2020-09-03 +####################################################################### + +declare -r curr_path=$(dirname $(readlink -f "$0")) +source ../helpers.sh + +function test_cpu_nano_spec() +{ + local ret=0 + local image="busybox" + local test="container blkio nano test => (${FUNCNAME[@]})" + + msg_info "${test} starting..." + + isula pull ${image} + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to pull image: ${image}" && return ${FAILURE} + + isula images | grep busybox + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - missing list image: ${image}" && ((ret++)) + + isula run -itd --cpus 1.5 --cpu-period 20000 $image /bin/sh 2>&1 | grep "Nano CPUs and CPU Period cannot both be set" + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - Nano CPUs and CPU Period cannot both be set" && ((ret++)) + + isula run -itd --cpus 1.5 --cpu-quota 20000 $image /bin/sh 2>&1 | grep "Nano CPUs and CPU Quota cannot both be set" + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - Nano CPUs and CPU Quota cannot both be set" && ((ret++)) + + c_id=`isula run -itd --cpus 1.5 busybox sh` + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to run container with image: ${image}" && ((ret++)) + + isula exec -it $c_id sh -c "cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us" | grep "150000" + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to check cfs_quota_us: ${image}" && ((ret++)) + + isula exec -it $c_id sh -c "cat /sys/fs/cgroup/cpu/cpu.cfs_period_us" | grep "100000" + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to check cfs_period_us: ${image}" && ((ret++)) + + isula restart -t 0 $c_id + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to restart container: $c_id" && ((ret++)) + + isula exec -it $c_id sh -c "cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us" | grep "150000" + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to check cfs_quota_us: ${image}" && ((ret++)) + + isula exec -it $c_id sh -c "cat /sys/fs/cgroup/cpu/cpu.cfs_period_us" | grep "100000" + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to check cfs_period_us: ${image}" && ((ret++)) + + isula update --cpus 1.3 --cpu-period 20000 $c_id 2>&1 | grep "Nano CPUs and CPU Period cannot both be set" + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - Nano CPUs and CPU Period cannot both be set" && ((ret++)) + + isula update --cpus 1.3 --cpu-quota 20000 $c_id 2>&1 | grep "Nano CPUs and CPU Quota cannot both be set" + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - Nano CPUs and CPU Quota cannot both be set" && ((ret++)) + + isula update --cpu-period 20000 $c_id 2>&1 | grep "CPU Period cannot be updated as NanoCPUs has already been set" + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - CPU Period cannot be updated as NanoCPUs has already been set" && ((ret++)) + + isula update --cpu-quota 20000 $c_id 2>&1 | grep "CPU Quota cannot be updated as NanoCPUs has already been set" + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - CPU Quota cannot be updated as NanoCPUs has already been set" && ((ret++)) + + isula update --cpus 1.3 $c_id + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - Failed to update cpus" && ((ret++)) + + isula exec -it $c_id sh -c "cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us" | grep "130000" + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to check cfs_quota_us: ${image}" && ((ret++)) + + isula exec -it $c_id sh -c "cat /sys/fs/cgroup/cpu/cpu.cfs_period_us" | grep "100000" + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to check cfs_period_us: ${image}" && ((ret++)) + + isula restart -t 0 $c_id + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to restart container: $c_id" && ((ret++)) + + isula exec -it $c_id sh -c "cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us" | grep "130000" + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to check cfs_quota_us: ${image}" && ((ret++)) + + isula exec -it $c_id sh -c "cat /sys/fs/cgroup/cpu/cpu.cfs_period_us" | grep "100000" + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to check cfs_period_us: ${image}" && ((ret++)) + + isula rm -f $c_id + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to rm container ${c_id}" && ((ret++)) + + c_id=`isula run -itd --cpu-period 20000 --cpu-quota 10000 busybox sh` + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to run container with image: ${image}" && ((ret++)) + + isula update --cpus 1.4 $c_id 2>&1 | grep "Nano CPUs cannot be updated as CPU Period has already been set" + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - Nano CPUs cannot be updated as CPU Period has already been set" && ((ret++)) + + isula rm -f $c_id + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to rm container ${c_id}" && ((ret++)) + + msg_info "${test} finished with return ${ret}..." + return ${ret} +} + +declare -i ans=0 + +test_cpu_nano_spec || ((ans++)) + +show_result ${ans} "${curr_path}/${0}" diff --git a/CI/test_cases/container_cases/run.sh b/CI/test_cases/container_cases/run.sh index 85f6e55..357fcd0 100755 --- a/CI/test_cases/container_cases/run.sh +++ b/CI/test_cases/container_cases/run.sh @@ -50,7 +50,7 @@ function do_test_t() echo AA > /tmp/test_run_env - isula run --name $containername -itd -e AAA=BB -e BAA --env-file /tmp/test_run_env busybox + isula run --name $containername -itd --user 100:100 -e AAA=BB -e BAA --env-file /tmp/test_run_env busybox fn_check_eq "$?" "0" "run failed" testcontainer $containername running diff --git a/CI/test_cases/container_cases/storage_opts_dm.sh b/CI/test_cases/container_cases/storage_opts_dm.sh index 705eaad..e0f476f 100755 --- a/CI/test_cases/container_cases/storage_opts_dm.sh +++ b/CI/test_cases/container_cases/storage_opts_dm.sh @@ -84,7 +84,7 @@ function do_test() { local ret=0 - local test="devicemapper dm.mkfsarg adn dm.mountopt params test => (${FUNCNAME[@]})" + local test="devicemapper dm.mkfsarg and dm.mountopt params test => (${FUNCNAME[@]})" msg_info "${test} starting..." isula pull $image_busybox diff --git a/CI/test_cases/image_cases/image_load_multiplex.sh b/CI/test_cases/image_cases/image_load_multiplex.sh new file mode 100755 index 0000000..719d8e7 --- /dev/null +++ b/CI/test_cases/image_cases/image_load_multiplex.sh @@ -0,0 +1,83 @@ +#!/bin/bash +# +# attributes: isulad basic image +# concurrent: NA +# spend time: 22 + +####################################################################### +##- @Copyright (C) Huawei Technologies., Ltd. 2020. All rights reserved. +# - iSulad licensed under the Mulan PSL v2. +# - You can use this software according to the terms and conditions of the Mulan PSL v2. +# - You may obtain a copy of Mulan PSL v2 at: +# - http://license.coscl.org.cn/MulanPSL2 +# - 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 v2 for more details. +##- @Description:CI +##- @Author: gaohuatao +##- @Create: 2020-10-12 +####################################################################### + +declare -r curr_path=$(dirname $(readlink -f "$0")) +source ../helpers.sh +base_image="${curr_path}/busybox.tar" +multiplex_image="${curr_path}/multiplex_busybox.tar" + +function test_multiplex_layers_image_load() +{ + local ret=0 + local test="isula load image with multiplex layers test => (${FUNCNAME[@]})" + + msg_info "${test} starting..." + + # remove all images related to busybox + isula rmi `isula images | grep busybox | awk '{print $3}'` + + # load image lacking layers + isula load -i $multiplex_image + [[ $? -eq 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - load image success, expect fail: ${multiplex_image}" && ((ret++)) + + isula images | grep "multiplex_busybox" + [[ $? -eq 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - get image: multiplex_busybox, expect no such image" && ((ret++)) + + # load base image + isula load -i $base_image + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - load image failed: ${base_image} with" && ((ret++)) + + isula images | grep busybox + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - missing list base image: busybox" && ((ret++)) + + # load image with base image loaded + isula load -i $multiplex_image + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - load image failed: ${multiplex_image}" && ((ret++)) + + container_name=multiplex_container + isula run -tid --name $container_name multiplex_busybox:latest /bin/sh + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - isula run failed" && ((ret++)) + + isula exec $container_name sh -c 'ls /gao' + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - no such file /gao" && ((ret++)) + + isula rm -f $container_name + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - rm container failed" && ((ret++)) + + base_id=`isula inspect -f '{{.image.id}}' busybox:latest` + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - fail to inspect image: busybox:latest" && ((ret++)) + + mult_id=`isula inspect -f '{{.image.id}}' multiplex_busybox:latest` + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - fail to inspect image: multiplex_busybox:latest" && ((ret++)) + + isula rmi $base_id $mult_id + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to remove image ${base_id} and ${mult_id}" && ((ret++)) + + msg_info "${test} finished with return ${ret}..." + return ${ret} +} + +declare -i ans=0 + +test_multiplex_layers_image_load || ((ans++)) + +show_result ${ans} "${curr_path}/${0}" + diff --git a/CI/test_cases/image_cases/multiplex_busybox.tar b/CI/test_cases/image_cases/multiplex_busybox.tar new file mode 100644 index 0000000000000000000000000000000000000000..e55144cc2ffecb6996937acbce41172e5412733a GIT binary patch literal 20480 zcmeI2TTdHD6vuh)r?93ktz_)EUo7>30#YI+B}!BZm*6unALjLYOYa2od z*hw%b5wk{k=RW&8GqZF4c+EwkXOJ7y?J5C!6jn0fAB6ETT&PmWJ5~HcXgajd^1H(k;G!aI)kYxe$ zz_G#7a&45rYW)D}4E&|`r;2W23Llc}{}{t&1NMKr|N71IgFo)>ZD)VU`OSHM8HQB0 zbvgeR_9v9X{Kt1!xw(`lKL5$!Q7CWDUa6*y64=1}|F@~im3>+>|0%=j=KO~pK$`z6 zp>8Pg0_6dX(0w-nsE;PLj%5pVNy()NGEya(WyS<%jp5XCqnV=IDl1(GGSdQ!Kp~5a zo;Z(%VgmLV7V7eKv~BD<)@=p03H;GRtVdXlC>>CxmC%N(f4Zzy+1k8}^$FZ%`6(J* zpl4OnmUbMWJmlD`#*pDt_|GQRib!H4Ydx(AeabRcqg29++&43 z1`|XpDT~aL5PWdlf#r<0+6O2Jd%|8`_J+N#!JYcF*>Aj^bXIBWDUf_9&G}nIF*5{Kd??%}o$3gk~G%uh>i{K0EVzDef>!VQl_b@I##Jb5V zurMNKfZ0GoOHXjDz%cni?PzO%mbcNj)4CgPb{r%J8&+UxROIFKBbse!HGF#2Y~cN0 z*z;Hqz>B_%-kSG6gY+Bke{la~djH?WbCdC>w%TNMx7LM0*jerWUD=;;*b9R4AQ*d0 z`-3aGPTyIV-VJiNE}hz2L8Qn;AQ4Cez9RyIAuP7kSy-PVaf)Yf1D=?SBzU7E+&OMD z!bPU3^Tsh9tfM+3*hfnx)_!nb|DRF*ng7p022T3lBaD*^bjR*Gc}PEyr<+8OB!b)_ zf_#OPwn8sC%bT{ULGL=cxGBzIxsB-|B_m=+LJeTA59_&>d@jx{bi5M>B`?LQ-nQ>8 zg{qysy`@g2xrgINnngje3Pd?U2#zGim}S^H5tO%@k)Sw;#W-3=qE^AfnK2wxayGmv|( zX(WBrxiA@sCKsqZpL9yf{8<`!w2)`nNgg2W=t|CW5nv1ES-=?_1jG5TWZDX91dB2Q z!4|Z>C>&7)8%lyR(Nk+duT>O|jSbYg6b1w3hIo;|2OFZ5RiF$Tsci&(m_#T~trRY5 z?S!SCN~SQ$6q6E8nWdoUc$V~?huR7ZhIO1&O%Ag=kIloh()q=!{D1Q4YSMP+6ma~~bcZ?jJ{X$KetMWum1^Atfx&QW%RB>P zulM7=wY_!opTmzmx;)DZ^gjwOp5*_1EAOu<2m86*<+&-^h!Ozr{nzkDIkczq-Na|B z%V@c@z~Ac7;nf)gG=JYE>sn>Uv*WaSea&!6c@u#|AQ4Ce5`jb@5l93Q zfkYq?NCXmrL?97J1QLNnAQ4Ce5`jb@5l93QfkYq?NCXmrL?97J1QLNnAQ4Ce9*Mwz DD^Trr literal 0 HcmV?d00001 diff --git a/CI/test_cases/image_cases/registry.sh b/CI/test_cases/image_cases/registry.sh index 7507d22..042b1f4 100755 --- a/CI/test_cases/image_cases/registry.sh +++ b/CI/test_cases/image_cases/registry.sh @@ -39,8 +39,8 @@ function isula_pull() isula inspect busybox fn_check_eq "$?" "0" "isula inspect busybox" - isula pull hub-mirror.c.163.com/library/busybox - fn_check_eq "$?" "0" "isula pull hub-mirror.c.163.com/library/busybox" + isula pull 3laho3y3.mirror.aliyuncs.com/library/busybox + fn_check_eq "$?" "0" "isula pull 3laho3y3.mirror.aliyuncs.com/library/busybox" rm -f /etc/isulad/daemon.json.bak cp /etc/isulad/daemon.json /etc/isulad/daemon.json.bak @@ -59,7 +59,7 @@ function isula_pull() cp /etc/isulad/daemon.json.bak /etc/isulad/daemon.json rm -f /etc/isulad/daemon.json.bak - isula rmi hub-mirror.c.163.com/library/busybox + isula rmi 3laho3y3.mirror.aliyuncs.com/library/busybox check_valgrind_log fn_check_eq "$?" "0" "stop isulad with check valgrind" @@ -70,12 +70,12 @@ function isula_pull() function isula_login() { - isula login -u test -p test hub-mirror.c.163.com - fn_check_eq "$?" "0" "isula login -u test -p test hub-mirror.c.163.com" + isula login -u test -p test 3laho3y3.mirror.aliyuncs.com + fn_check_eq "$?" "0" "isula login -u test -p test 3laho3y3.mirror.aliyuncs.com" # double login for memory leak check - isula login -u test -p test hub-mirror.c.163.com - fn_check_eq "$?" "0" "isula login -u test -p test hub-mirror.c.163.com" + isula login -u test -p test 3laho3y3.mirror.aliyuncs.com + fn_check_eq "$?" "0" "isula login -u test -p test 3laho3y3.mirror.aliyuncs.com" # use username/password to pull busybox for memmory leak check isula pull busybox @@ -84,12 +84,12 @@ function isula_login() function isula_logout() { - isula logout hub-mirror.c.163.com - fn_check_eq "$?" "0" "isula logout hub-mirror.c.163.com" + isula logout 3laho3y3.mirror.aliyuncs.com + fn_check_eq "$?" "0" "isula logout 3laho3y3.mirror.aliyuncs.com" # double logout for memory leak check - isula logout hub-mirror.c.163.com - fn_check_eq "$?" "0" "isula logout hub-mirror.c.163.com" + isula logout 3laho3y3.mirror.aliyuncs.com + fn_check_eq "$?" "0" "isula logout 3laho3y3.mirror.aliyuncs.com" } function do_test_t() diff --git a/CMakeLists.txt b/CMakeLists.txt index 7226ba9..94cc244 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,7 +9,7 @@ include(cmake/set_build_flags.cmake) #set(CMAKE_C_COMPILER "gcc" CACHE PATH "c compiler") -set(GIT_COMMIT_HASH "f84000843bf2ba98adea547721b235e3b77168e1") +set(GIT_COMMIT_HASH "375d59895aab13dc8d6606e2764783a2d4b9d161") message("-- commit id: " ${GIT_COMMIT_HASH}) add_definitions(-DISULAD_GIT_COMMIT="${GIT_COMMIT_HASH}") @@ -89,16 +89,6 @@ ENDIF(ENABLE_UT) # install all files install(FILES ${CMAKE_BINARY_DIR}/conf/isulad.pc DESTINATION ${LIB_INSTALL_DIR_DEFAULT}/pkgconfig PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ GROUP_WRITE) -install(FILES src/client/libisula.h - DESTINATION include/isulad) -install(FILES src/client/connect/isula_connect.h - DESTINATION include/isulad) -install(FILES src/utils/cutils/utils_timestamp.h - DESTINATION include/isulad) -install(FILES src/utils/cutils/error.h - DESTINATION include/isulad) -install(FILES src/daemon/modules/runtime/engines/engine.h - DESTINATION include/isulad) install(FILES src/daemon/modules/api/image_api.h DESTINATION include/isulad) diff --git a/Dockerfile b/Dockerfile index d65e355..20e714c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,7 +8,7 @@ # - IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR # - PURPOSE. # - See the Mulan PSL v2 for more details. -##- @Description: prepare compile container envrionment +##- @Description: prepare compile container environment ##- @Author: lifeng ##- @Create: 2020-01-10 ####################################################################### diff --git a/README.md b/README.md index 934f6ee..08467dd 100644 --- a/README.md +++ b/README.md @@ -9,13 +9,24 @@ ### Installing To install iSulad, you can use `rpm` or `yum` package manager command with `openEuler` repository. -Install iSulad with yum +Or write repository file by hand: + +```sh +cat << EOF > /etc/yum.repos.d/openEuler.repo +[openEuler] +baseurl=https://repo.openeuler.org/openEuler-20.03-LTS/OS/\$basearch +enabled=1 +EOF +``` + +Install iSulad with yum: + ```sh yum install -y iSulad ``` ### Run -We provide `systemd` service to start `iSulad` +We provide `systemd` service to start `iSulad`: ```sh systemctl start isulad # run the server with systemd command ``` @@ -25,43 +36,51 @@ You can use direct command to start `iSulad` server: $ sudo isulad # run the server with default socket name and default log level and images manage function ``` ### Operations on containers: -`iSulad` provides command line `isulad` to talk with server. -Here are some sample commands to manager containers. -List all containers in your own environment: -```sh -# list containers -$ sudo isula ps -a -``` +For more informations on how to use `iSulad`, please refer to the [guide](https://openeuler.org/en/docs/20.03_LTS/docs/Container/isulad-container-engine.html) -Create a container with busybox named `test` -```sh -# create a container 'test' with image busybox -$ sudo isula create -t -n test busybox -``` +`iSulad` provides two operate interfaces to manager images and containers. + +- CLI, `iSulad` provides `isula` as client CLI + + Here are some sample commands to manager containers. + + List all containers in your own environment: + ```sh + # list containers + $ sudo isula ps -a + ``` + + Create a container with busybox named `test`: + ```sh + # create a container 'test' with image busybox + $ sudo isula create -t -n test busybox + ``` + + Start this container `test`: + ```sh + # start the container 'test' + $ sudo isula start test + ``` + Kill the container `test`: + ```sh + # kill the container 'test': + $ sudo isula kill test + ``` + Remove the container `test`: + ```sh + # remove the container 'test' + $ sudo isula rm test + ``` + +- CRI interface, `iSulad` can be integrated with `kubernetes` through CRI interface + + How to integrate with `kubernetes` please refer to [integration.md](./docs/integration.md) -Start this container `test` -```sh -# start the container 'test' -$ sudo isula start test -``` -Kill the container `test` -```sh -# kill the container 'test' -$ sudo isula kill test -``` -Remove the container `test` -```sh -# remove the container 'test' -$ sudo isula rm test -``` ### Build from source Build requirements for developers are listed in [build_guide](./docs/build_guide.md) -### Integration -Integrate with `kubernetes` are listed in [integration.md](./docs/integration.md) - ## Performance #### Machine configuration @@ -79,7 +98,7 @@ ARM machine: | Configuration | Information | | ------------- | ------------- | -| OS | Euleros | +| OS | openEuler | | Kernel | linux 4.19.90 | | CPU | 64 cores | | Memory | 196 GB | diff --git a/cmake/checker.cmake b/cmake/checker.cmake index 112fb17..5ba4c63 100644 --- a/cmake/checker.cmake +++ b/cmake/checker.cmake @@ -90,13 +90,15 @@ find_library(CURL_LIBRARY curl HINTS ${PC_CURL_LIBDIR} ${PC_CURL_LIBRARY_DIRS}) _CHECK(CURL_LIBRARY "CURL_LIBRARY-NOTFOUND" "libcurl.so") -pkg_check_modules(PC_SELINUX "libselinux>=2.0") -find_path(SELINUX_INCLUDE_DIR "selinux/selinux.h" - HINTS ${PC_SELINUX_INCLUDEDIR} ${PC_SELINUX_INCLUDE_DIRS}) -_CHECK(SELINUX_INCLUDE_DIR "SELINUX_INCLUDE_DIR-NOTFOUND" "selinux/selinux.h") -find_library(SELINUX_LIBRARY selinux - HINTS ${PC_SELINUX_LIBDIR} ${PC_SELINUX_LIBRARY_DIRS}) -_CHECK(SELINUX_LIBRARY "SELINUX_LIBRARY-NOTFOUND" "libselinux.so") +if (ENABLE_SELINUX) + pkg_check_modules(PC_SELINUX "libselinux>=2.0") + find_path(SELINUX_INCLUDE_DIR "selinux/selinux.h" + HINTS ${PC_SELINUX_INCLUDEDIR} ${PC_SELINUX_INCLUDE_DIRS}) + _CHECK(SELINUX_INCLUDE_DIR "SELINUX_INCLUDE_DIR-NOTFOUND" "selinux/selinux.h") + find_library(SELINUX_LIBRARY selinux + HINTS ${PC_SELINUX_LIBDIR} ${PC_SELINUX_LIBRARY_DIRS}) + _CHECK(SELINUX_LIBRARY "SELINUX_LIBRARY-NOTFOUND" "libselinux.so") +endif() # check iSula libutils pkg_check_modules(PC_ISULA_LIBUTILS REQUIRED "lcr") diff --git a/cmake/options.cmake b/cmake/options.cmake index d8f5824..e0a2a33 100644 --- a/cmake/options.cmake +++ b/cmake/options.cmake @@ -33,7 +33,7 @@ endif() option(VERSION "set isulad version" ON) if (VERSION STREQUAL "ON") - set(ISULAD_VERSION "2.0.5") + set(ISULAD_VERSION "2.0.6") endif() option(DEBUG "set isulad gcc option" ON) @@ -60,3 +60,10 @@ if (ENABLE_EMBEDDED STREQUAL "ON") add_definitions(-DENABLE_EMBEDDED_IMAGE=1) set(ENABLE_EMBEDDED_IMAGE 1) endif() + +option(ENABLE_SELINUX "enable isulad daemon selinux option" ON) +if (ENABLE_SELINUX STREQUAL "ON") + add_definitions(-DENABLE_SELINUX=1) + set(ENABLE_SELINUX 1) +endif() + diff --git a/docs/build_guide.md b/docs/build_guide.md index b401bb5..912139f 100644 --- a/docs/build_guide.md +++ b/docs/build_guide.md @@ -19,6 +19,10 @@ $ sudo apt install -y libtool automake autoconf cmake make pkg-config libyajl-de ## Build and install other dependencies from source These dependencies may not be provided by your package manager. So you need to build them from source. +Please use the protobuf and grpc came with your distribution, if not exists then need to build them from source. + +Note: grpc-1.22 can not support GCC 9+. + ### set ldconfig and pkgconfig ``` $ export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH @@ -93,7 +97,7 @@ $ sudo -E make install $ sudo -E ldconfig ``` -## Build and install specific versions dependencies from source +## Build and install specific versions dependencies from source iSulad depend on some specific versions dependencies. ### build and install lxc diff --git a/iSulad.spec b/iSulad.spec index 25baadc..35bd125 100644 --- a/iSulad.spec +++ b/iSulad.spec @@ -1,5 +1,5 @@ -%global _version 2.0.5 -%global _release 20200903.171615.gitf8400084 +%global _version 2.0.6 +%global _release 20201014.143412.git375d5989 %global is_systemd 1 Name: iSulad @@ -74,13 +74,11 @@ install -d $RPM_BUILD_ROOT/%{_bindir} install -m 0755 ./src/isula %{buildroot}/%{_bindir}/isula install -m 0755 ./src/isulad-shim %{buildroot}/%{_bindir}/isulad-shim install -m 0755 ./src/isulad %{buildroot}/%{_bindir}/isulad +chrpath -d ./src/isula +chrpath -d ./src/isulad-shim +chrpath -d ./src/isulad install -d $RPM_BUILD_ROOT/%{_includedir}/isulad -install -m 0644 ../src/client/libisula.h %{buildroot}/%{_includedir}/isulad/libisula.h -install -m 0644 ../src/client/connect/isula_connect.h %{buildroot}/%{_includedir}/isulad/isula_connect.h -install -m 0644 ../src/utils/cutils/utils_timestamp.h %{buildroot}/%{_includedir}/isulad/utils_timestamp.h -install -m 0644 ../src/utils/cutils/error.h %{buildroot}/%{_includedir}/isulad/error.h -install -m 0644 ../src/daemon/modules/runtime/engines/engine.h %{buildroot}/%{_includedir}/isulad/engine.h install -m 0644 ../src/daemon/modules/api/image_api.h %{buildroot}/%{_includedir}/isulad/image_api.h install -d $RPM_BUILD_ROOT/%{_sysconfdir}/isulad @@ -127,8 +125,8 @@ fi fi %post -if ! getent group isulad > /dev/null; then - groupadd --system isulad +if ! getent group isula > /dev/null; then + groupadd --system isula fi if [ "$1" = "1" ]; then @@ -159,8 +157,8 @@ fi %endif fi -if ! getent group isulad > /dev/null; then - groupadd --system isulad +if ! getent group isula > /dev/null; then + groupadd --system isula fi %preun @@ -215,6 +213,12 @@ fi %endif %changelog +* Tue Sep 10 2020 openEuler Buildteam - 2.0.5-20200910.140350.git72990229 +- Type:enhancement +- ID:NA +- SUG:NA +- DESC: add chrpath + * Mon Aug 03 2020 openEuler Buildteam - 2.0.3-20200803.130854.git0c7dc28a - Type:enhancement - ID:NA diff --git a/release_notes b/release_notes index 2913d63..2789c97 100644 --- a/release_notes +++ b/release_notes @@ -1,3 +1,65 @@ +2020-10-14 lifeng release 2.0.6 + - !764 add CI for image load multiplex From: @gaohuatao Reviewed-by: @lifeng2221dd1 Signed-off-by: @lifeng2221dd1 + - !765 clean code: refact utils and add prefix util_ From: @lifeng2221dd1 Reviewed-by: @duguhaotian Signed-off-by: @duguhaotian + - !756 iSulad: isula load support layer reusing From: @gaohuatao Reviewed-by: Signed-off-by: + - !762 resize: refact client resize From: @lifeng2221dd1 Reviewed-by: @duguhaotian Signed-off-by: @duguhaotian + - !759 clean code: reduce redundant code in isula_host_spec.c From: @lifeng2221dd1 Reviewed-by: @duguhaotian Signed-off-by: @duguhaotian + - !760 fix load only part of certs error From: @wangfengtu Reviewed-by: @lifeng2221dd1 Signed-off-by: @lifeng2221dd1 + - !757 layer: fix memory leak errors From: @lifeng2221dd1 Reviewed-by: @duguhaotian Signed-off-by: @duguhaotian + - !755 avoid using HEAD_ONLY option when pulling image From: @wangfengtu Reviewed-by: @lifeng2221dd1 Signed-off-by: @lifeng2221dd1 + - !754 use reference count to avoid flag be cleared by mistake From: @wangfengtu Reviewed-by: @lifeng2221dd1 Signed-off-by: @lifeng2221dd1 + - !749 refact: refact client pack config progress From: @lifeng2221dd1 Reviewed-by: @duguhaotian Signed-off-by: @duguhaotian + - !750 modify default group value "isulad" to "isula" From: @gaohuatao Reviewed-by: @lifeng2221dd1 Signed-off-by: @lifeng2221dd1 + - !725 iSulad: add isula group From: @gaohuatao Reviewed-by: @jingxiaolu,@lifeng2221dd1 Signed-off-by: @lifeng2221dd1 + - !746 umount: skip umount if rootfs not exist From: @lifeng2221dd1 Reviewed-by: @duguhaotian Signed-off-by: @duguhaotian + - !743 remove dir of rw layer while create failed From: @duguhaotian Reviewed-by: @lifeng2221dd1 Signed-off-by: @lifeng2221dd1 + - !742 fix macro defination conflict with sqlite3.h in openeuler From: @wangfengtu Reviewed-by: @lifeng2221dd1 Signed-off-by: @lifeng2221dd1 + - !741 iSulad: bugfix, convert size_t type to int From: @zh_xiaoyu Reviewed-by: @duguhaotian,@lifeng2221dd1 Signed-off-by: @lifeng2221dd1 + - !740 fix coredump when load image with uid From: @jingwoo Reviewed-by: @duguhaotian Signed-off-by: @duguhaotian + - !739 iSulad: fix memeory out From: @zh_xiaoyu Reviewed-by: @duguhaotian Signed-off-by: @duguhaotian + - !737 Docs/build_guide.md: comment gcc version From: @long-dai Reviewed-by: @lifeng2221dd1 Signed-off-by: @lifeng2221dd1 + - !724 Fix spell issue From: @long-dai Reviewed-by: Signed-off-by: + - !738 Readme: remove useless description From: @lifeng2221dd1 Reviewed-by: @duguhaotian Signed-off-by: @duguhaotian + - !736 Docs: clean up white noise From: @long-dai Reviewed-by: @lifeng2221dd1 Signed-off-by: @lifeng2221dd1 + - !735 pass context to uitls scan subdir From: @duguhaotian Reviewed-by: @lifeng2221dd1 Signed-off-by: @lifeng2221dd1 + - !734 isulad-shim: fix code review issues From: @leizhongkai Reviewed-by: @lifeng2221dd1 Signed-off-by: @lifeng2221dd1 + - !733 improve code From: @duguhaotian Reviewed-by: @lifeng2221dd1 Signed-off-by: @lifeng2221dd1 + - !726 CI: fix spell issue From: @long-dai Reviewed-by: @lifeng2221dd1 Signed-off-by: @lifeng2221dd1 + - !723 README: unify punctuation From: @long-dai Reviewed-by: @lifeng2221dd1,@lifeng2221dd1 Signed-off-by: @lifeng2221dd1,@lifeng2221dd1 + - !731 CI: update registry from 163 to ali From: @lifeng2221dd1 Reviewed-by: @duguhaotian Signed-off-by: @duguhaotian + - !730 fix bugs From: @wangfengtu Reviewed-by: @lifeng2221dd1 Signed-off-by: @lifeng2221dd1 + - !722 README: add openEuler repository From: @long-dai Reviewed-by: @lifeng2221dd1 Signed-off-by: @lifeng2221dd1 + - !721 readme: add refer to openeuler guide From: @lifeng2221dd1 Reviewed-by: @duguhaotian Signed-off-by: @duguhaotian + - !720 clean code: add more log for invalid input From: @lifeng2221dd1 Reviewed-by: @duguhaotian Signed-off-by: @duguhaotian + - !719 fix bad formatting placeholder in http parse module From: @jingwoo Reviewed-by: @duguhaotian,@lifeng2221dd1 Signed-off-by: @lifeng2221dd1 + - !718 fix coredump when pull image with lock ${driver}-image dir From: @jingwoo Reviewed-by: @lifeng2221dd1 Signed-off-by: @lifeng2221dd1 + - !716 fix layer remain caused by hold flag not clean From: @wangfengtu Reviewed-by: @lifeng2221dd1 Signed-off-by: @lifeng2221dd1 + - !717 clear invalid data From: @duguhaotian Reviewed-by: @lifeng2221dd1 Signed-off-by: @lifeng2221dd1 + - !715 add compilation macro isolation for selinux related code From: @jingwoo Reviewed-by: @lifeng2221dd1 Signed-off-by: @lifeng2221dd1 + - !714 fix pull failure caused by link conflict From: @wangfengtu Reviewed-by: @lifeng2221dd1 Signed-off-by: @lifeng2221dd1 + - !713 readme: fix readme From: @lifeng2221dd1 Reviewed-by: @duguhaotian Signed-off-by: @duguhaotian + - !712 config: remove unused config From: @lifeng2221dd1 Reviewed-by: @duguhaotian Signed-off-by: @duguhaotian + - !711 fix code review From: @wangfengtu Reviewed-by: @lifeng2221dd1 Signed-off-by: @lifeng2221dd1 + - !710 fix: delete rootfs dir when rootfs load failed From: @jingwoo Reviewed-by: @lifeng2221dd1 Signed-off-by: @lifeng2221dd1 + - !708 fix: security-opt parsing access out of bounds From: @jingwoo Reviewed-by: @lifeng2221dd1 Signed-off-by: @lifeng2221dd1 + - !709 fix memory leak From: @wangfengtu Reviewed-by: @lifeng2221dd1 Signed-off-by: @lifeng2221dd1 + - !707 dev_cgroup_rule: add support device cgroup rule Merge pull request !707 from lifeng_isula/blk + - !706 iSulad : logs command add option timestamps Merge pull request !706 from YoungJQ/logs + - !705 add chrpath Merge pull request !705 from YoungJQ/logs + - !704 CI: add testcases for nano CPUs Merge pull request !704 from lifeng_isula/blk + - !702 cpus: add support nano cpus Merge pull request !702 from lifeng_isula/blk + - !700 cpu_rt: add support cpurt runtime period Merge pull request !700 from lifeng_isula/blk + - !701 iSulad: add LIB_ISULAD_IMG_SO for libisulad_img.so to avoid func do_integration_of_images_check() Merge pull request !701 from zhangxiaoyu/master + - !699 update readme Merge pull request !699 from haozi007/master + - !698 blkio: add support blk read/write iops Merge pull request !698 from lifeng_isula/blk + - !697 add testcase for --user option Merge pull request !697 from JingWoo/master + - !696 iSulad: initialization buf before readlink() Merge pull request !696 from zhangxiaoyu/master + - !695 overlay: fix magic define error Merge pull request !695 from lifeng_isula/master + + dev stats: + - 228 files changed, 6526 insertions(+), 5324 deletions(-) + - contributors: lifeng68, WangFengTu, wujing, Long Dai, haozi007, gaohuatao, zhangxiaoyu, YoungJQ, leizhongkai + 2020-09-03 lifeng release 2.0.5 - !693 Set mount rootfs highest mode Merge pull request !693 from gaohuatao/update - !692 log: fix log level to warn Merge pull request !692 from lifeng_isula/master diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2158658..4127e5a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -145,9 +145,9 @@ endif() # ------ install binary -------- install(TARGETS libisula - LIBRARY DESTINATION ${LIB_INSTALL_DIR_DEFAULT} PERMISSIONS OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE) + LIBRARY DESTINATION ${LIB_INSTALL_DIR_DEFAULT} PERMISSIONS OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) install(TARGETS isula - RUNTIME DESTINATION bin PERMISSIONS OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE) + RUNTIME DESTINATION bin PERMISSIONS OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) install(TARGETS isulad-shim RUNTIME DESTINATION bin PERMISSIONS OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE) install(TARGETS isulad diff --git a/src/client/connect/CMakeLists.txt b/src/client/connect/CMakeLists.txt index 5289f5b..60a3429 100644 --- a/src/client/connect/CMakeLists.txt +++ b/src/client/connect/CMakeLists.txt @@ -1,6 +1,6 @@ set(local_client_connect_srcs ${CMAKE_CURRENT_SOURCE_DIR}/isula_connect.c - ${CMAKE_CURRENT_SOURCE_DIR}/pack_config.c + ${CMAKE_CURRENT_SOURCE_DIR}/protocol_type.c ) set(local_client_connect_incs ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/src/client/connect/grpc/grpc_containers_client.cc b/src/client/connect/grpc/grpc_containers_client.cc index fa0d7e4..e511a6a 100644 --- a/src/client/connect/grpc/grpc_containers_client.cc +++ b/src/client/connect/grpc/grpc_containers_client.cc @@ -18,7 +18,6 @@ #include "isula_libutils/container_copy_to_request.h" #include "isula_libutils/container_exec_request.h" #include "isulad_tar.h" -#include "pack_config.h" #include "stoppable_thread.h" #include "utils.h" #include @@ -173,10 +172,6 @@ public: auto request_to_grpc(const isula_create_request *request, CreateRequest *grequest) -> int override { - int ret = 0; - char *host_json = nullptr; - char *config_json = nullptr; - if (request == nullptr) { return -1; } @@ -193,23 +188,14 @@ public: if (request->runtime != nullptr) { grequest->set_runtime(request->runtime); } - ret = generate_hostconfig(request->hostconfig, &host_json); - if (ret != 0) { - ERROR("Failed to pack host config"); - return EINVALIDARGS; - } - grequest->set_hostconfig(host_json); - free(host_json); - - ret = generate_container_config(request->config, &config_json); - if (ret != 0) { - ERROR("Failed to pack custom config"); - return EINVALIDARGS; + if (request->container_spec_json != NULL) { + grequest->set_customconfig(request->container_spec_json); } - grequest->set_customconfig(config_json); - free(config_json); + if (request->host_spec_json != NULL) { + grequest->set_hostconfig(request->host_spec_json); + } return 0; } @@ -697,7 +683,6 @@ public: } }; - class ContainerRestart : public ClientBase { public: @@ -1082,8 +1067,8 @@ public: return 0; } - auto grpc_call(ClientContext *context, const InspectContainerRequest &req, - InspectContainerResponse *reply) -> Status override + auto grpc_call(ClientContext *context, const InspectContainerRequest &req, InspectContainerResponse *reply) + -> Status override { return stub_->Inspect(context, req, reply); } @@ -1186,8 +1171,8 @@ public: ERROR("Too many summary info!"); return -1; } - response->container_summary = static_cast(util_common_calloc_s( - sizeof(struct isula_container_summary_info *) * static_cast(num))); + response->container_summary = static_cast( + util_common_calloc_s(sizeof(struct isula_container_summary_info *) * static_cast(num))); if (response->container_summary == nullptr) { ERROR("out of memory"); response->cc = ISULAD_ERR_MEMOUT; @@ -1209,10 +1194,11 @@ public: } private: - static auto get_container_summary_from_grpc(isula_list_response *response, ListResponse *gresponse, int index) -> int + static auto get_container_summary_from_grpc(isula_list_response *response, ListResponse *gresponse, int index) + -> int { - response->container_summary[index] = - static_cast(util_common_calloc_s(sizeof(struct isula_container_summary_info))); + response->container_summary[index] = static_cast( + util_common_calloc_s(sizeof(struct isula_container_summary_info))); if (response->container_summary[index] == nullptr) { ERROR("out of memory"); response->cc = ISULAD_ERR_MEMOUT; @@ -1224,15 +1210,15 @@ private: response->container_summary[index]->id = util_strdup_s(id); const char *name = !in.name().empty() ? in.name().c_str() : "-"; response->container_summary[index]->name = util_strdup_s(name); - response->container_summary[index]->runtime = !in.runtime().empty() ? util_strdup_s(in.runtime().c_str()) - : nullptr; + response->container_summary[index]->runtime = !in.runtime().empty() ? util_strdup_s(in.runtime().c_str()) : + nullptr; response->container_summary[index]->has_pid = static_cast(static_cast(in.pid()) != 0); response->container_summary[index]->pid = static_cast(in.pid()); response->container_summary[index]->status = static_cast(in.status()); - response->container_summary[index]->image = !in.image().empty() ? util_strdup_s(in.image().c_str()) - : util_strdup_s("none"); - response->container_summary[index]->command = !in.command().empty() ? util_strdup_s(in.command().c_str()) - : util_strdup_s("-"); + response->container_summary[index]->image = !in.image().empty() ? util_strdup_s(in.image().c_str()) : + util_strdup_s("none"); + response->container_summary[index]->command = !in.command().empty() ? util_strdup_s(in.command().c_str()) : + util_strdup_s("-"); const char *starttime = !in.startat().empty() ? in.startat().c_str() : "-"; response->container_summary[index]->startat = util_strdup_s(starttime); @@ -1246,8 +1232,8 @@ private: if (!in.health_state().empty()) { healthState = "(" + in.health_state() + ")"; } - response->container_summary[index]->health_state = !healthState.empty() ? util_strdup_s(healthState.c_str()) - : nullptr; + response->container_summary[index]->health_state = !healthState.empty() ? util_strdup_s(healthState.c_str()) : + nullptr; response->container_num++; return 0; @@ -1604,33 +1590,18 @@ public: auto request_to_grpc(const isula_update_request *request, UpdateRequest *grequest) -> int override { int ret = 0; - char *json = nullptr; if (request == nullptr) { return -1; } - isula_host_config_t hostconfig; - (void)memset(&hostconfig, 0, sizeof(hostconfig)); - - if (request->updateconfig != nullptr) { - hostconfig.restart_policy = request->updateconfig->restart_policy; - hostconfig.cr = request->updateconfig->cr; - } - ret = generate_hostconfig(&hostconfig, &json); - if (ret != 0) { - ERROR("Failed to generate hostconfig json"); - ret = -1; - goto cleanup; + if (request->host_spec_json != NULL) { + grequest->set_hostconfig(request->host_spec_json); } - - grequest->set_hostconfig(json); if (request->name != nullptr) { grequest->set_id(request->name); } -cleanup: - free(json); return ret; } @@ -1688,8 +1659,8 @@ public: { int size = gresponse->containers_size(); if (size > 0) { - response->container_stats = - static_cast(util_common_calloc_s(size * sizeof(struct isula_container_info))); + response->container_stats = static_cast( + util_common_calloc_s(size * sizeof(struct isula_container_info))); if (response->container_stats == nullptr) { ERROR("Out of memory"); return -1; @@ -1771,7 +1742,8 @@ public: std::unique_ptr> reader(stub_->Events(&context, req)); while (reader->Read(&event)) { - isula_event = static_cast(util_common_calloc_s(sizeof(container_events_format_t))); + isula_event = + static_cast(util_common_calloc_s(sizeof(container_events_format_t))); if (isula_event == nullptr) { ERROR("Out of memory"); response->server_errono = ISULAD_ERR_EXEC; @@ -1863,7 +1835,7 @@ private: struct CopyFromContainerContext { CopyFromContainerRequest request; ClientContext context; - ClientReader *reader{}; + ClientReader *reader {}; }; // Note: len of buf can not smaller than ARCHIVE_BLOCK_SIZE @@ -2008,7 +1980,8 @@ public: explicit CopyToContainerWriteToServerTask( const struct io_read_wrapper *reader, std::shared_ptr> stream) - : m_reader(reader), m_stream(std::move(std::move(stream))) + : m_reader(reader) + , m_stream(std::move(std::move(stream))) { } ~CopyToContainerWriteToServerTask() = default; @@ -2026,7 +1999,7 @@ public: while (!stopRequested()) { ssize_t have_read_len = m_reader->read(m_reader->context, buf, len); CopyToContainerRequest request; - request.set_data((const void*)buf, static_cast(have_read_len)); + request.set_data((const void *)buf, static_cast(have_read_len)); if (!m_stream->Write(request)) { DEBUG("Server may be exited, stop send data"); break; @@ -2095,9 +2068,8 @@ out: return ret; } - auto run(const struct isula_copy_to_container_request *request, - struct isula_copy_to_container_response *response) -> int - override + auto run(const struct isula_copy_to_container_request *request, struct isula_copy_to_container_response *response) + -> int override { ClientContext context; if (set_custom_header_metadata(context, request, response) != 0) { @@ -2262,4 +2234,3 @@ auto grpc_containers_client_ops_init(isula_connect_ops *ops) -> int return 0; } - diff --git a/src/client/connect/isula_connect.h b/src/client/connect/isula_connect.h index 8e9fed5..a24336d 100644 --- a/src/client/connect/isula_connect.h +++ b/src/client/connect/isula_connect.h @@ -15,8 +15,8 @@ #ifndef CLIENT_CONNECT_ISULA_CONNECT_H #define CLIENT_CONNECT_ISULA_CONNECT_H -#include "libisula.h" #include "connect.h" +#include "protocol_type.h" #ifdef __cplusplus extern "C" { diff --git a/src/client/libisula.c b/src/client/connect/protocol_type.c similarity index 84% rename from src/client/libisula.c rename to src/client/connect/protocol_type.c index 12b7ac5..19310a0 100644 --- a/src/client/libisula.c +++ b/src/client/connect/protocol_type.c @@ -8,17 +8,16 @@ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR * PURPOSE. * See the Mulan PSL v2 for more details. - * Author: tanyifeng - * Create: 2018-11-08 + * Author: lifeng + * Create: 2020-10-12 * Description: provide container isula library functions ******************************************************************************/ +#include "protocol_type.h" #include #include -#include #include #include -#include "libisula.h" #include "isula_libutils/log.h" #include "utils.h" #include "utils_array.h" @@ -93,7 +92,7 @@ struct isula_filters *isula_filters_parse_args(const char **array, size_t len) } *valuepos++ = '\0'; filters->values[filters->len] = util_strdup_s(util_trim_space(valuepos)); - lowerkey = strings_to_lower(util_trim_space(copy)); + lowerkey = util_strings_to_lower(util_trim_space(copy)); free(copy); if (lowerkey == NULL) { free(filters->values[filters->len]); @@ -227,157 +226,6 @@ void isula_info_response_free(struct isula_info_response *response) free(response); } -void isula_ns_change_files_free(isula_host_config_t *hostconfig) -{ - if (hostconfig == NULL) { - return; - } - - util_free_array_by_len(hostconfig->ns_change_files, hostconfig->ns_change_files_len); - hostconfig->ns_change_files = NULL; - hostconfig->ns_change_files_len = 0; -} - -void isula_host_config_storage_opts_free(isula_host_config_t *hostconfig) -{ - if (hostconfig == NULL) { - return; - } - - free_json_map_string_string(hostconfig->storage_opts); - hostconfig->storage_opts = NULL; -} - -void isula_host_config_sysctl_free(isula_host_config_t *hostconfig) -{ - if (hostconfig == NULL) { - return; - } - - free_json_map_string_string(hostconfig->sysctls); - hostconfig->sysctls = NULL; -} - -/* isula host config free */ -void isula_host_config_free(isula_host_config_t *hostconfig) -{ - if (hostconfig == NULL) { - return; - } - - util_free_array_by_len(hostconfig->cap_add, hostconfig->cap_add_len); - hostconfig->cap_add = NULL; - hostconfig->cap_add_len = 0; - - util_free_array_by_len(hostconfig->cap_drop, hostconfig->cap_drop_len); - hostconfig->cap_drop = NULL; - hostconfig->cap_drop_len = 0; - - free_json_map_string_string(hostconfig->storage_opts); - hostconfig->storage_opts = NULL; - - free_json_map_string_string(hostconfig->sysctls); - hostconfig->sysctls = NULL; - - util_free_array_by_len(hostconfig->devices, hostconfig->devices_len); - hostconfig->devices = NULL; - hostconfig->devices_len = 0; - - util_free_array_by_len(hostconfig->hugetlbs, hostconfig->hugetlbs_len); - hostconfig->hugetlbs = NULL; - hostconfig->hugetlbs_len = 0; - - free(hostconfig->network_mode); - hostconfig->network_mode = NULL; - - free(hostconfig->ipc_mode); - hostconfig->ipc_mode = NULL; - - free(hostconfig->pid_mode); - hostconfig->pid_mode = NULL; - - free(hostconfig->uts_mode); - hostconfig->uts_mode = NULL; - - free(hostconfig->userns_mode); - hostconfig->userns_mode = NULL; - - free(hostconfig->user_remap); - hostconfig->user_remap = NULL; - - util_free_array_by_len(hostconfig->ulimits, hostconfig->ulimits_len); - hostconfig->ulimits = NULL; - hostconfig->ulimits_len = 0; - - free(hostconfig->restart_policy); - hostconfig->restart_policy = NULL; - - free(hostconfig->host_channel); - hostconfig->host_channel = NULL; - - free(hostconfig->hook_spec); - hostconfig->hook_spec = NULL; - - free(hostconfig->env_target_file); - hostconfig->env_target_file = NULL; - - free(hostconfig->cgroup_parent); - hostconfig->cgroup_parent = NULL; - - util_free_array_by_len(hostconfig->binds, hostconfig->binds_len); - hostconfig->binds = NULL; - hostconfig->binds_len = 0; - - util_free_array_by_len(hostconfig->blkio_weight_device, hostconfig->blkio_weight_device_len); - hostconfig->blkio_weight_device = NULL; - hostconfig->blkio_weight_device_len = 0; - - container_cgroup_resources_free(hostconfig->cr); - hostconfig->cr = NULL; - - free(hostconfig); -} - -/* isula container config free */ -void isula_container_config_free(isula_container_config_t *config) -{ - if (config == NULL) { - return; - } - - util_free_array_by_len(config->env, config->env_len); - config->env = NULL; - config->env_len = 0; - - free(config->hostname); - config->hostname = NULL; - - free(config->user); - config->user = NULL; - - util_free_array_by_len(config->mounts, config->mounts_len); - config->mounts = NULL; - config->mounts_len = 0; - - util_free_array_by_len(config->cmd, config->cmd_len); - config->cmd = NULL; - config->cmd_len = 0; - - free(config->entrypoint); - config->entrypoint = NULL; - - free(config->log_driver); - config->log_driver = NULL; - - free_json_map_string_string(config->annotations); - config->annotations = NULL; - - free(config->workdir); - config->workdir = NULL; - - free(config); -} - /* isula create request free */ void isula_create_request_free(struct isula_create_request *request) { @@ -397,11 +245,12 @@ void isula_create_request_free(struct isula_create_request *request) free(request->runtime); request->runtime = NULL; - isula_host_config_free(request->hostconfig); - request->hostconfig = NULL; + free(request->container_spec_json); + request->container_spec_json = NULL; + + free(request->host_spec_json); + request->host_spec_json = NULL; - isula_container_config_free(request->config); - request->config = NULL; free(request); } @@ -489,6 +338,9 @@ void isula_top_response_free(struct isula_top_response *response) free(response->titles); response->titles = NULL; + free(response->errmsg); + response->errmsg = NULL; + if (response->processes_len && response->processes != NULL) { size_t i; for (i = 0; i < response->processes_len; i++) { @@ -806,22 +658,6 @@ void isula_kill_response_free(struct isula_kill_response *response) free(response); } -/* isula update config free */ -void isula_update_config_free(isula_update_config_t *config) -{ - if (config == NULL) { - return; - } - - free(config->restart_policy); - config->restart_policy = NULL; - - container_cgroup_resources_free(config->cr); - config->cr = NULL; - - free(config); -} - /* isula update request free */ void isula_update_request_free(struct isula_update_request *request) { @@ -832,8 +668,8 @@ void isula_update_request_free(struct isula_update_request *request) free(request->name); request->name = NULL; - isula_update_config_free(request->updateconfig); - request->updateconfig = NULL; + free(request->host_spec_json); + request->host_spec_json = NULL; free(request); } @@ -1453,21 +1289,6 @@ void isula_logs_response_free(struct isula_logs_response *response) free(response); } -/* container cgroup resources free */ -void container_cgroup_resources_free(container_cgroup_resources_t *cr) -{ - if (cr == NULL) { - return; - } - free(cr->cpuset_cpus); - cr->cpuset_cpus = NULL; - - free(cr->cpuset_mems); - cr->cpuset_mems = NULL; - - free(cr); -} - void container_events_format_free(container_events_format_t *value) { size_t i; @@ -1491,4 +1312,4 @@ void container_events_format_free(container_events_format_t *value) value->annotations = NULL; free(value); -} \ No newline at end of file +} diff --git a/src/client/libisula.h b/src/client/connect/protocol_type.h similarity index 80% rename from src/client/libisula.h rename to src/client/connect/protocol_type.h index 62954f9..f8f18c0 100644 --- a/src/client/libisula.h +++ b/src/client/connect/protocol_type.h @@ -8,12 +8,12 @@ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR * PURPOSE. * See the Mulan PSL v2 for more details. - * Author: tanyifeng - * Create: 2018-11-08 - * Description: provide container isula library definition + * Author: lifeng + * Create: 2020-10-12 + * Description: provide container isula protocol definition ******************************************************************************/ -#ifndef CLIENT_LIBISULA_H -#define CLIENT_LIBISULA_H +#ifndef CLIENT_CONNECT_PROTOCOL_H +#define CLIENT_CONNECT_PROTOCOL_H #include #include @@ -22,7 +22,6 @@ #include "constants.h" #include "io_wrapper.h" #include "isula_libutils/container_path_stat.h" -#include "isula_libutils/json_common.h" #include "utils_timestamp.h" #ifdef __cplusplus @@ -35,179 +34,13 @@ struct isula_filters { size_t len; }; -typedef struct isula_container_config { - char **env; - size_t env_len; - - char **label; - size_t label_len; - - char *hostname; - - char *user; - - bool attach_stdin; - - bool attach_stdout; - - bool attach_stderr; - - bool open_stdin; - - bool tty; - - bool readonly; - - bool all_devices; - - bool system_container; - char *ns_change_opt; - - char **mounts; - size_t mounts_len; - - char *entrypoint; - - char **cmd; - size_t cmd_len; - - char *log_driver; - - json_map_string_string *annotations; - - char *workdir; - - char *health_cmd; - - int64_t health_interval; - - int health_retries; - - int64_t health_timeout; - - int64_t health_start_period; - - bool no_healthcheck; - - bool exit_on_unhealthy; - - char **accel; - size_t accel_len; -} isula_container_config_t; - -typedef struct container_cgroup_resources { - uint16_t blkio_weight; - int64_t cpu_shares; - int64_t cpu_period; - int64_t cpu_quota; - int64_t cpu_realtime_period; - int64_t cpu_realtime_runtime; - char *cpuset_cpus; - char *cpuset_mems; - int64_t memory; - int64_t memory_swap; - int64_t memory_reservation; - int64_t kernel_memory; - int64_t pids_limit; - int64_t files_limit; - int64_t oom_score_adj; - int64_t swappiness; -} container_cgroup_resources_t; - -typedef struct isula_host_config { - char **devices; - size_t devices_len; - - char **hugetlbs; - size_t hugetlbs_len; - - char **group_add; - size_t group_add_len; - - char *network_mode; - - char *ipc_mode; - - char *pid_mode; - - char *uts_mode; - - char *userns_mode; - - char *user_remap; - - char **ulimits; - size_t ulimits_len; - - char *restart_policy; - - char *host_channel; - - char **cap_add; - size_t cap_add_len; - - char **cap_drop; - size_t cap_drop_len; - - json_map_string_string *storage_opts; - - json_map_string_string *sysctls; - - char **dns; - size_t dns_len; - - char **dns_options; - size_t dns_options_len; - - char **dns_search; - size_t dns_search_len; - - char **extra_hosts; - size_t extra_hosts_len; - - char *hook_spec; - - char **binds; - size_t binds_len; - - char **blkio_weight_device; - size_t blkio_weight_device_len; - - char **blkio_throttle_read_bps_device; - size_t blkio_throttle_read_bps_device_len; - - char **blkio_throttle_write_bps_device; - size_t blkio_throttle_write_bps_device_len; - - bool privileged; - bool system_container; - char **ns_change_files; - size_t ns_change_files_len; - bool auto_remove; - - bool oom_kill_disable; - - int64_t shm_size; - - bool readonly_rootfs; - - char *env_target_file; - - char *cgroup_parent; - - container_cgroup_resources_t *cr; - - char **security; - size_t security_len; -} isula_host_config_t; - struct isula_create_request { char *name; char *rootfs; char *image; char *runtime; - isula_host_config_t *hostconfig; - isula_container_config_t *config; + char *host_spec_json; + char *container_spec_json; }; struct isula_create_response { @@ -576,14 +409,9 @@ struct isula_info_response { char *errmsg; }; -typedef struct isula_update_config { - char *restart_policy; - container_cgroup_resources_t *cr; -} isula_update_config_t; - struct isula_update_request { char *name; - isula_update_config_t *updateconfig; + char *host_spec_json; }; struct isula_update_response { @@ -747,12 +575,8 @@ struct isula_resize_response { char *errmsg; }; -void container_cgroup_resources_free(container_cgroup_resources_t *cr); - void container_events_format_free(container_events_format_t *value); -Container_Status isulastastr2sta(const char *state); - struct isula_filters *isula_filters_parse_args(const char **array, size_t len); void isula_filters_free(struct isula_filters *filters); @@ -767,16 +591,6 @@ void isula_info_request_free(struct isula_info_request *request); void isula_info_response_free(struct isula_info_response *response); -void isula_ns_change_files_free(isula_host_config_t *hostconfig); - -void isula_host_config_storage_opts_free(isula_host_config_t *hostconfig); - -void isula_host_config_sysctl_free(isula_host_config_t *hostconfig); - -void isula_host_config_free(isula_host_config_t *hostconfig); - -void isula_container_config_free(isula_container_config_t *config); - void isula_create_request_free(struct isula_create_request *request); void isula_create_response_free(struct isula_create_response *response); @@ -825,8 +639,6 @@ void isula_kill_request_free(struct isula_kill_request *request); void isula_kill_response_free(struct isula_kill_response *response); -void isula_update_config_free(isula_update_config_t *config); - void isula_update_request_free(struct isula_update_request *request); void isula_update_response_free(struct isula_update_response *response); diff --git a/src/client/connect/rest/rest_containers_client.c b/src/client/connect/rest/rest_containers_client.c index e697861..3b5918a 100644 --- a/src/client/connect/rest/rest_containers_client.c +++ b/src/client/connect/rest/rest_containers_client.c @@ -18,7 +18,6 @@ #include "isula_libutils/log.h" #include "isula_connect.h" #include "container.rest.h" -#include "pack_config.h" #include "rest_common.h" #include "rest_containers_client.h" @@ -37,18 +36,12 @@ static int create_request_to_rest(const struct isula_create_request *lc_request, goto out; } - ret = generate_hostconfig(lc_request->hostconfig, &crequest->hostconfig); - if (ret != 0) { - ERROR("Failed to pack host config"); - ret = EINVALIDARGS; - goto out; + if (lc_request->host_spec_json != NULL) { + crequest->hostconfig = util_strdup_s(lc_request->host_spec_json); } - ret = generate_container_config(lc_request->config, &crequest->customconfig); - if (ret != 0) { - ERROR("Failed to pack custom config"); - ret = EINVALIDARGS; - goto out; + if (lc_request->container_spec_json != NULL) { + crequest->customconfig = util_strdup_s(lc_request->container_spec_json); } if (lc_request->name != NULL) { @@ -402,29 +395,33 @@ static int unpack_container_info_for_list_response(container_list_response *cres response->container_num = num; response->container_summary = summary_info; for (i = 0; i < num; i++) { - summary_info[i] = - (struct isula_container_summary_info *)util_common_calloc_s(sizeof(struct isula_container_summary_info)); + summary_info[i] = (struct isula_container_summary_info *)util_common_calloc_s( + sizeof(struct isula_container_summary_info)); if (summary_info[i] == NULL) { ERROR("Out of memory"); return -1; } - summary_info[i]->id = cresponse->containers[i]->id ? util_strdup_s(cresponse->containers[i]->id) - : util_strdup_s("-"); - summary_info[i]->name = cresponse->containers[i]->name ? util_strdup_s(cresponse->containers[i]->name) - : util_strdup_s("-"); - summary_info[i]->runtime = cresponse->containers[i]->runtime ? util_strdup_s(cresponse->containers[i]->runtime) - : util_strdup_s("-"); + summary_info[i]->id = cresponse->containers[i]->id ? util_strdup_s(cresponse->containers[i]->id) : + util_strdup_s("-"); + summary_info[i]->name = cresponse->containers[i]->name ? util_strdup_s(cresponse->containers[i]->name) : + util_strdup_s("-"); + summary_info[i]->runtime = cresponse->containers[i]->runtime ? + util_strdup_s(cresponse->containers[i]->runtime) : + util_strdup_s("-"); summary_info[i]->has_pid = cresponse->containers[i]->pid != 0; summary_info[i]->pid = cresponse->containers[i]->pid; summary_info[i]->status = cresponse->containers[i]->status; - summary_info[i]->image = cresponse->containers[i]->image ? util_strdup_s(cresponse->containers[i]->image) - : util_strdup_s("-"); - summary_info[i]->command = cresponse->containers[i]->command ? util_strdup_s(cresponse->containers[i]->command) - : util_strdup_s("-"); - summary_info[i]->startat = cresponse->containers[i]->startat ? util_strdup_s(cresponse->containers[i]->startat) - : util_strdup_s("-"); + summary_info[i]->image = cresponse->containers[i]->image ? util_strdup_s(cresponse->containers[i]->image) : + util_strdup_s("-"); + summary_info[i]->command = cresponse->containers[i]->command ? + util_strdup_s(cresponse->containers[i]->command) : + util_strdup_s("-"); + summary_info[i]->startat = cresponse->containers[i]->startat ? + util_strdup_s(cresponse->containers[i]->startat) : + util_strdup_s("-"); summary_info[i]->finishat = cresponse->containers[i]->finishat ? - util_strdup_s(cresponse->containers[i]->finishat) : util_strdup_s("-"); + util_strdup_s(cresponse->containers[i]->finishat) : + util_strdup_s("-"); summary_info[i]->exit_code = cresponse->containers[i]->exit_code; summary_info[i]->restart_count = (unsigned int)cresponse->containers[i]->restartcount; summary_info[i]->created = cresponse->containers[i]->created; @@ -675,8 +672,8 @@ out: } /* rest container list */ -static int rest_container_list(const struct isula_list_request *ll_request, - struct isula_list_response *ll_response, void *arg) +static int rest_container_list(const struct isula_list_request *ll_request, struct isula_list_response *ll_response, + void *arg) { char *body = NULL; int ret = 0; @@ -741,8 +738,8 @@ out: } /* rest container wait */ -static int rest_container_wait(const struct isula_wait_request *lw_request, - struct isula_wait_response *lw_response, void *arg) +static int rest_container_wait(const struct isula_wait_request *lw_request, struct isula_wait_response *lw_response, + void *arg) { char *body = NULL; int ret = 0; @@ -842,8 +839,8 @@ out: } /* rest container stop */ -static int rest_container_stop(const struct isula_stop_request *ls_request, - struct isula_stop_response *ls_response, void *arg) +static int rest_container_stop(const struct isula_stop_request *ls_request, struct isula_stop_response *ls_response, + void *arg) { char *body = NULL; int ret = 0; @@ -976,14 +973,10 @@ out: static int update_request_to_rest(const struct isula_update_request *lu_request, char **body, size_t *body_len) { container_update_request *crequest = NULL; - isula_host_config_t srcconfig; struct parser_context ctx = { OPT_GEN_SIMPLIFY, 0 }; parser_error err = NULL; - char *srcconfigjson = NULL; int ret = 0; - (void)memset(&srcconfig, 0, sizeof(srcconfig)); - crequest = util_common_calloc_s(sizeof(container_update_request)); if (crequest == NULL) { ERROR("Out of memory"); @@ -991,22 +984,14 @@ static int update_request_to_rest(const struct isula_update_request *lu_request, goto out; } - if (lu_request->updateconfig != NULL) { - srcconfig.restart_policy = lu_request->updateconfig->restart_policy; - srcconfig.cr = lu_request->updateconfig->cr; - } - ret = generate_hostconfig(&srcconfig, &srcconfigjson); - if (ret != 0) { - ERROR("Failed to generate hostconfig json"); - ret = -1; - goto out; - } - crequest->host_config = srcconfigjson; - if (lu_request->name != NULL) { crequest->name = util_strdup_s(lu_request->name); } + if (lu_request->host_spec_json != NULL) { + crequest->host_config = util_strdup_s(lu_request->host_spec_json); + } + *body = container_update_request_generate_json(crequest, &ctx, &err); if (*body == NULL) { ERROR("Failed to generate update request json:%s", err); @@ -1261,8 +1246,8 @@ out: } /* rest container pause */ -static int rest_container_pause(const struct isula_pause_request *lp_request, - struct isula_pause_response *lp_response, void *arg) +static int rest_container_pause(const struct isula_pause_request *lp_request, struct isula_pause_response *lp_response, + void *arg) { char *body = NULL; int ret = 0; @@ -1361,8 +1346,8 @@ out: } /* rest container kill */ -static int rest_container_kill(const struct isula_kill_request *lk_request, - struct isula_kill_response *lk_response, void *arg) +static int rest_container_kill(const struct isula_kill_request *lk_request, struct isula_kill_response *lk_response, + void *arg) { char *body = NULL; int ret = 0; @@ -1716,8 +1701,8 @@ out: } /* rest container exec */ -static int rest_container_exec(const struct isula_exec_request *le_request, - struct isula_exec_response *le_response, void *arg) +static int rest_container_exec(const struct isula_exec_request *le_request, struct isula_exec_response *le_response, + void *arg) { char *body = NULL; int ret = 0; @@ -1773,4 +1758,3 @@ int rest_containers_client_ops_init(isula_connect_ops *ops) return 0; } - diff --git a/src/cmd/CMakeLists.txt b/src/cmd/CMakeLists.txt index 845cb0f..3d3e881 100644 --- a/src/cmd/CMakeLists.txt +++ b/src/cmd/CMakeLists.txt @@ -1,13 +1,15 @@ # get current directory sources files aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} comm_srcs) +add_subdirectory(options) + add_subdirectory(isula) -set(ISULA_SRCS ${comm_srcs} ${CMD_ISULA_SRCS} PARENT_SCOPE) -set(ISULA_INCS ${CMAKE_CURRENT_SOURCE_DIR} ${CMD_ISULA_INCS} PARENT_SCOPE) +set(ISULA_SRCS ${comm_srcs} ${OPT_SRCS} ${CMD_ISULA_SRCS} PARENT_SCOPE) +set(ISULA_INCS ${CMAKE_CURRENT_SOURCE_DIR} ${OPT_INCS} ${CMD_ISULA_INCS} PARENT_SCOPE) add_subdirectory(isulad) -set(ISULAD_SRCS ${comm_srcs} ${CMD_ISULAD_SRCS} PARENT_SCOPE) -set(ISULAD_INCS ${CMAKE_CURRENT_SOURCE_DIR} ${CMD_ISULAD_INCS} PARENT_SCOPE) +set(ISULAD_SRCS ${comm_srcs} ${OPT_SRCS} ${CMD_ISULAD_SRCS} PARENT_SCOPE) +set(ISULAD_INCS ${CMAKE_CURRENT_SOURCE_DIR} ${OPT_INCS} ${CMD_ISULAD_INCS} PARENT_SCOPE) add_subdirectory(isulad-shim) set(ISULAD_SHIM_SRCS ${CMD_ISULAD_SHIM_SRCS} PARENT_SCOPE) diff --git a/src/cmd/command_parser.c b/src/cmd/command_parser.c index 33a1f37..f72c1b4 100644 --- a/src/cmd/command_parser.c +++ b/src/cmd/command_parser.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "constants.h" #include "utils.h" @@ -29,6 +30,7 @@ #include "utils_convert.h" #include "utils_string.h" #include "utils_verify.h" +#include "utils_timestamp.h" void command_help_isulad_head() { @@ -242,7 +244,7 @@ static int command_get_option_data(command_t *self, command_option_t *option, co case CMD_OPT_TYPE_CALLBACK: return command_get_callback_option_data(self, option, opt_arg); default: - COMMAND_ERROR("Unkown command option type:%d", (int)(option->type)); + COMMAND_ERROR("Unknown command option type:%d", (int)(option->type)); return -1; } } @@ -304,7 +306,7 @@ static int command_parse_short_arg(command_t *self, const char *arg) } while (found && opt_arg != NULL); if (opt_arg != NULL) { - COMMAND_ERROR("Unkown flag found:'%c'", opt_arg[0]); + COMMAND_ERROR("Unknown flag found:'%c'", opt_arg[0]); exit(EINVALIDARGS); } return 0; @@ -328,7 +330,7 @@ static int command_parse_long_arg(command_t *self, const char *arg) continue; } - opt_arg = str_skip_str(arg, opt->large); + opt_arg = util_str_skip_str(arg, opt->large); if (opt_arg == NULL) { continue; } @@ -347,7 +349,7 @@ static int command_parse_long_arg(command_t *self, const char *arg) } return 0; } - COMMAND_ERROR("Unkown flag found:'--%s'\n", arg); + COMMAND_ERROR("Unknown flag found:'--%s'\n", arg); exit(EINVALIDARGS); } @@ -501,7 +503,7 @@ int command_convert_nanoseconds(command_option_t *option, const char *arg) if (option == NULL) { return -1; } - if (util_parse_time_str_to_nanoseconds(arg, option->data)) { + if (util_time_str_to_nanoseconds(arg, option->data)) { COMMAND_ERROR("Invalid value \"%s\" for flag --%s", arg, option->large); return EINVALIDARGS; } @@ -551,3 +553,48 @@ int command_convert_swappiness(command_option_t *option, const char *arg) } return 0; } + +int command_convert_nanocpus(command_option_t *option, const char *arg) +{ + int ret = 0; + char *dup = NULL; + + if (option == NULL) { + return -1; + } + + if (!isdigit(arg[0])) { + COMMAND_ERROR("Invalid value \"%s\" for flag --%s", arg, option->large); + return EINVALIDARGS; + } + + dup = util_strdup_s(arg); + if (dup == NULL) { + COMMAND_ERROR("Invalid value \"%s\" for flag --%s", arg, option->large); + return EINVALIDARGS; + } + + if (util_parse_size_int_and_float(arg, 1e9, option->data)) { + COMMAND_ERROR("Invalid value \"%s\" for flag --%s", arg, option->large); + ret = EINVALIDARGS; + goto out; + } + +out: + free(dup); + return ret; +} + +int command_convert_device_cgroup_rules(command_option_t *option, const char *arg) +{ + if (option == NULL) { + return -1; + } + + if (!util_valid_device_cgroup_rule(arg)) { + COMMAND_ERROR("Invalid value \"%s\" for flag --%s", arg, option->large); + return EINVALIDARGS; + } + + return command_append_array(option, arg); +} diff --git a/src/cmd/command_parser.h b/src/cmd/command_parser.h index cdf3e1e..5f4cedc 100644 --- a/src/cmd/command_parser.h +++ b/src/cmd/command_parser.h @@ -100,10 +100,12 @@ int command_convert_membytes(command_option_t *option, const char *arg); int command_convert_memswapbytes(command_option_t *option, const char *arg); -int check_default_ulimit_type(const char *type); - int command_convert_swappiness(command_option_t *option, const char *arg); +int command_convert_nanocpus(command_option_t *option, const char *arg); + +int command_convert_device_cgroup_rules(command_option_t *option, const char *arg); + #ifdef __cplusplus } #endif diff --git a/src/cmd/isula/base/create.c b/src/cmd/isula/base/create.c index 583664a..12903ce 100644 --- a/src/cmd/isula/base/create.c +++ b/src/cmd/isula/base/create.c @@ -12,6 +12,7 @@ * Create: 2017-11-22 * Description: provide container create functions ******************************************************************************/ +#include "create.h" #include #include #include @@ -32,17 +33,18 @@ #include "isula_libutils/log.h" #include "utils.h" #include "utils_string.h" -#include "create.h" #include "isula_connect.h" #include "path.h" #include "pull.h" #include "constants.h" #include "connect.h" -#include "libisula.h" + #include "utils_array.h" #include "utils_convert.h" #include "utils_file.h" #include "utils_verify.h" +#include "isula_container_spec.h" +#include "isula_host_spec.h" const char g_cmd_create_desc[] = "Create a new container"; const char g_cmd_create_usage[] = "create [OPTIONS] --external-rootfs=PATH|IMAGE [COMMAND] [ARG...]"; @@ -142,9 +144,18 @@ static int request_pack_host_config_cgroup(const struct client_arguments *args, return -1; } + hostconfig->cr = util_common_calloc_s(sizeof(container_cgroup_resources_t)); + if (hostconfig->cr == NULL) { + COMMAND_ERROR("Memory out"); + return -1; + } + /* blkio weight */ hostconfig->cr->blkio_weight = args->cr.blkio_weight; + /* nano cpus */ + hostconfig->cr->nano_cpus = args->cr.nano_cpus; + /* cpu shares */ hostconfig->cr->cpu_shares = args->cr.cpu_shares; @@ -161,10 +172,10 @@ static int request_pack_host_config_cgroup(const struct client_arguments *args, hostconfig->cr->cpu_realtime_runtime = args->cr.cpu_rt_runtime; /* cpuset-cpus */ - hostconfig->cr->cpuset_cpus = args->cr.cpuset_cpus; + hostconfig->cr->cpuset_cpus = util_strdup_s(args->cr.cpuset_cpus); /* cpuset memory */ - hostconfig->cr->cpuset_mems = args->cr.cpuset_mems; + hostconfig->cr->cpuset_mems = util_strdup_s(args->cr.cpuset_mems); /* oom_score_adj */ hostconfig->cr->oom_score_adj = args->cr.oom_score_adj; @@ -188,54 +199,7 @@ static int request_pack_host_config_cgroup(const struct client_arguments *args, return 0; } -static int util_env_set_isulad_enable_plugins(char ***penv, const size_t *penv_len, const char *names) -{ - size_t env_len; - size_t len = 0; - char *val = NULL; - char *kv = NULL; - char **env = NULL; - const char *arr[10] = { NULL }; - - if (penv == NULL || penv_len == NULL || names == NULL) { - return -1; - } - - env = *penv; - env_len = *penv_len; - - arr[0] = ISULAD_ENABLE_PLUGINS; - arr[1] = "="; - arr[2] = names; - len = 3; - - val = util_env_get_val(env, env_len, ISULAD_ENABLE_PLUGINS, strlen(ISULAD_ENABLE_PLUGINS)); - if (val != NULL && strlen(val) != 0) { - arr[3] = ISULAD_ENABLE_PLUGINS_SEPERATOR; - arr[4] = val; - len = 5; - } - - kv = util_string_join("", arr, len); - if (kv == NULL) { - goto failed; - } - - if (util_env_set_val(penv, penv_len, ISULAD_ENABLE_PLUGINS, strlen(ISULAD_ENABLE_PLUGINS), kv)) { - goto failed; - } - - free(val); - free(kv); - return 0; - -failed: - free(val); - free(kv); - return -1; -} - -static int request_pack_custom_env(struct client_arguments *args, isula_container_config_t *conf) +static int request_pack_custom_env(const struct client_arguments *args, isula_container_config_t *conf) { int ret = 0; char *pe = NULL; @@ -244,7 +208,7 @@ static int request_pack_custom_env(struct client_arguments *args, isula_containe if (args->custom_conf.env != NULL) { size_t i; for (i = 0; i < util_array_len((const char **)(args->custom_conf.env)); i++) { - if (util_validate_env(args->custom_conf.env[i], &new_env) != 0) { + if (util_valid_env(args->custom_conf.env[i], &new_env) != 0) { COMMAND_ERROR("Invalid environment %s", args->custom_conf.env[i]); ret = -1; goto out; @@ -263,25 +227,6 @@ static int request_pack_custom_env(struct client_arguments *args, isula_containe conf->env_len = util_array_len((const char **)(conf->env)); } - if (args->custom_conf.accel != NULL) { - pe = util_env_get_val(conf->env, conf->env_len, ISULAD_ENABLE_PLUGINS, strlen(ISULAD_ENABLE_PLUGINS)); - if (pe == NULL) { - if (util_array_append(&conf->env, ISULAD_ENABLE_PLUGINS "=")) { - COMMAND_ERROR("init env ISULAD_ENABLE_PLUGINS failed"); - ret = -1; - goto out; - } - } - conf->env_len = util_array_len((const char **)(conf->env)); - conf->accel = args->custom_conf.accel; - conf->accel_len = util_array_len((const char **)(args->custom_conf.accel)); - if (util_env_set_isulad_enable_plugins(&conf->env, &conf->env_len, ISULAD_ISULA_ADAPTER)) { - COMMAND_ERROR("init accel env failed"); - ret = -1; - goto out; - } - } - out: free(pe); free(new_env); @@ -315,7 +260,7 @@ static int read_env_from_file(const char *path, size_t file_size, isula_containe continue; } buf[len - 1] = '\0'; - if (util_validate_env(buf, &new_env) != 0) { + if (util_valid_env(buf, &new_env) != 0) { ret = -1; goto out; } @@ -408,7 +353,7 @@ out: return ret; } -static int request_pack_custom_label(struct client_arguments *args, isula_container_config_t *conf) +static int request_pack_custom_label(const struct client_arguments *args, isula_container_config_t *conf) { int ret = 0; size_t i; @@ -429,8 +374,6 @@ static int request_pack_custom_label(struct client_arguments *args, isula_contai goto out; } } - util_free_array(args->custom_conf.label); - args->custom_conf.label = conf->label; /* make sure args->custom_conf.label point to valid memory. */ conf->label_len = util_array_len((const char **)(conf->label)); out: @@ -527,7 +470,7 @@ out: static void request_pack_custom_user(const struct client_arguments *args, isula_container_config_t *conf) { if (args->custom_conf.user != NULL) { - conf->user = args->custom_conf.user; + conf->user = util_strdup_s(args->custom_conf.user); } return; @@ -536,7 +479,7 @@ static void request_pack_custom_user(const struct client_arguments *args, isula_ static void request_pack_custom_hostname(const struct client_arguments *args, isula_container_config_t *conf) { if (args->custom_conf.hostname != NULL) { - conf->hostname = args->custom_conf.hostname; + conf->hostname = util_strdup_s(args->custom_conf.hostname); } return; @@ -560,39 +503,50 @@ static void request_pack_custom_system_container(const struct client_arguments * /* ns change opt */ if (!args->custom_conf.privileged) { if (args->custom_conf.ns_change_opt != NULL) { - conf->ns_change_opt = args->custom_conf.ns_change_opt; + conf->ns_change_opt = util_strdup_s(args->custom_conf.ns_change_opt); } } return; } -static void request_pack_custom_mounts(const struct client_arguments *args, isula_container_config_t *conf) +static int request_pack_custom_mounts(const struct client_arguments *args, isula_container_config_t *conf) { - if (args->custom_conf.mounts != NULL) { - conf->mounts_len = util_array_len((const char **)(args->custom_conf.mounts)); - conf->mounts = args->custom_conf.mounts; + if (args->custom_conf.mounts == NULL) { + return 0; } - return; + + if (util_dup_array_of_strings((const char **)args->custom_conf.mounts, + util_array_len((const char **)(args->custom_conf.mounts)), &conf->mounts, + &conf->mounts_len) != 0) { + COMMAND_ERROR("Failed to dup mounts info"); + return -1; + } + + return 0; } static void request_pack_custom_entrypoint(const struct client_arguments *args, isula_container_config_t *conf) { if (args->custom_conf.entrypoint != NULL) { - conf->entrypoint = args->custom_conf.entrypoint; + conf->entrypoint = util_strdup_s(args->custom_conf.entrypoint); } return; } -static void request_pack_custom_args(const struct client_arguments *args, isula_container_config_t *conf) +static int request_pack_custom_args(const struct client_arguments *args, isula_container_config_t *conf) { - if (args->argc != 0 && args->argv != NULL) { - conf->cmd_len = (size_t)(args->argc); - conf->cmd = (char **)args->argv; + if (args->argc == 0) { + return 0; } - return; + if (util_dup_array_of_strings((const char **)args->argv, args->argc, &conf->cmd, &conf->cmd_len) != 0) { + COMMAND_ERROR("Failed to dup command"); + return -1; + } + + return 0; } static void request_pack_custom_log_options(const struct client_arguments *args, isula_container_config_t *conf) @@ -600,42 +554,11 @@ static void request_pack_custom_log_options(const struct client_arguments *args, conf->log_driver = util_strdup_s(args->log_driver); } -static int request_pack_custom_log_accel(struct client_arguments *args, isula_container_config_t *conf) -{ - int ret = 0; - char *accargs = NULL; - - if (conf->accel != NULL) { - accargs = util_string_join(ISULAD_ISULA_ACCEL_ARGS_SEPERATOR, (const char **)conf->accel, conf->accel_len); - - if (conf->annotations == NULL) { - conf->annotations = util_common_calloc_s(sizeof(json_map_string_string)); - if (conf->annotations == NULL) { - COMMAND_ERROR("alloc annotations failed for accel"); - ret = -1; - goto out; - } - } - - ret = append_json_map_string_string(conf->annotations, ISULAD_ISULA_ACCEL_ARGS, accargs); - if (ret != 0) { - COMMAND_ERROR("init accel annotations failed accel=%s", accargs); - ret = -1; - goto out; - } - UTIL_FREE_AND_SET_NULL(accargs); - } - -out: - free(accargs); - return ret; -} - static void request_pack_custom_work_dir(const struct client_arguments *args, isula_container_config_t *conf) { /* work dir in container */ if (args->custom_conf.workdir != NULL) { - conf->workdir = args->custom_conf.workdir; + conf->workdir = util_strdup_s(args->custom_conf.workdir); } return; @@ -655,7 +578,7 @@ static void request_pack_custom_tty(const struct client_arguments *args, isula_c static void request_pack_custom_health_check(const struct client_arguments *args, isula_container_config_t *conf) { if (args->custom_conf.health_cmd != NULL) { - conf->health_cmd = args->custom_conf.health_cmd; + conf->health_cmd = util_strdup_s(args->custom_conf.health_cmd); } /* health check */ conf->health_interval = args->custom_conf.health_interval; @@ -668,30 +591,57 @@ static void request_pack_custom_health_check(const struct client_arguments *args return; } -static int request_pack_custom_conf(struct client_arguments *args, isula_container_config_t *conf) +static int request_pack_custom_annotations(const struct client_arguments *args, isula_container_config_t *conf) { - if (args == NULL) { + if (args->annotations == NULL) { + return 0; + } + + conf->annotations = util_common_calloc_s(sizeof(json_map_string_string)); + if (conf->annotations == NULL) { + COMMAND_ERROR("Out of memory"); + return -1; + } + + if (dup_json_map_string_string(args->annotations, conf->annotations) != 0) { + COMMAND_ERROR("Failed to dup map"); return -1; } + return 0; +} + +static isula_container_config_t *request_pack_custom_conf(const struct client_arguments *args) +{ + isula_container_config_t *conf = NULL; + + if (args == NULL) { + return NULL; + } + + conf = util_common_calloc_s(sizeof(isula_container_config_t)); + if (conf == NULL) { + return NULL; + } + /* append environment variables from env file */ if (request_pack_custom_env_file(args, conf) != 0) { - return -1; + goto error_out; } /* make sure --env has higher priority than --env-file */ if (request_pack_custom_env(args, conf) != 0) { - return -1; + goto error_out; } /* append labels from label file */ if (request_pack_custom_label_file(args, conf) != 0) { - return -1; + goto error_out; } /* make sure --label has higher priority than --label-file */ if (request_pack_custom_label(args, conf) != 0) { - return -1; + goto error_out; } /* user and group */ @@ -706,22 +656,23 @@ static int request_pack_custom_conf(struct client_arguments *args, isula_contain request_pack_custom_system_container(args, conf); /* mounts to mount filesystem */ - request_pack_custom_mounts(args, conf); + if (request_pack_custom_mounts(args, conf) != 0) { + goto error_out; + } /* entrypoint */ request_pack_custom_entrypoint(args, conf); /* command args */ - request_pack_custom_args(args, conf); + if (request_pack_custom_args(args, conf) != 0) { + goto error_out; + } /* console log options */ request_pack_custom_log_options(args, conf); - conf->annotations = args->annotations; - args->annotations = NULL; - - if (request_pack_custom_log_accel(args, conf) != 0) { - return -1; + if (request_pack_custom_annotations(args, conf) != 0) { + goto error_out; } /* work dir in container */ @@ -731,7 +682,11 @@ static int request_pack_custom_conf(struct client_arguments *args, isula_contain request_pack_custom_health_check(args, conf); - return 0; + return conf; + +error_out: + isula_container_config_free(conf); + return NULL; } static int request_pack_host_ns_change_files(const struct client_arguments *args, isula_host_config_t *hostconfig) @@ -786,182 +741,310 @@ static int request_pack_host_ns_change_files(const struct client_arguments *args return ret; } -static void request_pack_host_caps(const struct client_arguments *args, isula_host_config_t *hostconfig) +static int request_pack_host_caps(const struct client_arguments *args, isula_host_config_t *hostconfig) { /* cap add */ if (args->custom_conf.cap_adds != NULL) { - hostconfig->cap_add_len = util_array_len((const char **)(args->custom_conf.cap_adds)); - hostconfig->cap_add = args->custom_conf.cap_adds; + if (util_dup_array_of_strings((const char **)(args->custom_conf.cap_adds), + util_array_len((const char **)(args->custom_conf.cap_adds)), &hostconfig->cap_add, + &hostconfig->cap_add_len) != 0) { + COMMAND_ERROR("Failed to dup cap adds"); + return -1; + } } /* cap drop */ if (args->custom_conf.cap_drops != NULL) { - hostconfig->cap_drop_len = util_array_len((const char **)(args->custom_conf.cap_drops)); - hostconfig->cap_drop = args->custom_conf.cap_drops; + if (util_dup_array_of_strings((const char **)(args->custom_conf.cap_drops), + util_array_len((const char **)(args->custom_conf.cap_drops)), + &hostconfig->cap_drop, &hostconfig->cap_drop_len) != 0) { + COMMAND_ERROR("Failed to dup cap drops"); + return -1; + } } + + return 0; } -static void request_pack_host_group_add(const struct client_arguments *args, isula_host_config_t *hostconfig) +static int request_pack_host_group_add(const struct client_arguments *args, isula_host_config_t *hostconfig) { /* group add */ if (args->custom_conf.group_add != NULL) { - hostconfig->group_add_len = util_array_len((const char **)(args->custom_conf.group_add)); - hostconfig->group_add = args->custom_conf.group_add; + if (util_dup_array_of_strings((const char **)(args->custom_conf.group_add), + util_array_len((const char **)(args->custom_conf.group_add)), + &hostconfig->group_add, &hostconfig->group_add_len) != 0) { + COMMAND_ERROR("Failed to dup group adds"); + return -1; + } } + + return 0; } -static void request_pack_host_extra_hosts(const struct client_arguments *args, isula_host_config_t *hostconfig) +static int request_pack_host_extra_hosts(const struct client_arguments *args, isula_host_config_t *hostconfig) { /* extra hosts */ if (args->custom_conf.extra_hosts != NULL) { - hostconfig->extra_hosts_len = util_array_len((const char **)(args->custom_conf.extra_hosts)); - hostconfig->extra_hosts = args->custom_conf.extra_hosts; + if (util_dup_array_of_strings((const char **)(args->custom_conf.extra_hosts), + util_array_len((const char **)(args->custom_conf.extra_hosts)), + &hostconfig->extra_hosts, &hostconfig->extra_hosts_len) != 0) { + COMMAND_ERROR("Failed to dup extra hosts"); + return -1; + } } + + return 0; } -static void request_pack_host_dns(const struct client_arguments *args, isula_host_config_t *hostconfig) +static int request_pack_host_dns(const struct client_arguments *args, isula_host_config_t *hostconfig) { /* dns */ if (args->custom_conf.dns != NULL) { - hostconfig->dns_len = util_array_len((const char **)(args->custom_conf.dns)); - hostconfig->dns = args->custom_conf.dns; + if (util_dup_array_of_strings((const char **)(args->custom_conf.dns), + util_array_len((const char **)(args->custom_conf.dns)), &hostconfig->dns, + &hostconfig->dns_len) != 0) { + COMMAND_ERROR("Failed to dup dns"); + return -1; + } } /* dns options */ if (args->custom_conf.dns_options != NULL) { - hostconfig->dns_options_len = util_array_len((const char **)(args->custom_conf.dns_options)); - hostconfig->dns_options = args->custom_conf.dns_options; + if (util_dup_array_of_strings((const char **)(args->custom_conf.dns_options), + util_array_len((const char **)(args->custom_conf.dns_options)), + &hostconfig->dns_options, &hostconfig->dns_options_len) != 0) { + COMMAND_ERROR("Failed to dup dns options"); + return -1; + } } /* dns search */ if (args->custom_conf.dns_search != NULL) { - hostconfig->dns_search_len = util_array_len((const char **)(args->custom_conf.dns_search)); - hostconfig->dns_search = args->custom_conf.dns_search; + if (util_dup_array_of_strings((const char **)(args->custom_conf.dns_search), + util_array_len((const char **)(args->custom_conf.dns_search)), + &hostconfig->dns_search, &hostconfig->dns_search_len) != 0) { + COMMAND_ERROR("Failed to dup dns search"); + return -1; + } } + + return 0; } -static void request_pack_host_ulimit(const struct client_arguments *args, isula_host_config_t *hostconfig) +inline static int request_pack_host_ulimit(const struct client_arguments *args, isula_host_config_t *hostconfig) { /* ulimit options */ if (args->custom_conf.ulimits != NULL) { - hostconfig->ulimits_len = util_array_len((const char **)(args->custom_conf.ulimits)); - hostconfig->ulimits = args->custom_conf.ulimits; + if (util_dup_array_of_strings((const char **)(args->custom_conf.ulimits), + util_array_len((const char **)(args->custom_conf.ulimits)), &hostconfig->ulimits, + &hostconfig->ulimits_len) != 0) { + COMMAND_ERROR("Failed to dup ulimits"); + return -1; + } } + + return 0; } -static void request_pack_host_weight_devices(const struct client_arguments *args, isula_host_config_t *hostconfig) +inline static int request_pack_host_weight_devices(const struct client_arguments *args, isula_host_config_t *hostconfig) { /* blkio weight devices */ if (args->custom_conf.weight_devices != NULL) { - hostconfig->blkio_weight_device_len = util_array_len((const char **)(args->custom_conf.weight_devices)); - hostconfig->blkio_weight_device = args->custom_conf.weight_devices; + if (util_dup_array_of_strings((const char **)(args->custom_conf.weight_devices), + util_array_len((const char **)(args->custom_conf.weight_devices)), + &hostconfig->blkio_weight_device, &hostconfig->blkio_weight_device_len) != 0) { + COMMAND_ERROR("Failed to dup weight devices"); + return -1; + } } + + return 0; } -static void request_pack_host_device_read_bps(const struct client_arguments *args, isula_host_config_t *hostconfig) +inline static int request_pack_host_device_read_bps(const struct client_arguments *args, + isula_host_config_t *hostconfig) { if (args->custom_conf.blkio_throttle_read_bps_device != NULL) { - hostconfig->blkio_throttle_read_bps_device_len = - util_array_len((const char **)(args->custom_conf.blkio_throttle_read_bps_device)); - hostconfig->blkio_throttle_read_bps_device = args->custom_conf.blkio_throttle_read_bps_device; + if (util_dup_array_of_strings((const char **)(args->custom_conf.blkio_throttle_read_bps_device), + util_array_len((const char **)(args->custom_conf.blkio_throttle_read_bps_device)), + &hostconfig->blkio_throttle_read_bps_device, + &hostconfig->blkio_throttle_read_bps_device_len) != 0) { + COMMAND_ERROR("Failed to dup blkio_throttle_read_bps_device"); + return -1; + } } + + return 0; } -static void request_pack_host_device_write_bps(const struct client_arguments *args, isula_host_config_t *hostconfig) +inline static int request_pack_host_device_write_bps(const struct client_arguments *args, + isula_host_config_t *hostconfig) { if (args->custom_conf.blkio_throttle_write_bps_device != NULL) { - hostconfig->blkio_throttle_write_bps_device_len = - util_array_len((const char **)(args->custom_conf.blkio_throttle_write_bps_device)); - hostconfig->blkio_throttle_write_bps_device = args->custom_conf.blkio_throttle_write_bps_device; + if (util_dup_array_of_strings((const char **)(args->custom_conf.blkio_throttle_write_bps_device), + util_array_len((const char **)(args->custom_conf.blkio_throttle_write_bps_device)), + &hostconfig->blkio_throttle_write_bps_device, + &hostconfig->blkio_throttle_write_bps_device_len) != 0) { + COMMAND_ERROR("Failed to dup blkio_throttle_write_bps_device"); + return -1; + } + } + + return 0; +} + +inline static int request_pack_host_device_read_iops(const struct client_arguments *args, + isula_host_config_t *hostconfig) +{ + if (args->custom_conf.blkio_throttle_read_iops_device != NULL) { + if (util_dup_array_of_strings((const char **)(args->custom_conf.blkio_throttle_read_iops_device), + util_array_len((const char **)(args->custom_conf.blkio_throttle_read_iops_device)), + &hostconfig->blkio_throttle_read_iops_device, + &hostconfig->blkio_throttle_read_iops_device_len) != 0) { + COMMAND_ERROR("Failed to dup blkio_throttle_read_iops_device"); + return -1; + } + } + + return 0; +} + +inline static int request_pack_host_device_write_iops(const struct client_arguments *args, + isula_host_config_t *hostconfig) +{ + if (args->custom_conf.blkio_throttle_write_iops_device != NULL) { + if (util_dup_array_of_strings( + (const char **)(args->custom_conf.blkio_throttle_write_iops_device), + util_array_len((const char **)(args->custom_conf.blkio_throttle_write_iops_device)), + &hostconfig->blkio_throttle_write_iops_device, + &hostconfig->blkio_throttle_write_iops_device_len) != 0) { + COMMAND_ERROR("Failed to dup blkio_throttle_write_iops_device"); + return -1; + } + } + + return 0; +} + +inline static int request_pack_host_device_cgroup_rules(const struct client_arguments *args, + isula_host_config_t *hostconfig) +{ + if (args->custom_conf.device_cgroup_rules != NULL) { + if (util_dup_array_of_strings((const char **)(args->custom_conf.device_cgroup_rules), + util_array_len((const char **)(args->custom_conf.device_cgroup_rules)), + &hostconfig->device_cgroup_rules, &hostconfig->device_cgroup_rules_len) != 0) { + COMMAND_ERROR("Failed to dup device_cgroup_rules"); + return -1; + } } + + return 0; } -static void request_pack_host_blockio(const struct client_arguments *args, isula_host_config_t *hostconfig) +inline static int request_pack_host_blockio(const struct client_arguments *args, isula_host_config_t *hostconfig) { - request_pack_host_weight_devices(args, hostconfig); - request_pack_host_device_read_bps(args, hostconfig); - request_pack_host_device_write_bps(args, hostconfig); + return (request_pack_host_weight_devices(args, hostconfig) || request_pack_host_device_read_bps(args, hostconfig) || + request_pack_host_device_write_bps(args, hostconfig) || + request_pack_host_device_read_iops(args, hostconfig) || + request_pack_host_device_write_iops(args, hostconfig)); } -static void request_pack_host_devices(const struct client_arguments *args, isula_host_config_t *hostconfig) +inline static int request_pack_host_devices(const struct client_arguments *args, isula_host_config_t *hostconfig) { /* devices */ if (args->custom_conf.devices != NULL) { - hostconfig->devices_len = util_array_len((const char **)(args->custom_conf.devices)); - hostconfig->devices = args->custom_conf.devices; + if (util_dup_array_of_strings((const char **)(args->custom_conf.devices), + util_array_len((const char **)(args->custom_conf.devices)), &hostconfig->devices, + &hostconfig->devices_len) != 0) { + COMMAND_ERROR("Failed to dup devices"); + return -1; + } } + + return 0; } -static void request_pack_host_hugepage_limits(const struct client_arguments *args, isula_host_config_t *hostconfig) +inline static int request_pack_host_hugepage_limits(const struct client_arguments *args, + isula_host_config_t *hostconfig) { /* hugepage limits */ if (args->custom_conf.hugepage_limits != NULL) { - hostconfig->hugetlbs_len = util_array_len((const char **)(args->custom_conf.hugepage_limits)); - hostconfig->hugetlbs = args->custom_conf.hugepage_limits; + if (util_dup_array_of_strings((const char **)(args->custom_conf.hugepage_limits), + util_array_len((const char **)(args->custom_conf.hugepage_limits)), + &hostconfig->hugetlbs, &hostconfig->hugetlbs_len) != 0) { + COMMAND_ERROR("Failed to dup hugepage_limits"); + return -1; + } } + + return 0; } -static void request_pack_host_binds(const struct client_arguments *args, isula_host_config_t *hostconfig) +inline static int request_pack_host_binds(const struct client_arguments *args, isula_host_config_t *hostconfig) { /* volumes to binds */ if (args->custom_conf.volumes != NULL) { - hostconfig->binds_len = (size_t)util_array_len((const char **)(args->custom_conf.volumes)); - hostconfig->binds = args->custom_conf.volumes; + if (util_dup_array_of_strings((const char **)(args->custom_conf.volumes), + util_array_len((const char **)(args->custom_conf.volumes)), &hostconfig->binds, + &hostconfig->binds_len) != 0) { + COMMAND_ERROR("Failed to dup volumes"); + return -1; + } } + + return 0; } -static void request_pack_host_hook_spec(const struct client_arguments *args, isula_host_config_t *hostconfig) +inline static void request_pack_host_hook_spec(const struct client_arguments *args, isula_host_config_t *hostconfig) { /* hook-spec file */ - if (args->custom_conf.hook_spec != NULL) { - hostconfig->hook_spec = args->custom_conf.hook_spec; - } + hostconfig->hook_spec = util_strdup_s(args->custom_conf.hook_spec); } -static void request_pack_host_restart_policy(const struct client_arguments *args, isula_host_config_t *hostconfig) +inline static void request_pack_host_restart_policy(const struct client_arguments *args, + isula_host_config_t *hostconfig) { - if (args->restart != NULL) { - hostconfig->restart_policy = args->restart; - } + hostconfig->restart_policy = util_strdup_s(args->restart); } static void request_pack_host_namespaces(const struct client_arguments *args, isula_host_config_t *hostconfig) { - if (args->host_channel != NULL) { - hostconfig->host_channel = args->host_channel; - } + hostconfig->network_mode = util_strdup_s(args->custom_conf.share_ns[NAMESPACE_NET]); - if (args->custom_conf.share_ns[NAMESPACE_NET] != NULL) { - hostconfig->network_mode = args->custom_conf.share_ns[NAMESPACE_NET]; - } - if (args->custom_conf.share_ns[NAMESPACE_IPC] != NULL) { - hostconfig->ipc_mode = args->custom_conf.share_ns[NAMESPACE_IPC]; - } - if (args->custom_conf.share_ns[NAMESPACE_USER] != NULL) { - hostconfig->userns_mode = args->custom_conf.share_ns[NAMESPACE_USER]; - } - if (args->custom_conf.share_ns[NAMESPACE_UTS] != NULL) { - hostconfig->uts_mode = args->custom_conf.share_ns[NAMESPACE_UTS]; - } - if (args->custom_conf.share_ns[NAMESPACE_PID] != NULL) { - hostconfig->pid_mode = args->custom_conf.share_ns[NAMESPACE_PID]; - } + hostconfig->ipc_mode = util_strdup_s(args->custom_conf.share_ns[NAMESPACE_IPC]); + + hostconfig->userns_mode = util_strdup_s(args->custom_conf.share_ns[NAMESPACE_USER]); + + hostconfig->uts_mode = util_strdup_s(args->custom_conf.share_ns[NAMESPACE_UTS]); + + hostconfig->pid_mode = util_strdup_s(args->custom_conf.share_ns[NAMESPACE_PID]); } -static void request_pack_host_security(const struct client_arguments *args, isula_host_config_t *hostconfig) +inline static int request_pack_host_security(const struct client_arguments *args, isula_host_config_t *hostconfig) { /* security opt */ if (args->custom_conf.security != NULL) { - hostconfig->security_len = util_array_len((const char **)(args->custom_conf.security)); - hostconfig->security = args->custom_conf.security; + if (util_dup_array_of_strings((const char **)(args->custom_conf.security), + util_array_len((const char **)(args->custom_conf.security)), + &hostconfig->security, &hostconfig->security_len) != 0) { + COMMAND_ERROR("Failed to dup security"); + return -1; + } } + + return 0; } -static int request_pack_host_config(const struct client_arguments *args, isula_host_config_t *hostconfig) +static isula_host_config_t *request_pack_host_config(const struct client_arguments *args) { - int ret = 0; + isula_host_config_t *hostconfig = NULL; if (args == NULL) { - return -1; + return NULL; + } + + hostconfig = util_common_calloc_s(sizeof(isula_host_config_t)); + if (hostconfig == NULL) { + return NULL; } /* privileged */ @@ -977,7 +1060,7 @@ static int request_pack_host_config(const struct client_arguments *args, isula_h hostconfig->shm_size = args->custom_conf.shm_size; /* user remap */ - hostconfig->user_remap = args->custom_conf.user_remap; + hostconfig->user_remap = util_strdup_s(args->custom_conf.user_remap); /* auto remove */ hostconfig->auto_remove = args->custom_conf.auto_remove; @@ -986,50 +1069,64 @@ static int request_pack_host_config(const struct client_arguments *args, isula_h hostconfig->readonly_rootfs = args->custom_conf.readonly; /* env target file */ - hostconfig->env_target_file = args->custom_conf.env_target_file; + hostconfig->env_target_file = util_strdup_s(args->custom_conf.env_target_file); /* cgroup parent */ - hostconfig->cgroup_parent = args->custom_conf.cgroup_parent; + hostconfig->cgroup_parent = util_strdup_s(args->custom_conf.cgroup_parent); - ret = request_pack_host_config_cgroup(args, hostconfig); - if (ret != 0) { - return ret; + if (request_pack_host_config_cgroup(args, hostconfig) != 0) { + goto error_out; } /* storage options */ - ret = request_pack_host_config_storage_opts(args, hostconfig); - if (ret != 0) { - return ret; + if (request_pack_host_config_storage_opts(args, hostconfig) != 0) { + goto error_out; } /* sysctls */ - ret = request_pack_host_config_sysctls(args, hostconfig); - if (ret != 0) { - return ret; + if (request_pack_host_config_sysctls(args, hostconfig) != 0) { + goto error_out; } - ret = request_pack_host_ns_change_files(args, hostconfig); - if (ret != 0) { - return ret; + if (request_pack_host_ns_change_files(args, hostconfig) != 0) { + goto error_out; } - request_pack_host_caps(args, hostconfig); + if (request_pack_host_caps(args, hostconfig) != 0) { + goto error_out; + } - request_pack_host_group_add(args, hostconfig); + if (request_pack_host_group_add(args, hostconfig) != 0) { + goto error_out; + } - request_pack_host_extra_hosts(args, hostconfig); + if (request_pack_host_extra_hosts(args, hostconfig) != 0) { + goto error_out; + } - request_pack_host_dns(args, hostconfig); + if (request_pack_host_dns(args, hostconfig) != 0) { + goto error_out; + } - request_pack_host_ulimit(args, hostconfig); + if (request_pack_host_ulimit(args, hostconfig) != 0) { + goto error_out; + } - request_pack_host_blockio(args, hostconfig); + if (request_pack_host_blockio(args, hostconfig) != 0) { + goto error_out; + } - request_pack_host_devices(args, hostconfig); + if (request_pack_host_devices(args, hostconfig) != 0) { + goto error_out; + } - request_pack_host_hugepage_limits(args, hostconfig); + if (request_pack_host_hugepage_limits(args, hostconfig) != 0) { + goto error_out; + } - request_pack_host_binds(args, hostconfig); + if (request_pack_host_binds(args, hostconfig) != 0) { + goto error_out; + } request_pack_host_hook_spec(args, hostconfig); @@ -1037,9 +1134,21 @@ static int request_pack_host_config(const struct client_arguments *args, isula_h request_pack_host_namespaces(args, hostconfig); - request_pack_host_security(args, hostconfig); + hostconfig->host_channel = util_strdup_s(args->host_channel); - return ret; + if (request_pack_host_security(args, hostconfig) != 0) { + goto error_out; + } + + if (request_pack_host_device_cgroup_rules(args, hostconfig) != 0) { + goto error_out; + } + + return hostconfig; + +error_out: + isula_host_config_free(hostconfig); + return NULL; } #define IMAGE_NOT_FOUND_ERROR "No such image" @@ -1116,57 +1225,52 @@ out: return ret; } -static void free_alloced_memory_in_host_config(isula_host_config_t *hostconfig) -{ - isula_ns_change_files_free(hostconfig); - isula_host_config_storage_opts_free(hostconfig); - isula_host_config_sysctl_free(hostconfig); -} - -static void free_alloced_memory_in_config(isula_container_config_t *custom_conf) -{ - if (custom_conf == NULL) { - return; - } - - free_json_map_string_string(custom_conf->annotations); - custom_conf->annotations = NULL; - - free(custom_conf->log_driver); - custom_conf->log_driver = NULL; -} - /* * Create a create request message and call RPC */ int client_create(struct client_arguments *args) { int ret = 0; - struct isula_create_request request = { 0 }; + struct isula_create_request *request = NULL; struct isula_create_response *response = NULL; - isula_container_config_t custom_conf = { 0 }; - isula_host_config_t host_config = { 0 }; - container_cgroup_resources_t cr = { 0 }; - - request.name = args->name; - request.rootfs = args->create_rootfs; - request.runtime = args->runtime; - request.image = args->image_name; - request.hostconfig = &host_config; - request.config = &custom_conf; - host_config.cr = &cr; - - ret = request_pack_custom_conf(args, request.config); - if (ret != 0) { + isula_container_config_t *container_spec = NULL; + isula_host_config_t *host_spec = NULL; + + request = util_common_calloc_s(sizeof(struct isula_create_request)); + if (request == NULL) { + COMMAND_ERROR("Memery out"); + ret = -1; goto out; } - ret = request_pack_host_config(args, request.hostconfig); - if (ret != 0) { + request->name = util_strdup_s(args->name); + request->rootfs = util_strdup_s(args->create_rootfs); + request->runtime = util_strdup_s(args->runtime); + request->image = util_strdup_s(args->image_name); + + container_spec = request_pack_custom_conf(args); + if (container_spec == 0) { + ret = -1; + goto out; + } + + if (generate_container_config(container_spec, &request->container_spec_json) != 0) { + ret = -1; + goto out; + } + + host_spec = request_pack_host_config(args); + if (host_spec == 0) { + ret = -1; + goto out; + } + + if (generate_hostconfig(host_spec, &request->host_spec_json) != 0) { + ret = -1; goto out; } - ret = client_try_to_create(args, &request, &response); + ret = client_try_to_create(args, request, &response); if (ret != 0) { goto out; } @@ -1180,9 +1284,10 @@ int client_create(struct client_arguments *args) goto out; } out: - free_alloced_memory_in_host_config(request.hostconfig); - free_alloced_memory_in_config(request.config); + isula_host_config_free(host_spec); + isula_container_config_free(container_spec); isula_create_response_free(response); + isula_create_request_free(request); return ret; } @@ -1741,7 +1846,7 @@ static int parse_mount_item_dst(const char *value, struct valid_mounts_state *st return MOUNT_STATE_CHECK_INVALID_ARG; } - if (!cleanpath(value, dstpath, sizeof(dstpath))) { + if (!util_clean_path(value, dstpath, sizeof(dstpath))) { COMMAND_ERROR("Invalid mount specification '%s'.Can't translate destination path to clean path", state->mount); return MOUNT_STATE_CHECK_INVALID_ARG; } @@ -2139,7 +2244,7 @@ static int create_namespaces_checker(const struct client_arguments *args) const char *net_mode = args->custom_conf.share_ns[NAMESPACE_NET]; if (args->custom_conf.share_ns[NAMESPACE_NET]) { - if (!is_host(net_mode) && !is_container(net_mode) && !is_none(net_mode)) { + if (!namespace_is_host(net_mode) && !namespace_is_container(net_mode) && !namespace_is_none(net_mode)) { COMMAND_ERROR("Unsupported network mode %s", net_mode); ret = -1; goto out; @@ -2228,7 +2333,7 @@ static bool do_create_check_sysctl(const char *sysctl) if (p != NULL) { *p = '\0'; if (strcmp("kernel.pid_max", sysctl) == 0) { - if (!pid_max_kernel_namespaced()) { + if (!util_check_pid_max_kernel_namespaced()) { COMMAND_ERROR("Sysctl '%s' is not kernel namespaced, it cannot be changed", sysctl); restore_to_equate(p); return false; @@ -2237,7 +2342,7 @@ static bool do_create_check_sysctl(const char *sysctl) return true; } } - if (!check_sysctl_valid(sysctl)) { + if (!util_valid_sysctl(sysctl)) { restore_to_equate(p); COMMAND_ERROR("Sysctl '%s' is not whitelist", sysctl); return false; @@ -2286,7 +2391,7 @@ static int create_check_env_target_file(const struct client_arguments *args) COMMAND_ERROR("external rootfs not specified"); return 0; } - if (realpath_in_scope(args->external_rootfs, env_target_file, &env_path) < 0) { + if (util_realpath_in_scope(args->external_rootfs, env_target_file, &env_path) < 0) { COMMAND_ERROR("env target file '%s' real path must be under '%s'", env_target_file, args->external_rootfs); ret = -1; goto out; diff --git a/src/cmd/isula/base/create.h b/src/cmd/isula/base/create.h index d8733e0..79f6378 100644 --- a/src/cmd/isula/base/create.h +++ b/src/cmd/isula/base/create.h @@ -26,396 +26,442 @@ extern "C" { #endif -#define CREATE_OPTIONS(cmdargs) \ - { CMD_OPT_TYPE_CALLBACK, \ - false, \ - "accel", \ - 0, \ - &(cmdargs).custom_conf.accel, \ - "Accelerator bindings (format: [=][@[,]])", \ - command_append_array }, \ - { CMD_OPT_TYPE_BOOL, \ - false, \ - "read-only", \ - 0, \ - &(cmdargs).custom_conf.readonly, \ - "Make container rootfs readonly", \ - NULL }, \ - { CMD_OPT_TYPE_CALLBACK, \ - false, \ - "cap-add", \ - 0, \ - &(cmdargs).custom_conf.cap_adds, \ - "Add Linux capabilities ('ALL' to add all capabilities)", \ - command_append_array }, \ - { CMD_OPT_TYPE_CALLBACK, \ - false, \ - "cap-drop", \ - 0, \ - &(cmdargs).custom_conf.cap_drops, \ - "Drop Linux capabilities ('ALL' to drop all capabilities)", \ - command_append_array }, \ - { CMD_OPT_TYPE_CALLBACK, false, "cpu-shares", 0, &(cmdargs).cr.cpu_shares, "CPU shares (relative weight)", \ - command_convert_llong }, \ - { CMD_OPT_TYPE_CALLBACK, \ - false, \ - "cpu-period", \ - 0, \ - &(cmdargs).cr.cpu_period, \ - "Limit CPU CFS (Completely Fair Scheduler) period", \ - command_convert_llong }, \ - { CMD_OPT_TYPE_CALLBACK, \ - false, \ - "cpu-quota", \ - 0, \ - &(cmdargs).cr.cpu_quota, \ - "Limit CPU CFS (Completely Fair Scheduler) quota", \ - command_convert_llong }, \ - { CMD_OPT_TYPE_STRING, \ - false, \ - "cpuset-cpus", \ - 0, \ - &(cmdargs).cr.cpuset_cpus, \ - "CPUs in which to allow execution (e.g. 0-3, 0,1)", \ - NULL }, \ - { CMD_OPT_TYPE_STRING, \ - false, \ - "cpuset-mems", \ - 0, \ - &(cmdargs).cr.cpuset_mems, \ - "MEMs in which to allow execution (0-3, 0,1)", \ - NULL }, \ - { CMD_OPT_TYPE_CALLBACK, \ - false, \ - "device-read-bps", \ - 0, \ - &(cmdargs).custom_conf.blkio_throttle_read_bps_device, \ - "Limit read rate (bytes per second) from a device (default [])", \ - command_append_array }, \ - { CMD_OPT_TYPE_CALLBACK, \ - false, \ - "device-write-bps", \ - 0, \ - &(cmdargs).custom_conf.blkio_throttle_write_bps_device, \ - "Limit write rate (bytes per second) to a device (default [])", \ - command_append_array }, \ - { CMD_OPT_TYPE_CALLBACK, \ - false, \ - "oom-score-adj", \ - 0, \ - &(cmdargs).cr.oom_score_adj, \ - "Tune host's OOM preferences (-1000 to 1000)", \ - command_convert_llong }, \ - { CMD_OPT_TYPE_CALLBACK, \ - false, \ - "device", \ - 0, \ - &(cmdargs).custom_conf.devices, \ - "Add a host device to the container", \ - command_append_array }, \ - { CMD_OPT_TYPE_CALLBACK, false, "env", 'e', &(cmdargs).custom_conf.env, "Set environment variables", \ - command_append_array }, \ - { CMD_OPT_TYPE_CALLBACK, \ - false, \ - "env-file", \ - 0, \ - &(cmdargs).custom_conf.env_file, \ - "Read in a file of environment variables", \ - command_append_array }, \ - { CMD_OPT_TYPE_CALLBACK, \ - false, \ - "label", \ - 'l', \ - &(cmdargs).custom_conf.label, \ - "Set metadata on container (default [])", \ - command_append_array }, \ - { CMD_OPT_TYPE_CALLBACK, \ - false, \ - "label-file", \ - 0, \ - &(cmdargs).custom_conf.label_file, \ - "Read in a line delimited file of labels (default [])", \ - command_append_array }, \ - { CMD_OPT_TYPE_STRING_DUP, \ - false, \ - "entrypoint", \ - 0, \ - &(cmdargs).custom_conf.entrypoint, \ - "Entrypoint to run when starting the container", \ - NULL }, \ - { CMD_OPT_TYPE_STRING, \ - false, \ - "external-rootfs", \ - 0, \ - &(cmdargs).external_rootfs, \ - "Specify the custom rootfs that is not managed by isulad for the container, directory or block device", \ - NULL }, \ - { CMD_OPT_TYPE_CALLBACK, \ - false, \ - "files-limit", \ - 0, \ - &(cmdargs).custom_conf.files_limit, \ - "Tune container files limit (set -1 for unlimited)", \ - command_convert_llong }, \ - { CMD_OPT_TYPE_STRING_DUP, \ - false, \ - "hook-spec", \ - 0, \ - &(cmdargs).custom_conf.hook_spec, \ - "File containing hook definition(prestart, poststart, poststop)", \ - NULL }, \ - { CMD_OPT_TYPE_STRING_DUP, false, "hostname", 'h', &(cmdargs).custom_conf.hostname, \ - "Container host name", NULL }, \ - { CMD_OPT_TYPE_CALLBACK, \ - false, \ - "add-host", \ - 0, \ - &(cmdargs).custom_conf.extra_hosts, \ - "Add a custom host-to-IP mapping (host:ip)", \ - command_append_array }, \ - { CMD_OPT_TYPE_CALLBACK, false, "dns", 0, &(cmdargs).custom_conf.dns, "Set custom DNS servers", \ - command_append_array }, \ - { CMD_OPT_TYPE_CALLBACK, false, "dns-opt", 0, &(cmdargs).custom_conf.dns_options, "Set DNS options", \ - command_append_array }, \ - { CMD_OPT_TYPE_CALLBACK, \ - false, \ - "dns-search", \ - 0, \ - &(cmdargs).custom_conf.dns_search, \ - "Set custom DNS search domains", \ - command_append_array }, \ - { CMD_OPT_TYPE_STRING, \ - false, \ - "user-remap", \ - 0, \ - &(cmdargs).custom_conf.user_remap, \ - "Set user remap for container", \ - NULL }, \ - { CMD_OPT_TYPE_STRING_DUP, false, "ipc", 0, &(cmdargs).custom_conf.share_ns[NAMESPACE_IPC], \ - "IPC namespace to use", NULL }, \ - { CMD_OPT_TYPE_CALLBACK, \ - false, \ - "shm-size", \ - 0, \ - &(cmdargs).custom_conf.shm_size, \ - "Size of /dev/shm, default value is 64MB", \ - command_convert_membytes }, \ - { CMD_OPT_TYPE_CALLBACK, \ - false, \ - "kernel-memory", \ - 0, \ - &(cmdargs).cr.kernel_memory_limit, \ - "Kernel memory limit", \ - command_convert_membytes }, \ - { CMD_OPT_TYPE_CALLBACK, \ - false, \ - "hugetlb-limit", \ - 0, \ - &(cmdargs).custom_conf.hugepage_limits, \ - "Huge page limit (format: [size:], e.g. --hugetlb-limit 2MB:32MB)", \ - command_append_array }, \ - { CMD_OPT_TYPE_CALLBACK, \ - false, \ - "log-driver", \ - 0, \ - &(cmdargs), \ - "Container log driver, support syslog and json-file", \ - callback_log_driver }, \ - { CMD_OPT_TYPE_CALLBACK, false, "log-opt", 0, &(cmdargs), "Container log options, value formate: key=value", \ - callback_log_opt }, \ - { CMD_OPT_TYPE_CALLBACK, false, "memory", 'm', &(cmdargs).cr.memory_limit, "Memory limit", \ - command_convert_membytes }, \ - { CMD_OPT_TYPE_CALLBACK, \ - false, \ - "memory-reservation", \ - 0, \ - &(cmdargs).cr.memory_reservation, \ - "Memory soft limit", \ - command_convert_membytes }, \ - { CMD_OPT_TYPE_CALLBACK, \ - false, \ - "memory-swap", \ - 0, \ - &(cmdargs).cr.memory_swap, \ - "Swap limit equal to memory plus swap: '-1' to enable unlimited swap", \ - command_convert_memswapbytes }, \ - { CMD_OPT_TYPE_CALLBACK, false, \ - "memory-swappiness", 0, \ - &(cmdargs).cr.swappiness, "Tune container memory swappiness (0 to 100) (default -1)", \ - command_convert_swappiness }, \ - { CMD_OPT_TYPE_CALLBACK, \ - false, \ - "mount", \ - 0, \ - &(cmdargs).custom_conf.mounts, \ - "Attach a filesystem mount to the service", \ - command_append_array }, \ - { CMD_OPT_TYPE_CALLBACK, \ - false, \ - "group-add", \ - 0, \ - &(cmdargs).custom_conf.group_add, \ - "Add additional groups to join", \ - command_append_array }, \ - { CMD_OPT_TYPE_STRING_DUP, false, "name", 'n', &(cmdargs).name, "Name of the container", NULL }, \ - { CMD_OPT_TYPE_STRING_DUP, \ - false, \ - "net", \ - 0, \ - &(cmdargs).custom_conf.share_ns[NAMESPACE_NET], \ - "Connect a container to a network", \ - NULL }, \ - { CMD_OPT_TYPE_STRING_DUP, false, "pid", 0, &(cmdargs).custom_conf.share_ns[NAMESPACE_PID], \ - "PID namespace to use", NULL }, \ - { CMD_OPT_TYPE_CALLBACK, \ - false, \ - "pids-limit", \ - 0, \ - &(cmdargs).custom_conf.pids_limit, \ - "Tune container pids limit (set -1 for unlimited)", \ - command_convert_llong }, \ - { CMD_OPT_TYPE_BOOL, \ - false, \ - "privileged", \ - 0, \ - &(cmdargs).custom_conf.privileged, \ - "Give extended privileges to this container", \ - NULL }, \ - { CMD_OPT_TYPE_BOOL, false, "tty", 't', &(cmdargs).custom_conf.tty, "Allocate a pseudo-TTY", NULL }, \ - { CMD_OPT_TYPE_STRING, \ - false, \ - "restart", \ - 0, \ - &(cmdargs).restart, \ - "Restart policy to apply when a container exits(no, always, on-reboot, on-failure[:max-retries])", \ - NULL }, \ - { CMD_OPT_TYPE_STRING, \ - false, \ - "host-channel", \ - 0, \ - &(cmdargs).host_channel, \ - "Create share memory between host and container", \ - NULL }, \ - { CMD_OPT_TYPE_STRING, \ - false, \ - "runtime", \ - 'R', \ - &(cmdargs).runtime, \ - "Runtime to use for containers(default: lcr)", \ - NULL }, \ - { CMD_OPT_TYPE_STRING_DUP, \ - false, \ - "user", \ - 'u', \ - &(cmdargs).custom_conf.user, \ - "Username or UID (format: [:])", \ - NULL }, \ - { CMD_OPT_TYPE_STRING_DUP, false, "uts", 0, &(cmdargs).custom_conf.share_ns[NAMESPACE_UTS], \ - "UTS namespace to use", NULL }, \ - { CMD_OPT_TYPE_CALLBACK, false, "volume", 'v', &(cmdargs).custom_conf.volumes, "Bind mount a volume", \ - command_append_array }, \ - { CMD_OPT_TYPE_CALLBACK, false, "annotation", 0, &(cmdargs), "Set annotations on a container", \ - callback_annotation }, \ - { CMD_OPT_TYPE_STRING_DUP, \ - false, \ - "workdir", \ - 0, \ - &(cmdargs).custom_conf.workdir, \ - "Working directory inside the container", \ - NULL }, \ - { CMD_OPT_TYPE_BOOL, \ - false, \ - "system-container", \ - 0, \ - &(cmdargs).custom_conf.system_container, \ - "Extend some features only needed by running system container", \ - NULL }, \ - { CMD_OPT_TYPE_BOOL, false, "oom-kill-disable", 0, &(cmdargs).custom_conf.oom_kill_disable, \ - "Disable OOM Killer", NULL }, \ - { CMD_OPT_TYPE_CALLBACK, \ - false, \ - "security-opt", \ - 0, \ - &(cmdargs).custom_conf.security, \ - "Security Options (default [])", \ - command_append_array }, \ - { CMD_OPT_TYPE_CALLBACK, \ - false, \ - "storage-opt", \ - 0, \ - &(cmdargs).custom_conf.storage_opts, \ - "Storage driver options for the container", \ - command_append_array }, \ - { CMD_OPT_TYPE_STRING_DUP, false, "health-cmd", 0, &(cmdargs).custom_conf.health_cmd, \ - "Command to run to check health", NULL }, \ - { CMD_OPT_TYPE_CALLBACK, false, "sysctl", 0, &(cmdargs).custom_conf.sysctls, "Sysctl options", \ - command_append_array }, \ - { CMD_OPT_TYPE_STRING_DUP, \ - false, \ - "env-target-file", \ - 0, \ - &(cmdargs).custom_conf.env_target_file, \ - "Export env to target file path in rootfs", \ - NULL }, \ - { CMD_OPT_TYPE_STRING_DUP, \ - false, \ - "cgroup-parent", \ - 0, \ - &(cmdargs).custom_conf.cgroup_parent, \ - "Optional parent cgroup for the container", \ - NULL }, \ - { CMD_OPT_TYPE_CALLBACK, \ - false, \ - "health-interval", \ - 0, \ - &(cmdargs).custom_conf.health_interval, \ - "Time between running the check (ms|s|m|h) (default 30s)", \ - command_convert_nanoseconds }, \ - { CMD_OPT_TYPE_CALLBACK, \ - false, \ - "health-retries", \ - 0, \ - &(cmdargs).custom_conf.health_retries, \ - "Consecutive failures needed to report unhealthy (default 3)", \ - command_convert_int }, \ - { CMD_OPT_TYPE_CALLBACK, \ - false, \ - "health-timeout", \ - 0, \ - &(cmdargs).custom_conf.health_timeout, \ - "Maximum time to allow one check to run (ms|s|m|h) (default 30s)", \ - command_convert_nanoseconds }, \ - { CMD_OPT_TYPE_CALLBACK, \ - false, \ - "health-start-period", \ - 0, \ - &(cmdargs).custom_conf.health_start_period, \ - "Start period for the container to initialize before starting health-retries countdown (ms|s|m|h) " \ - "(default 0s)", \ - command_convert_nanoseconds }, \ - { CMD_OPT_TYPE_BOOL, \ - false, \ - "no-healthcheck", \ - 0, \ - &(cmdargs).custom_conf.no_healthcheck, \ - "Disable any container-specified HEALTHCHECK", \ - NULL }, \ - { CMD_OPT_TYPE_BOOL, \ - false, \ - "health-exit-on-unhealthy", \ - 0, \ - &(cmdargs).custom_conf.exit_on_unhealthy, \ - "Kill the container when it is detected to be unhealthy", \ - NULL }, \ - { CMD_OPT_TYPE_STRING, \ - false, \ - "ns-change-opt", \ - 0, \ - &(cmdargs).custom_conf.ns_change_opt, \ - "Namespaced kernel param options for system container (default [])", \ - NULL }, \ - { CMD_OPT_TYPE_CALLBACK, false, "ulimit", 0, &(cmdargs).custom_conf.ulimits, "Ulimit options (default [])", \ - command_append_array }, +#define CREATE_OPTIONS(cmdargs) \ + { \ + CMD_OPT_TYPE_BOOL, \ + false, \ + "read-only", \ + 0, \ + &(cmdargs).custom_conf.readonly, \ + "Make container rootfs readonly", \ + NULL \ + }, \ + { CMD_OPT_TYPE_CALLBACK, \ + false, \ + "cap-add", \ + 0, \ + &(cmdargs).custom_conf.cap_adds, \ + "Add Linux capabilities ('ALL' to add all capabilities)", \ + command_append_array }, \ + { CMD_OPT_TYPE_CALLBACK, \ + false, \ + "cap-drop", \ + 0, \ + &(cmdargs).custom_conf.cap_drops, \ + "Drop Linux capabilities ('ALL' to drop all capabilities)", \ + command_append_array }, \ + { CMD_OPT_TYPE_CALLBACK, false, "cpu-shares", 0, &(cmdargs).cr.cpu_shares, "CPU shares (relative weight)", \ + command_convert_llong }, \ + { CMD_OPT_TYPE_CALLBACK, \ + false, \ + "cpu-period", \ + 0, \ + &(cmdargs).cr.cpu_period, \ + "Limit CPU CFS (Completely Fair Scheduler) period", \ + command_convert_llong }, \ + { CMD_OPT_TYPE_CALLBACK, \ + false, \ + "cpu-quota", \ + 0, \ + &(cmdargs).cr.cpu_quota, \ + "Limit CPU CFS (Completely Fair Scheduler) quota", \ + command_convert_llong }, \ + { CMD_OPT_TYPE_STRING, \ + false, \ + "cpuset-cpus", \ + 0, \ + &(cmdargs).cr.cpuset_cpus, \ + "CPUs in which to allow execution (e.g. 0-3, 0,1)", \ + NULL }, \ + { CMD_OPT_TYPE_STRING, \ + false, \ + "cpuset-mems", \ + 0, \ + &(cmdargs).cr.cpuset_mems, \ + "MEMs in which to allow execution (0-3, 0,1)", \ + NULL }, \ + { CMD_OPT_TYPE_CALLBACK, \ + false, \ + "device-read-bps", \ + 0, \ + &(cmdargs).custom_conf.blkio_throttle_read_bps_device, \ + "Limit read rate (bytes per second) from a device (default []),format: :[], Number is a positive integer", \ + command_append_array }, \ + { CMD_OPT_TYPE_CALLBACK, \ + false, \ + "device-write-bps", \ + 0, \ + &(cmdargs).custom_conf.blkio_throttle_write_bps_device, \ + "Limit write rate (bytes per second) to a device (default []),format: :[], Number is a positive integer", \ + command_append_array }, \ + { CMD_OPT_TYPE_CALLBACK, \ + false, \ + "oom-score-adj", \ + 0, \ + &(cmdargs).cr.oom_score_adj, \ + "Tune host's OOM preferences (-1000 to 1000)", \ + command_convert_llong }, \ + { CMD_OPT_TYPE_CALLBACK, \ + false, \ + "device", \ + 0, \ + &(cmdargs).custom_conf.devices, \ + "Add a host device to the container", \ + command_append_array }, \ + { CMD_OPT_TYPE_CALLBACK, false, "env", 'e', &(cmdargs).custom_conf.env, "Set environment variables", \ + command_append_array }, \ + { CMD_OPT_TYPE_CALLBACK, \ + false, \ + "env-file", \ + 0, \ + &(cmdargs).custom_conf.env_file, \ + "Read in a file of environment variables", \ + command_append_array }, \ + { CMD_OPT_TYPE_CALLBACK, \ + false, \ + "label", \ + 'l', \ + &(cmdargs).custom_conf.label, \ + "Set metadata on container (default [])", \ + command_append_array }, \ + { CMD_OPT_TYPE_CALLBACK, \ + false, \ + "label-file", \ + 0, \ + &(cmdargs).custom_conf.label_file, \ + "Read in a line delimited file of labels (default [])", \ + command_append_array }, \ + { CMD_OPT_TYPE_STRING_DUP, \ + false, \ + "entrypoint", \ + 0, \ + &(cmdargs).custom_conf.entrypoint, \ + "Entrypoint to run when starting the container", \ + NULL }, \ + { CMD_OPT_TYPE_STRING, \ + false, \ + "external-rootfs", \ + 0, \ + &(cmdargs).external_rootfs, \ + "Specify the custom rootfs that is not managed by isulad for the container, directory or block device", \ + NULL }, \ + { CMD_OPT_TYPE_CALLBACK, \ + false, \ + "files-limit", \ + 0, \ + &(cmdargs).custom_conf.files_limit, \ + "Tune container files limit (set -1 for unlimited)", \ + command_convert_llong }, \ + { CMD_OPT_TYPE_STRING_DUP, \ + false, \ + "hook-spec", \ + 0, \ + &(cmdargs).custom_conf.hook_spec, \ + "File containing hook definition(prestart, poststart, poststop)", \ + NULL }, \ + { CMD_OPT_TYPE_STRING_DUP, false, "hostname", 'h', &(cmdargs).custom_conf.hostname, \ + "Container host name", NULL }, \ + { CMD_OPT_TYPE_CALLBACK, \ + false, \ + "add-host", \ + 0, \ + &(cmdargs).custom_conf.extra_hosts, \ + "Add a custom host-to-IP mapping (host:ip)", \ + command_append_array }, \ + { CMD_OPT_TYPE_CALLBACK, false, "dns", 0, &(cmdargs).custom_conf.dns, "Set custom DNS servers", \ + command_append_array }, \ + { CMD_OPT_TYPE_CALLBACK, false, "dns-opt", 0, &(cmdargs).custom_conf.dns_options, "Set DNS options", \ + command_append_array }, \ + { CMD_OPT_TYPE_CALLBACK, \ + false, \ + "dns-search", \ + 0, \ + &(cmdargs).custom_conf.dns_search, \ + "Set custom DNS search domains", \ + command_append_array }, \ + { CMD_OPT_TYPE_STRING, \ + false, \ + "user-remap", \ + 0, \ + &(cmdargs).custom_conf.user_remap, \ + "Set user remap for container", \ + NULL }, \ + { CMD_OPT_TYPE_STRING_DUP, false, "ipc", 0, &(cmdargs).custom_conf.share_ns[NAMESPACE_IPC], \ + "IPC namespace to use", NULL }, \ + { CMD_OPT_TYPE_CALLBACK, \ + false, \ + "shm-size", \ + 0, \ + &(cmdargs).custom_conf.shm_size, \ + "Size of /dev/shm, default value is 64MB", \ + command_convert_membytes }, \ + { CMD_OPT_TYPE_CALLBACK, \ + false, \ + "kernel-memory", \ + 0, \ + &(cmdargs).cr.kernel_memory_limit, \ + "Kernel memory limit", \ + command_convert_membytes }, \ + { CMD_OPT_TYPE_CALLBACK, \ + false, \ + "hugetlb-limit", \ + 0, \ + &(cmdargs).custom_conf.hugepage_limits, \ + "Huge page limit (format: [size:], e.g. --hugetlb-limit 2MB:32MB)", \ + command_append_array }, \ + { CMD_OPT_TYPE_CALLBACK, \ + false, \ + "log-driver", \ + 0, \ + &(cmdargs), \ + "Container log driver, support syslog and json-file", \ + callback_log_driver }, \ + { CMD_OPT_TYPE_CALLBACK, false, "log-opt", 0, &(cmdargs), "Container log options, value formate: key=value", \ + callback_log_opt }, \ + { CMD_OPT_TYPE_CALLBACK, false, "memory", 'm', &(cmdargs).cr.memory_limit, "Memory limit", \ + command_convert_membytes }, \ + { CMD_OPT_TYPE_CALLBACK, \ + false, \ + "memory-reservation", \ + 0, \ + &(cmdargs).cr.memory_reservation, \ + "Memory soft limit", \ + command_convert_membytes }, \ + { CMD_OPT_TYPE_CALLBACK, \ + false, \ + "memory-swap", \ + 0, \ + &(cmdargs).cr.memory_swap, \ + "Swap limit equal to memory plus swap: '-1' to enable unlimited swap", \ + command_convert_memswapbytes }, \ + { CMD_OPT_TYPE_CALLBACK, false, \ + "memory-swappiness", 0, \ + &(cmdargs).cr.swappiness, "Tune container memory swappiness (0 to 100) (default -1)", \ + command_convert_swappiness }, \ + { CMD_OPT_TYPE_CALLBACK, \ + false, \ + "mount", \ + 0, \ + &(cmdargs).custom_conf.mounts, \ + "Attach a filesystem mount to the service", \ + command_append_array }, \ + { CMD_OPT_TYPE_CALLBACK, \ + false, \ + "group-add", \ + 0, \ + &(cmdargs).custom_conf.group_add, \ + "Add additional groups to join", \ + command_append_array }, \ + { CMD_OPT_TYPE_STRING_DUP, false, "name", 'n', &(cmdargs).name, "Name of the container", NULL }, \ + { CMD_OPT_TYPE_STRING_DUP, \ + false, \ + "net", \ + 0, \ + &(cmdargs).custom_conf.share_ns[NAMESPACE_NET], \ + "Connect a container to a network", \ + NULL }, \ + { CMD_OPT_TYPE_STRING_DUP, false, "pid", 0, &(cmdargs).custom_conf.share_ns[NAMESPACE_PID], \ + "PID namespace to use", NULL }, \ + { CMD_OPT_TYPE_CALLBACK, \ + false, \ + "pids-limit", \ + 0, \ + &(cmdargs).custom_conf.pids_limit, \ + "Tune container pids limit (set -1 for unlimited)", \ + command_convert_llong }, \ + { CMD_OPT_TYPE_BOOL, \ + false, \ + "privileged", \ + 0, \ + &(cmdargs).custom_conf.privileged, \ + "Give extended privileges to this container", \ + NULL }, \ + { CMD_OPT_TYPE_BOOL, false, "tty", 't', &(cmdargs).custom_conf.tty, "Allocate a pseudo-TTY", NULL }, \ + { CMD_OPT_TYPE_STRING, \ + false, \ + "restart", \ + 0, \ + &(cmdargs).restart, \ + "Restart policy to apply when a container exits(no, always, on-reboot, on-failure[:max-retries])", \ + NULL }, \ + { CMD_OPT_TYPE_STRING, \ + false, \ + "host-channel", \ + 0, \ + &(cmdargs).host_channel, \ + "Create share memory between host and container", \ + NULL }, \ + { CMD_OPT_TYPE_STRING, \ + false, \ + "runtime", \ + 'R', \ + &(cmdargs).runtime, \ + "Runtime to use for containers(default: lcr)", \ + NULL }, \ + { CMD_OPT_TYPE_STRING_DUP, \ + false, \ + "user", \ + 'u', \ + &(cmdargs).custom_conf.user, \ + "Username or UID (format: [:])", \ + NULL }, \ + { CMD_OPT_TYPE_STRING_DUP, false, "uts", 0, &(cmdargs).custom_conf.share_ns[NAMESPACE_UTS], \ + "UTS namespace to use", NULL }, \ + { CMD_OPT_TYPE_CALLBACK, false, "volume", 'v', &(cmdargs).custom_conf.volumes, "Bind mount a volume", \ + command_append_array }, \ + { CMD_OPT_TYPE_CALLBACK, false, "annotation", 0, &(cmdargs), "Set annotations on a container", \ + callback_annotation }, \ + { CMD_OPT_TYPE_STRING_DUP, \ + false, \ + "workdir", \ + 0, \ + &(cmdargs).custom_conf.workdir, \ + "Working directory inside the container", \ + NULL }, \ + { CMD_OPT_TYPE_BOOL, \ + false, \ + "system-container", \ + 0, \ + &(cmdargs).custom_conf.system_container, \ + "Extend some features only needed by running system container", \ + NULL }, \ + { CMD_OPT_TYPE_BOOL, false, "oom-kill-disable", 0, &(cmdargs).custom_conf.oom_kill_disable, \ + "Disable OOM Killer", NULL }, \ + { CMD_OPT_TYPE_CALLBACK, \ + false, \ + "security-opt", \ + 0, \ + &(cmdargs).custom_conf.security, \ + "Security Options (default [])", \ + command_append_array }, \ + { CMD_OPT_TYPE_CALLBACK, \ + false, \ + "storage-opt", \ + 0, \ + &(cmdargs).custom_conf.storage_opts, \ + "Storage driver options for the container", \ + command_append_array }, \ + { CMD_OPT_TYPE_STRING_DUP, false, "health-cmd", 0, &(cmdargs).custom_conf.health_cmd, \ + "Command to run to check health", NULL }, \ + { CMD_OPT_TYPE_CALLBACK, false, "sysctl", 0, &(cmdargs).custom_conf.sysctls, "Sysctl options", \ + command_append_array }, \ + { CMD_OPT_TYPE_STRING_DUP, \ + false, \ + "env-target-file", \ + 0, \ + &(cmdargs).custom_conf.env_target_file, \ + "Export env to target file path in rootfs", \ + NULL }, \ + { CMD_OPT_TYPE_STRING_DUP, \ + false, \ + "cgroup-parent", \ + 0, \ + &(cmdargs).custom_conf.cgroup_parent, \ + "Optional parent cgroup for the container", \ + NULL }, \ + { CMD_OPT_TYPE_CALLBACK, \ + false, \ + "health-interval", \ + 0, \ + &(cmdargs).custom_conf.health_interval, \ + "Time between running the check (ms|s|m|h) (default 30s)", \ + command_convert_nanoseconds }, \ + { CMD_OPT_TYPE_CALLBACK, \ + false, \ + "health-retries", \ + 0, \ + &(cmdargs).custom_conf.health_retries, \ + "Consecutive failures needed to report unhealthy (default 3)", \ + command_convert_int }, \ + { CMD_OPT_TYPE_CALLBACK, \ + false, \ + "health-timeout", \ + 0, \ + &(cmdargs).custom_conf.health_timeout, \ + "Maximum time to allow one check to run (ms|s|m|h) (default 30s)", \ + command_convert_nanoseconds }, \ + { CMD_OPT_TYPE_CALLBACK, \ + false, \ + "health-start-period", \ + 0, \ + &(cmdargs).custom_conf.health_start_period, \ + "Start period for the container to initialize before starting health-retries countdown (ms|s|m|h) " \ + "(default 0s)", \ + command_convert_nanoseconds }, \ + { CMD_OPT_TYPE_BOOL, \ + false, \ + "no-healthcheck", \ + 0, \ + &(cmdargs).custom_conf.no_healthcheck, \ + "Disable any container-specified HEALTHCHECK", \ + NULL }, \ + { CMD_OPT_TYPE_BOOL, \ + false, \ + "health-exit-on-unhealthy", \ + 0, \ + &(cmdargs).custom_conf.exit_on_unhealthy, \ + "Kill the container when it is detected to be unhealthy", \ + NULL }, \ + { CMD_OPT_TYPE_STRING, \ + false, \ + "ns-change-opt", \ + 0, \ + &(cmdargs).custom_conf.ns_change_opt, \ + "Namespaced kernel param options for system container (default [])", \ + NULL }, \ + { CMD_OPT_TYPE_CALLBACK, false, "ulimit", 0, &(cmdargs).custom_conf.ulimits, "Ulimit options (default [])", \ + command_append_array }, \ + { CMD_OPT_TYPE_CALLBACK, \ + false, \ + "blkio-weight", \ + 0, \ + &(cmdargs).cr.blkio_weight, \ + "Block IO (relative weight), between 10 and 1000, or 0 to disable (default 0)", \ + command_convert_u16 }, \ + { CMD_OPT_TYPE_CALLBACK, \ + false, \ + "blkio-weight-device", \ + 0, \ + &(cmdargs).custom_conf.weight_devices, \ + "Block IO weight (relative device weight) (default []), format: DEVICE_NAME:WEIGHT, weight value between 10 and 1000, or 0 to disable (default 0)", \ + command_append_array }, \ + { CMD_OPT_TYPE_CALLBACK, \ + false, \ + "device-read-iops", \ + 0, \ + &(cmdargs).custom_conf.blkio_throttle_read_iops_device, \ + "Limit read rate (IO per second) from a device (format: :),number is unsigned 64 bytes integer", \ + command_append_array }, \ + { CMD_OPT_TYPE_CALLBACK, \ + false, \ + "device-write-iops", \ + 0, \ + &(cmdargs).custom_conf.blkio_throttle_write_iops_device, \ + "Limit write rate (IO per second) to a device (format: :),number is unsigned 64 bytes integer.", \ + command_append_array }, \ + { CMD_OPT_TYPE_CALLBACK, \ + false, \ + "cpu-rt-period", \ + 0, \ + &((cmdargs).cr).cpu_rt_period, \ + "Limit CPU real-time period in microseconds.", \ + command_convert_llong }, \ + { CMD_OPT_TYPE_CALLBACK, \ + false, \ + "cpu-rt-runtime", \ + 0, \ + &((cmdargs).cr).cpu_rt_runtime, \ + "Limit CPU real-time runtime in microseconds.", \ + command_convert_llong }, \ + { CMD_OPT_TYPE_CALLBACK, false, "cpus", 0, &((cmdargs).cr).nano_cpus, "Number of CPUs.", \ + command_convert_nanocpus }, \ + { CMD_OPT_TYPE_CALLBACK, \ + false, \ + "device-cgroup-rule", \ + 0, \ + &(cmdargs).custom_conf.device_cgroup_rules, \ + "Add a rule to the cgroup allowed devices list.", \ + command_convert_device_cgroup_rules }, #define CREATE_EXTEND_OPTIONS(cmdargs) \ { CMD_OPT_TYPE_BOOL, \ diff --git a/src/cmd/isula/base/kill.c b/src/cmd/isula/base/kill.c index da1e3ce..e2e532a 100644 --- a/src/cmd/isula/base/kill.c +++ b/src/cmd/isula/base/kill.c @@ -21,7 +21,7 @@ #include "isula_libutils/log.h" #include "isula_connect.h" #include "connect.h" -#include "libisula.h" + #include "utils.h" #include "utils_verify.h" diff --git a/src/cmd/isula/base/rename.c b/src/cmd/isula/base/rename.c index 652e091..aafc9bd 100644 --- a/src/cmd/isula/base/rename.c +++ b/src/cmd/isula/base/rename.c @@ -22,7 +22,6 @@ #include "isula_connect.h" #include "command_parser.h" #include "connect.h" -#include "libisula.h" const char g_cmd_rename_desc[] = "Rename a container"; const char g_cmd_rename_usage[] = "rename [OPTIONS] OLD_NAME NEW_NAME"; diff --git a/src/cmd/isula/base/restart.c b/src/cmd/isula/base/restart.c index 2d58d33..f91ee3b 100644 --- a/src/cmd/isula/base/restart.c +++ b/src/cmd/isula/base/restart.c @@ -21,7 +21,6 @@ #include "utils.h" #include "isula_connect.h" #include "connect.h" -#include "libisula.h" const char g_cmd_restart_desc[] = "Restart one or more containers"; const char g_cmd_restart_usage[] = "restart [OPTIONS] CONTAINER [CONTAINER...]"; diff --git a/src/cmd/isula/base/rm.c b/src/cmd/isula/base/rm.c index eeff9aa..f54fc22 100644 --- a/src/cmd/isula/base/rm.c +++ b/src/cmd/isula/base/rm.c @@ -20,11 +20,10 @@ #include "client_arguments.h" #include "isula_libutils/log.h" #include "isula_connect.h" -#include "isula_commands.h" #include "console.h" #include "utils.h" #include "connect.h" -#include "libisula.h" + #include "utils_file.h" const char g_cmd_delete_desc[] = "Remove one or more containers"; diff --git a/src/cmd/isula/base/run.c b/src/cmd/isula/base/run.c index fa71abb..3225dbf 100644 --- a/src/cmd/isula/base/run.c +++ b/src/cmd/isula/base/run.c @@ -15,7 +15,6 @@ #include #include #include -#include // IWYU pragma: keep #include #include #include @@ -30,7 +29,7 @@ #include "error.h" #include "connect.h" #include "create.h" -#include "libisula.h" + #include "start.h" #include "wait.h" @@ -175,59 +174,6 @@ out: return ret; } -static void *run_console_resize_thread(void *arg) -{ - int ret = 0; - const struct client_arguments *args = arg; - static struct winsize s_pre_wsz; - struct winsize wsz; - - if (!isatty(STDIN_FILENO)) { - goto out; - } - - ret = pthread_detach(pthread_self()); - if (ret != 0) { - CRIT("Start: set thread detach fail"); - goto out; - } - - while (true) { - sleep(1); // check the windows size per 1s - ret = ioctl(STDIN_FILENO, TIOCGWINSZ, &wsz); - if (ret < 0) { - WARN("Failed to get window size"); - continue; - } - if (wsz.ws_row == s_pre_wsz.ws_row && wsz.ws_col == s_pre_wsz.ws_col) { - continue; - } - ret = do_resize_run_console(args, wsz.ws_row, wsz.ws_col); - if (ret != 0) { - continue; - } - s_pre_wsz.ws_row = wsz.ws_row; - s_pre_wsz.ws_col = wsz.ws_col; - } - -out: - return NULL; -} - -int run_client_console_resize_thread(struct client_arguments *args) -{ - int res = 0; - pthread_t a_thread; - - res = pthread_create(&a_thread, NULL, run_console_resize_thread, (void *)(args)); - if (res != 0) { - CRIT("Thread creation failed"); - return -1; - } - - return 0; -} - int cmd_run_main(int argc, const char **argv) { int ret = 0; @@ -241,6 +187,7 @@ int cmd_run_main(int argc, const char **argv) } g_cmd_run_args.custom_conf.attach_stdout = true; g_cmd_run_args.custom_conf.attach_stderr = true; + g_cmd_run_args.resize_cb = do_resize_run_console; g_cmd_run_args.progname = argv[0]; g_cmd_run_args.subcommand = argv[1]; @@ -270,7 +217,7 @@ int cmd_run_main(int argc, const char **argv) } if (g_cmd_run_args.custom_conf.tty && isatty(STDIN_FILENO)) { - (void)run_client_console_resize_thread(&g_cmd_run_args); + (void)start_client_console_resize_thread(&g_cmd_run_args); } if (strncmp(g_cmd_run_args.socket, "tcp://", strlen("tcp://")) == 0) { diff --git a/src/cmd/isula/base/start.c b/src/cmd/isula/base/start.c index 8ed491e..59cd05c 100644 --- a/src/cmd/isula/base/start.c +++ b/src/cmd/isula/base/start.c @@ -30,7 +30,6 @@ #include "isula_commands.h" #include "command_parser.h" #include "connect.h" -#include "libisula.h" const char g_cmd_start_desc[] = "Start one or more stopped containers"; const char g_cmd_start_usage[] = "start [OPTIONS] CONTAINER [CONTAINER...]"; diff --git a/src/cmd/isula/base/start.h b/src/cmd/isula/base/start.h index 112f14a..8633c9c 100644 --- a/src/cmd/isula/base/start.h +++ b/src/cmd/isula/base/start.h @@ -19,7 +19,7 @@ #include #include "client_arguments.h" -#include "isula_commands.h" +#include "client_console.h" #ifdef __cplusplus extern "C" { diff --git a/src/cmd/isula/base/stop.c b/src/cmd/isula/base/stop.c index c4fa666..e52db79 100644 --- a/src/cmd/isula/base/stop.c +++ b/src/cmd/isula/base/stop.c @@ -22,7 +22,6 @@ #include "utils.h" #include "isula_connect.h" #include "connect.h" -#include "libisula.h" const char g_cmd_stop_desc[] = "Stop one or more containers"; const char g_cmd_stop_usage[] = "stop [OPTIONS] CONTAINER [CONTAINER...]"; diff --git a/src/cmd/isula/client_arguments.c b/src/cmd/isula/client_arguments.c index 7160ea7..ad6ba40 100644 --- a/src/cmd/isula/client_arguments.c +++ b/src/cmd/isula/client_arguments.c @@ -148,6 +148,9 @@ void client_arguments_free(struct client_arguments *args) return; } + util_free_sensitive_string(args->username); + util_free_sensitive_string(args->password); + free(args->name); args->name = NULL; @@ -238,6 +241,21 @@ void client_arguments_free(struct client_arguments *args) free(args->key_file); args->key_file = NULL; + + util_free_array(custom_conf->blkio_throttle_read_bps_device); + custom_conf->blkio_throttle_read_bps_device = NULL; + + util_free_array(custom_conf->blkio_throttle_write_bps_device); + custom_conf->blkio_throttle_write_bps_device = NULL; + + util_free_array(custom_conf->blkio_throttle_read_iops_device); + custom_conf->blkio_throttle_read_iops_device = NULL; + + util_free_array(custom_conf->blkio_throttle_write_iops_device); + custom_conf->blkio_throttle_write_iops_device = NULL; + + util_free_array(custom_conf->device_cgroup_rules); + custom_conf->device_cgroup_rules = NULL; } /* print common help */ diff --git a/src/cmd/isula/client_arguments.h b/src/cmd/isula/client_arguments.h index ccd7b03..0ecdb21 100644 --- a/src/cmd/isula/client_arguments.h +++ b/src/cmd/isula/client_arguments.h @@ -20,6 +20,8 @@ #include #include #include +#include // IWYU pragma: keep +#include #include "command_parser.h" #include "isula_libutils/json_common.h" @@ -34,6 +36,8 @@ extern "C" { /* max arguments can be specify in client */ #define MAX_CLIENT_ARGS 1000 +#define CLIENT_RUNDIR "/var/run/isula" + struct client_arguments; struct custom_configs; @@ -183,9 +187,6 @@ struct custom_configs { /* oom kill disable */ bool oom_kill_disable; - /* create/run accel options */ - char **accel; - /* env target file */ char *env_target_file; @@ -197,6 +198,15 @@ struct custom_configs { /* device write bps */ char **blkio_throttle_write_bps_device; + + /* device read iops */ + char **blkio_throttle_read_iops_device; + + /* device write iops */ + char **blkio_throttle_write_iops_device; + + /* device cgroup rules */ + char **device_cgroup_rules; }; struct args_cgroup_resources { @@ -214,8 +224,13 @@ struct args_cgroup_resources { int64_t memory_reservation; int64_t kernel_memory_limit; int64_t swappiness; + int64_t nano_cpus; }; +struct client_arguments; + +typedef int (*do_resize_call_back_t)(const struct client_arguments *args, unsigned int height, unsigned int width); + struct client_arguments { const char *progname; /* main progname name */ const char *subcommand; /* sub command name */ @@ -283,6 +298,7 @@ struct client_arguments { // logs bool follow; + bool timestamps; /* * tail < 0: show all logs * tail = 0: do not show log @@ -325,6 +341,9 @@ struct client_arguments { char *ca_file; char *cert_file; char *key_file; + + do_resize_call_back_t resize_cb; + struct winsize s_pre_wsz; }; #define LOG_OPTIONS(log) { CMD_OPT_TYPE_BOOL_FALSE, false, "debug", 'D', &(log).quiet, "Enable debug mode", NULL }, diff --git a/src/cmd/isula/client_console.c b/src/cmd/isula/client_console.c new file mode 100644 index 0000000..d6d82f7 --- /dev/null +++ b/src/cmd/isula/client_console.c @@ -0,0 +1,319 @@ +/****************************************************************************** + * Copyright (c) Huawei Technologies Co., Ltd. 2017-2019. All rights reserved. + * iSulad licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * 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 v2 for more details. + * Author: lifeng + * Create: 2020-10-20 + * Description: provide container command functions + ******************************************************************************/ +#include "client_console.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "client_arguments.h" +#include "isula_libutils/log.h" +#include "utils.h" +#include "console.h" +#include "utils_file.h" + +/* free command fifo names */ +void free_command_fifo_config(struct command_fifo_config *fifos) +{ + if (fifos != NULL) { + if (fifos->stdin_path != NULL) { + free(fifos->stdin_path); + fifos->stdin_path = NULL; + } + if (fifos->stdout_path != NULL) { + free(fifos->stdout_path); + fifos->stdout_path = NULL; + } + if (fifos->stderr_path != NULL) { + free(fifos->stderr_path); + fifos->stderr_path = NULL; + } + if (fifos->stdin_name != NULL) { + free(fifos->stdin_name); + fifos->stdin_name = NULL; + } + if (fifos->stdout_name != NULL) { + free(fifos->stdout_name); + fifos->stdout_name = NULL; + } + if (fifos->stderr_name != NULL) { + free(fifos->stderr_name); + fifos->stderr_name = NULL; + } + free(fifos); + } +} + +/* delete command fifo */ +void delete_command_fifo(struct command_fifo_config *fifos) +{ + int ret; + + if (fifos == NULL) { + return; + } + + ret = console_fifo_delete(fifos->stdin_name); + if (ret) { + WARN("Delete fifo failed: %s", fifos->stdin_name); + } + ret = console_fifo_delete(fifos->stdout_name); + if (ret) { + WARN("Delete fifo failed: %s", fifos->stdout_name); + } + ret = console_fifo_delete(fifos->stderr_name); + if (ret) { + WARN("Delete fifo failed: %s", fifos->stderr_name); + } + ret = util_recursive_rmdir(fifos->stdin_path, 0); + if (ret) { + WARN("Remove directory failed: %s", fifos->stdin_path); + } + ret = util_recursive_rmdir(fifos->stdout_path, 0); + if (ret) { + WARN("Remove directory failed: %s", fifos->stdout_path); + } + ret = util_recursive_rmdir(fifos->stderr_path, 0); + if (ret) { + WARN("Remove directory failed: %s", fifos->stderr_path); + } + + free_command_fifo_config(fifos); +} + +static int do_create_console_fifo(const char *subpath, const char *stdflag, char **out_fifo_dir, char **out_fifo_name) +{ + int ret = 0; + char fifo_dir[PATH_MAX] = { 0 }; + char fifo_name[PATH_MAX] = { 0 }; + + ret = console_fifo_name(CLIENT_RUNDIR, subpath, stdflag, fifo_name, sizeof(fifo_name), fifo_dir, sizeof(fifo_dir), + true); + if (ret != 0) { + ERROR("Failed to get console fifo name."); + ret = -1; + goto out; + } + + if (console_fifo_create(fifo_name)) { + ERROR("Failed to create console fifo."); + ret = -1; + goto out; + } + + *out_fifo_dir = util_strdup_s(fifo_dir); + *out_fifo_name = util_strdup_s(fifo_name); + +out: + return ret; +} + +int create_console_fifos(bool attach_stdin, bool attach_stdout, bool attach_stderr, const char *name, const char *type, + struct command_fifo_config **pconsole_fifos) +{ + int ret = 0; + char subpath[PATH_MAX] = { 0 }; + struct command_fifo_config *fifos = NULL; + + fifos = util_common_calloc_s(sizeof(struct command_fifo_config)); + if (fifos == NULL) { + ERROR("Failed to malloc memory for FIFO names."); + return -1; + } + + ret = snprintf(subpath, sizeof(subpath), "%s/%s-%u-%u", name, type, (unsigned int)getpid(), + (unsigned int)pthread_self()); + if (ret < 0 || (size_t)ret >= sizeof(subpath)) { + ERROR("Path is too long"); + goto cleanup; + } + + if (attach_stdin) { + ret = do_create_console_fifo(subpath, "in", &fifos->stdin_path, &fifos->stdin_name); + if (ret != 0) { + goto cleanup; + } + INFO("FIFO:%s create for start success.", fifos->stdin_name); + } + + if (attach_stdout) { + ret = do_create_console_fifo(subpath, "out", &fifos->stdout_path, &fifos->stdout_name); + if (ret != 0) { + goto cleanup; + } + INFO("FIFO:%s create for start success.", fifos->stdout_name); + } + + if (attach_stderr) { + ret = do_create_console_fifo(subpath, "err", &fifos->stderr_path, &fifos->stderr_name); + if (ret != 0) { + goto cleanup; + } + INFO("FIFO:%s create for start success.", fifos->stderr_name); + } + + *pconsole_fifos = fifos; + return 0; + +cleanup: + console_fifo_delete(fifos->stdin_name); + console_fifo_delete(fifos->stdout_name); + console_fifo_delete(fifos->stderr_name); + free_command_fifo_config(fifos); + return -1; +} + +struct console_loop_thread_args { + struct command_fifo_config *fifo_config; + bool tty; +}; + +static void *client_console_loop_thread(void *arg) +{ + int ret = 0; + int fifoinfd = -1; + int fifooutfd = -1; + int fifoerrfd = -1; + const struct console_loop_thread_args *args = arg; + bool tty = args->tty; + struct command_fifo_config *fifo_config = args->fifo_config; + sem_t *wait_open = fifo_config->wait_open; + sem_t *wait_exit = fifo_config->wait_exit; + + ret = pthread_detach(pthread_self()); + if (ret != 0) { + CRIT("Start: set thread detach fail"); + goto err1; + } + + if (fifo_config->stdin_name) { + if (console_fifo_open_withlock(fifo_config->stdin_name, &fifoinfd, O_RDWR | O_NONBLOCK)) { + ERROR("Start: failed to open console fifo."); + goto err2; + } + INFO("FIFO:%s open success for start.", fifo_config->stdin_name); + } + + if (fifo_config->stdout_name) { + if (console_fifo_open(fifo_config->stdout_name, &fifooutfd, O_RDONLY | O_NONBLOCK)) { + ERROR("Failed to open console fifo."); + goto err2; + } + INFO("FIFO:%s open success for start.", fifo_config->stdout_name); + } + + if (fifo_config->stderr_name) { + if (console_fifo_open(fifo_config->stderr_name, &fifoerrfd, O_RDONLY | O_NONBLOCK)) { + ERROR("Start: failed to open console fifo."); + goto err2; + } + INFO("FIFO:%s open success for start.", fifo_config->stderr_name); + } + + sem_post(wait_open); + console_loop_with_std_fd(0, 1, 2, fifoinfd, fifooutfd, fifoerrfd, 1, tty); + +err2: + if (fifoinfd >= 0) { + console_fifo_close(fifoinfd); + } + if (fifooutfd >= 0) { + console_fifo_close(fifooutfd); + } + if (fifoerrfd >= 0) { + console_fifo_close(fifoerrfd); + } +err1: + sem_post(wait_open); + sem_post(wait_exit); + return NULL; +} + +int start_client_console_thread(struct command_fifo_config *console_fifos, bool tty) +{ + int res = 0; + pthread_t a_thread; + struct console_loop_thread_args args; + + args.fifo_config = console_fifos; + args.tty = tty; + res = pthread_create(&a_thread, NULL, client_console_loop_thread, (void *)(&args)); + if (res != 0) { + CRIT("Thread creation failed"); + return -1; + } + + sem_wait(console_fifos->wait_open); + + return 0; +} + +static void *client_console_resize_thread(void *arg) +{ + int ret = 0; + struct client_arguments *args = arg; + struct winsize wsz = { 0 }; + + if (!isatty(STDIN_FILENO)) { + goto out; + } + + ret = pthread_detach(pthread_self()); + if (ret != 0) { + CRIT("Start: set thread detach fail"); + goto out; + } + + while (true) { + sleep(1); // check the windows size per 1s + ret = ioctl(STDIN_FILENO, TIOCGWINSZ, &wsz); + if (ret < 0) { + WARN("Failed to get window size"); + continue; + } + if (wsz.ws_row == args->s_pre_wsz.ws_row && wsz.ws_col == args->s_pre_wsz.ws_col) { + continue; + } + if (args->resize_cb != NULL) { + ret = args->resize_cb(args, wsz.ws_row, wsz.ws_col); + if (ret != 0) { + continue; + } + args->s_pre_wsz.ws_row = wsz.ws_row; + args->s_pre_wsz.ws_col = wsz.ws_col; + } + } + +out: + return NULL; +} + +int start_client_console_resize_thread(struct client_arguments *args) +{ + int res = 0; + pthread_t a_thread; + + res = pthread_create(&a_thread, NULL, client_console_resize_thread, (void *)(args)); + if (res != 0) { + CRIT("Thread creation failed"); + return -1; + } + + return 0; +} \ No newline at end of file diff --git a/src/cmd/isula/client_console.h b/src/cmd/isula/client_console.h new file mode 100644 index 0000000..c264820 --- /dev/null +++ b/src/cmd/isula/client_console.h @@ -0,0 +1,52 @@ +/****************************************************************************** + * Copyright (c) Huawei Technologies Co., Ltd. 2017-2019. All rights reserved. + * iSulad licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * 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 v2 for more details. + * Author: lifeng + * Create: 2020-10-20 + * Description: provide client console functions + ******************************************************************************/ +#ifndef CMD_ISULA_CLIENT_CONSOLE_H +#define CMD_ISULA_CLIENT_CONSOLE_H + +#include +#include +#include "client_arguments.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct command_fifo_config { + char *stdin_path; + char *stdout_path; + char *stderr_path; + char *stdin_name; + char *stdout_name; + char *stderr_name; + sem_t *wait_open; + sem_t *wait_exit; +}; + +int create_console_fifos(bool attach_stdin, bool attach_stdout, bool attach_stderr, const char *name, const char *type, + struct command_fifo_config **pconsole_fifos); + +int start_client_console_thread(struct command_fifo_config *console_fifos, bool tty); + +void free_command_fifo_config(struct command_fifo_config *fifos); + +void delete_command_fifo(struct command_fifo_config *fifos); + +int start_client_console_resize_thread(struct client_arguments *args); + +#ifdef __cplusplus +} +#endif + +#endif // CMD_ISULA_ISULA_COMMANDS_H diff --git a/src/cmd/isula/extend/events.c b/src/cmd/isula/extend/events.c index 3040e28..3a10200 100644 --- a/src/cmd/isula/extend/events.c +++ b/src/cmd/isula/extend/events.c @@ -22,7 +22,7 @@ #include "isula_libutils/log.h" #include "isula_connect.h" #include "connect.h" -#include "libisula.h" + #include "utils.h" #include "utils_timestamp.h" @@ -132,7 +132,7 @@ static void print_events_callback(const container_events_format_t *event) return; } - if (!get_time_buffer(&(event->timestamp), timebuffer, sizeof(timebuffer))) { + if (!util_get_time_buffer(&(event->timestamp), timebuffer, sizeof(timebuffer))) { (void)strcpy(timebuffer, "-"); } @@ -176,13 +176,13 @@ static int client_event(struct client_arguments *args) goto out; } - if (args->since && !get_timestamp(args->since, &request.since)) { + if (args->since && !util_get_timestamp(args->since, &request.since)) { COMMAND_ERROR("Failed to get since timestamp"); ret = -1; goto out; } - if (args->until && !get_timestamp(args->until, &request.until)) { + if (args->until && !util_get_timestamp(args->until, &request.until)) { COMMAND_ERROR("Failed to get until timestamp"); ret = -1; goto out; diff --git a/src/cmd/isula/extend/export.c b/src/cmd/isula/extend/export.c index fd3bb4d..476cf77 100644 --- a/src/cmd/isula/extend/export.c +++ b/src/cmd/isula/extend/export.c @@ -26,7 +26,6 @@ #include "isula_libutils/log.h" #include "isula_connect.h" #include "connect.h" -#include "libisula.h" const char g_cmd_export_desc[] = "export container"; const char g_cmd_export_usage[] = "export [command options] [ID|NAME]"; diff --git a/src/cmd/isula/extend/pause.c b/src/cmd/isula/extend/pause.c index f4db507..4d508e7 100644 --- a/src/cmd/isula/extend/pause.c +++ b/src/cmd/isula/extend/pause.c @@ -24,7 +24,6 @@ #include "isula_connect.h" #include "command_parser.h" #include "connect.h" -#include "libisula.h" const char g_cmd_pause_desc[] = "Pause all processes within one or more containers"; const char g_cmd_pause_usage[] = "pause [OPTIONS] CONTAINER [CONTAINER...]"; diff --git a/src/cmd/isula/extend/resume.c b/src/cmd/isula/extend/resume.c index 0a020b6..c3c4376 100644 --- a/src/cmd/isula/extend/resume.c +++ b/src/cmd/isula/extend/resume.c @@ -24,7 +24,6 @@ #include "isula_connect.h" #include "command_parser.h" #include "connect.h" -#include "libisula.h" const char g_cmd_resume_desc[] = "Unpause all processes within one or more containers"; const char g_cmd_resume_usage[] = "unpause [OPTIONS] CONTAINER [CONTAINER...]"; diff --git a/src/cmd/isula/extend/stats.c b/src/cmd/isula/extend/stats.c index da0ce03..14c6159 100644 --- a/src/cmd/isula/extend/stats.c +++ b/src/cmd/isula/extend/stats.c @@ -26,7 +26,6 @@ #include "isula_libutils/log.h" #include "isula_connect.h" #include "connect.h" -#include "libisula.h" #define ESC "\033" #define TERMCLEAR ESC "[H" ESC "[J" @@ -140,8 +139,8 @@ static void stats_print(const struct isula_container_info *stats) static void stats_print_original_data_header(void) { printf("%-16s %-10s %-10s %-20s %-20s %-15s %-15s %-15s %-15s %-15s %-15s %-15s %-40s", "ID", "PIDS", "Status", - "CpuUseNanos", "CpuSystemUse", "OnlineCpus", "BlkioRead", "BlkioWrite", "MemUsed", "MemLimit", - "KmemUsed", "CacheUsage", "NAME"); + "CpuUseNanos", "CpuSystemUse", "OnlineCpus", "BlkioRead", "BlkioWrite", "MemUsed", "MemLimit", "KmemUsed", + "CacheUsage", "NAME"); printf("\n"); } @@ -157,8 +156,8 @@ static void stats_print_original_data(const struct isula_container_info *stats) printf("%-16s %-10llu %-10s %-20lu %-20lu %-15u %-15lu %-15lu %-15lu %-15lu %-15lu %-15lu %-40s", short_id, (unsigned long long)stats->pids_current, stats->status, stats->cpu_use_nanos, stats->cpu_system_use, - stats->online_cpus, stats->blkio_read, stats->blkio_write, stats->mem_used, stats->mem_limit, stats->kmem_used, - stats->cache, stats->name); + stats->online_cpus, stats->blkio_read, stats->blkio_write, stats->mem_used, stats->mem_limit, + stats->kmem_used, stats->cache, stats->name); free(short_id); } diff --git a/src/cmd/isula/extend/update.c b/src/cmd/isula/extend/update.c index 84240a1..da472b0 100644 --- a/src/cmd/isula/extend/update.c +++ b/src/cmd/isula/extend/update.c @@ -12,17 +12,18 @@ * Create: 2018-11-08 * Description: provide container update functions ******************************************************************************/ -#include +#include "update.h" + #include #include #include "client_arguments.h" -#include "update.h" #include "utils.h" #include "isula_libutils/log.h" #include "isula_connect.h" #include "connect.h" -#include "libisula.h" + +#include "isula_host_spec.h" const char g_cmd_update_desc[] = "Update configuration of one or more containers"; const char g_cmd_update_usage[] = "update [OPTIONS] CONTAINER [CONTAINER...]"; @@ -31,57 +32,88 @@ struct client_arguments g_cmd_update_args = { .restart = NULL, }; -static int pack_update_request(const struct client_arguments *args, struct isula_update_request *request) +static isula_host_config_t *pack_update_request(const struct client_arguments *args) { - int ret = 0; + isula_host_config_t *host_config = NULL; - request->updateconfig->restart_policy = args->restart; + host_config = util_common_calloc_s(sizeof(isula_host_config_t)); + if (host_config == NULL) { + COMMAND_ERROR("Memeory out"); + goto error_out; + } + host_config->restart_policy = util_strdup_s(args->restart); - request->updateconfig->cr->blkio_weight = args->cr.blkio_weight; + host_config->cr = util_common_calloc_s(sizeof(container_cgroup_resources_t)); + if (host_config->cr == NULL) { + COMMAND_ERROR("Memeory out"); + goto error_out; + } - request->updateconfig->cr->cpu_shares = args->cr.cpu_shares; + host_config->cr->blkio_weight = args->cr.blkio_weight; - request->updateconfig->cr->cpu_period = args->cr.cpu_period; + host_config->cr->nano_cpus = args->cr.nano_cpus; - request->updateconfig->cr->cpu_quota = args->cr.cpu_quota; + host_config->cr->cpu_shares = args->cr.cpu_shares; - request->updateconfig->cr->cpuset_cpus = args->cr.cpuset_cpus; + host_config->cr->cpu_period = args->cr.cpu_period; - request->updateconfig->cr->cpuset_mems = args->cr.cpuset_mems; + host_config->cr->cpu_quota = args->cr.cpu_quota; - request->updateconfig->cr->memory = args->cr.memory_limit; + host_config->cr->cpu_realtime_period = args->cr.cpu_rt_period; - request->updateconfig->cr->memory_swap = args->cr.memory_swap; + host_config->cr->cpu_realtime_runtime = args->cr.cpu_rt_runtime; - request->updateconfig->cr->memory_reservation = args->cr.memory_reservation; + host_config->cr->cpuset_cpus = util_strdup_s(args->cr.cpuset_cpus); - request->updateconfig->cr->kernel_memory = args->cr.kernel_memory_limit; + host_config->cr->cpuset_mems = util_strdup_s(args->cr.cpuset_mems); - return ret; + host_config->cr->memory = args->cr.memory_limit; + + host_config->cr->memory_swap = args->cr.memory_swap; + + host_config->cr->memory_reservation = args->cr.memory_reservation; + + host_config->cr->kernel_memory = args->cr.kernel_memory_limit; + + return host_config; + +error_out: + isula_host_config_free(host_config); + return NULL; } static int client_update(const struct client_arguments *args) { int ret = 0; isula_connect_ops *ops = NULL; - container_cgroup_resources_t cr = { 0 }; - isula_update_config_t updateconfig = { 0 }; - struct isula_update_request request = { 0 }; + isula_host_config_t *host_spec = NULL; + struct isula_update_request *request = NULL; struct isula_update_response *response = NULL; client_connect_config_t config = { 0 }; + request = util_common_calloc_s(sizeof(struct isula_update_request)); + if (request == NULL) { + ERROR("Out of memory"); + ret = -1; + goto out; + } + response = util_common_calloc_s(sizeof(struct isula_update_response)); if (response == NULL) { ERROR("Out of memory"); - return -1; + ret = -1; + goto out; } - updateconfig.cr = &cr; - request.updateconfig = &updateconfig; - request.name = args->name; + request->name = util_strdup_s(args->name); - ret = pack_update_request(args, &request); - if (ret) { + host_spec = pack_update_request(args); + if (host_spec == NULL) { + ret = -1; + goto out; + } + + if (generate_hostconfig(host_spec, &request->host_spec_json) != 0) { ret = -1; goto out; } @@ -94,13 +126,15 @@ static int client_update(const struct client_arguments *args) } config = get_connect_config(args); - ret = ops->container.update(&request, response, &config); + ret = ops->container.update(request, response, &config); if (ret) { client_print_error(response->cc, response->server_errono, response->errmsg); goto out; } out: + isula_host_config_free(host_spec); + isula_update_request_free(request); isula_update_response_free(response); return ret; } @@ -111,8 +145,8 @@ int cmd_update_main(int argc, const char **argv) int i = 0; struct isula_libutils_log_config lconf = { 0 }; command_t cmd; - struct command_option options[] = { LOG_OPTIONS(lconf) UPDATE_OPTIONS(g_cmd_update_args), - COMMON_OPTIONS(g_cmd_update_args) + struct command_option options[] = { LOG_OPTIONS(lconf) UPDATE_OPTIONS(g_cmd_update_args) + COMMON_OPTIONS(g_cmd_update_args) }; isula_libutils_default_log_config(argv[0], &lconf); diff --git a/src/cmd/isula/extend/update.h b/src/cmd/isula/extend/update.h index 361f10b..a527b46 100644 --- a/src/cmd/isula/extend/update.h +++ b/src/cmd/isula/extend/update.h @@ -79,10 +79,36 @@ extern "C" { &(cmdargs).cr.memory_swap, \ "Swap limit equal to memory plus swap: '-1' to enable unlimited swap", \ command_convert_memswapbytes }, \ - { \ - CMD_OPT_TYPE_STRING, false, "restart", 0, &(cmdargs).restart, \ - "Restart policy to apply when a container exits", NULL \ - } + { CMD_OPT_TYPE_STRING, \ + false, \ + "restart", \ + 0, \ + &(cmdargs).restart, \ + "Restart policy to apply when a container exits", \ + NULL }, \ + { CMD_OPT_TYPE_CALLBACK, \ + false, \ + "blkio-weight", \ + 0, \ + &(cmdargs).cr.blkio_weight, \ + "Block IO (relative weight), between 10 and 1000, or 0 to disable (default 0)", \ + command_convert_u16 }, \ + { CMD_OPT_TYPE_CALLBACK, \ + false, \ + "cpu-rt-period", \ + 0, \ + &((cmdargs).cr).cpu_rt_period, \ + "Limit CPU real-time period in microseconds.", \ + command_convert_llong }, \ + { CMD_OPT_TYPE_CALLBACK, \ + false, \ + "cpu-rt-runtime", \ + 0, \ + &((cmdargs).cr).cpu_rt_runtime, \ + "Limit CPU real-time runtime in microseconds.", \ + command_convert_llong }, \ + { CMD_OPT_TYPE_CALLBACK, false, "cpus", 0, &((cmdargs).cr).nano_cpus, "Number of CPUs.", \ + command_convert_nanocpus }, extern const char g_cmd_update_desc[]; extern const char g_cmd_update_usage[]; diff --git a/src/cmd/isula/images/images.c b/src/cmd/isula/images/images.c index c028bc7..f60e750 100644 --- a/src/cmd/isula/images/images.c +++ b/src/cmd/isula/images/images.c @@ -28,7 +28,7 @@ #include "isula_libutils/log.h" #include "command_parser.h" #include "connect.h" -#include "libisula.h" + #include "utils_array.h" #include "utils_file.h" #include "utils_verify.h" diff --git a/src/cmd/isula/images/import.c b/src/cmd/isula/images/import.c index 5d84274..2dcc648 100644 --- a/src/cmd/isula/images/import.c +++ b/src/cmd/isula/images/import.c @@ -27,7 +27,7 @@ #include "isula_libutils/log.h" #include "command_parser.h" #include "connect.h" -#include "libisula.h" + #include "utils_verify.h" const char g_cmd_import_desc[] = "Import the contents from a tarball to create a filesystem image"; diff --git a/src/cmd/isula/images/load.c b/src/cmd/isula/images/load.c index c804ebf..343d8d6 100644 --- a/src/cmd/isula/images/load.c +++ b/src/cmd/isula/images/load.c @@ -26,7 +26,6 @@ #include "isula_connect.h" #include "isula_libutils/log.h" #include "connect.h" -#include "libisula.h" #ifdef ENABLE_EMBEDDED_IMAGE const char g_cmd_load_desc[] = "load an image from a manifest or a tar archive"; diff --git a/src/cmd/isula/images/login.c b/src/cmd/isula/images/login.c index 32d6ea9..9255035 100644 --- a/src/cmd/isula/images/login.c +++ b/src/cmd/isula/images/login.c @@ -24,7 +24,6 @@ #include "isula_connect.h" #include "isula_libutils/log.h" #include "connect.h" -#include "libisula.h" const char g_cmd_login_desc[] = "Log in to a Docker registry"; const char g_cmd_login_usage[] = "login [OPTIONS] SERVER"; @@ -216,6 +215,8 @@ int cmd_login_main(int argc, const char **argv) } ret = client_login(&g_cmd_login_args); + util_free_sensitive_string(g_cmd_login_args.username); + util_free_sensitive_string(g_cmd_login_args.password); if (ret != 0) { exit(exit_code); } diff --git a/src/cmd/isula/images/login.h b/src/cmd/isula/images/login.h index dad619a..5f9a676 100644 --- a/src/cmd/isula/images/login.h +++ b/src/cmd/isula/images/login.h @@ -25,8 +25,8 @@ extern "C" { #endif #define LOGIN_OPTIONS(cmdargs) \ - { CMD_OPT_TYPE_STRING, false, "username", 'u', &(cmdargs).username, "Username", NULL }, \ - { CMD_OPT_TYPE_STRING, false, "password", 'p', &(cmdargs).password, "Password", NULL }, \ + { CMD_OPT_TYPE_STRING_DUP, false, "username", 'u', &(cmdargs).username, "Username", NULL }, \ + { CMD_OPT_TYPE_STRING_DUP, false, "password", 'p', &(cmdargs).password, "Password", NULL }, \ { CMD_OPT_TYPE_BOOL, \ false, \ "password-stdin", \ diff --git a/src/cmd/isula/images/logout.c b/src/cmd/isula/images/logout.c index 12645d4..8efec1e 100644 --- a/src/cmd/isula/images/logout.c +++ b/src/cmd/isula/images/logout.c @@ -23,7 +23,6 @@ #include "isula_libutils/log.h" #include "command_parser.h" #include "connect.h" -#include "libisula.h" const char g_cmd_logout_desc[] = "Log out from a Docker registry"; const char g_cmd_logout_usage[] = "logout SERVER"; diff --git a/src/cmd/isula/images/pull.c b/src/cmd/isula/images/pull.c index fff8898..b72b030 100644 --- a/src/cmd/isula/images/pull.c +++ b/src/cmd/isula/images/pull.c @@ -23,7 +23,6 @@ #include "isula_libutils/log.h" #include "command_parser.h" #include "connect.h" -#include "libisula.h" const char g_cmd_pull_desc[] = "Pull an image or a repository from a registry"; const char g_cmd_pull_usage[] = "pull [OPTIONS] NAME[:TAG|@DIGEST]"; diff --git a/src/cmd/isula/images/rmi.c b/src/cmd/isula/images/rmi.c index 70ff660..53ea734 100644 --- a/src/cmd/isula/images/rmi.c +++ b/src/cmd/isula/images/rmi.c @@ -23,7 +23,6 @@ #include "isula_connect.h" #include "isula_libutils/log.h" #include "connect.h" -#include "libisula.h" const char g_cmd_rmi_desc[] = "Remove one or more images"; const char g_cmd_rmi_usage[] = "rmi [OPTIONS] IMAGE [IMAGE...]"; diff --git a/src/cmd/isula/images/tag.c b/src/cmd/isula/images/tag.c index 822030c..e5a8670 100644 --- a/src/cmd/isula/images/tag.c +++ b/src/cmd/isula/images/tag.c @@ -23,7 +23,7 @@ #include "isula_libutils/log.h" #include "command_parser.h" #include "connect.h" -#include "libisula.h" + #include "utils_verify.h" const char g_cmd_tag_desc[] = "Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE"; diff --git a/src/cmd/isula/information/health.c b/src/cmd/isula/information/health.c index 417c543..17a51f9 100644 --- a/src/cmd/isula/information/health.c +++ b/src/cmd/isula/information/health.c @@ -23,7 +23,6 @@ #include "isula_connect.h" #include "connect.h" #include "constants.h" -#include "libisula.h" const char g_cmd_health_check_desc[] = "iSulad health check"; const char g_cmd_health_check_usage[] = "health [command options]"; diff --git a/src/cmd/isula/information/info.c b/src/cmd/isula/information/info.c index 955d58d..07cad9d 100644 --- a/src/cmd/isula/information/info.c +++ b/src/cmd/isula/information/info.c @@ -25,7 +25,6 @@ #include "isula_connect.h" #include "command_parser.h" #include "connect.h" -#include "libisula.h" const char g_cmd_info_desc[] = "Display system-wide information"; const char g_cmd_info_usage[] = "info"; diff --git a/src/cmd/isula/information/inspect.c b/src/cmd/isula/information/inspect.c index 8341640..76caaba 100644 --- a/src/cmd/isula/information/inspect.c +++ b/src/cmd/isula/information/inspect.c @@ -25,7 +25,6 @@ #include "isula_connect.h" #include "utils.h" #include "connect.h" -#include "libisula.h" const char g_cmd_inspect_desc[] = "Return low-level information on a container or image"; const char g_cmd_inspect_usage[] = "inspect [options] CONTAINER|IMAGE [CONTAINER|IMAGE...]"; diff --git a/src/cmd/isula/information/logs.c b/src/cmd/isula/information/logs.c index 0f603c2..2ddd16e 100644 --- a/src/cmd/isula/information/logs.c +++ b/src/cmd/isula/information/logs.c @@ -23,7 +23,7 @@ #include "isula_libutils/log.h" #include "isula_connect.h" #include "connect.h" -#include "libisula.h" + #include "utils.h" #include "utils_convert.h" @@ -67,7 +67,7 @@ static int do_logs(const struct client_arguments *args) request->runtime = util_strdup_s(args->runtime); request->follow = args->follow; request->tail = (int64_t)args->tail; - + request->timestamps = args->timestamps; config = get_connect_config(args); ret = ops->container.logs(request, response, &config); if (ret != 0) { @@ -105,8 +105,8 @@ static int cmd_logs_init(int argc, const char **argv) return ECOMMON; } g_cmd_logs_args.progname = argv[0]; - struct command_option options[] = { LOG_OPTIONS(lconf) LOGS_OPTIONS(g_cmd_logs_args), - COMMON_OPTIONS(g_cmd_logs_args) + struct command_option options[] = { LOG_OPTIONS(lconf) LOGS_OPTIONS(g_cmd_logs_args) + COMMON_OPTIONS(g_cmd_logs_args) }; command_init(&cmd, options, sizeof(options) / sizeof(options[0]), argc, (const char **)argv, g_cmd_logs_desc, diff --git a/src/cmd/isula/information/logs.h b/src/cmd/isula/information/logs.h index 477d3aa..05717a6 100644 --- a/src/cmd/isula/information/logs.h +++ b/src/cmd/isula/information/logs.h @@ -25,12 +25,16 @@ extern "C" { #endif -#define LOGS_OPTIONS(cmdargs) \ - { CMD_OPT_TYPE_BOOL, false, "follow", 'f', &(cmdargs).follow, "Follow log output", NULL }, \ - { \ - CMD_OPT_TYPE_CALLBACK, false, "tail", 0, &(cmdargs).tail, "Number of lines to show from the end of the logs", \ - callback_tail \ - } +#define LOGS_OPTIONS(cmdargs) \ + { CMD_OPT_TYPE_BOOL, false, "follow", 'f', &(cmdargs).follow, "Follow log output", NULL }, \ + { CMD_OPT_TYPE_CALLBACK, \ + false, \ + "tail", \ + 0, \ + &(cmdargs).tail, \ + "Number of lines to show from the end of the logs", \ + callback_tail }, \ + { CMD_OPT_TYPE_BOOL, false, "timestamps", 't', &(cmdargs).timestamps, "Show timestamps", NULL }, extern const char g_cmd_logs_desc[]; extern const char g_cmd_logs_usage[]; diff --git a/src/cmd/isula/information/ps.c b/src/cmd/isula/information/ps.c index 860ae01..a824ac3 100644 --- a/src/cmd/isula/information/ps.c +++ b/src/cmd/isula/information/ps.c @@ -26,7 +26,7 @@ #include "isula_connect.h" #include "connect.h" #include "constants.h" -#include "libisula.h" + #include "utils_array.h" #include "utils_string.h" #include "utils_timestamp.h" @@ -121,7 +121,7 @@ static int append_field(struct filters *ff, struct filter_field *field) old_size = ff->field_len * sizeof(struct filters); new_size = old_size + sizeof(struct filters); - if (mem_realloc((void **)(&tmp_fields), new_size, ff->fields, old_size) != 0) { + if (util_mem_realloc((void **)(&tmp_fields), new_size, ff->fields, old_size) != 0) { ERROR("Out of memory"); return -1; } @@ -209,8 +209,8 @@ static int mix_container_status(const struct isula_container_summary_info *in, c char finishat_duration[TIME_DURATION_MAX_LEN] = { 0 }; char *start_at = NULL; char *finish_at = NULL; - time_format_duration(in->startat, startat_duration, sizeof(startat_duration)); - time_format_duration_ago(in->finishat, finishat_duration, sizeof(finishat_duration)); + util_time_format_duration(in->startat, startat_duration, sizeof(startat_duration)); + util_time_format_duration_ago(in->finishat, finishat_duration, sizeof(finishat_duration)); start_at = in->startat ? startat_duration : "-"; finish_at = in->finishat ? finishat_duration : "-"; @@ -344,7 +344,7 @@ static int get_created_time_buffer(int64_t created, char *timebuffer, size_t len ERROR("Failed to get timestamp"); return -1; } - if (!get_time_buffer(×tamp, timebuffer, len)) { + if (!util_get_time_buffer(×tamp, timebuffer, len)) { ERROR("Failed to get timebuffer from timestamp"); return -1; } @@ -359,7 +359,7 @@ static void print_created_field(int64_t created, unsigned int length) if (get_created_time_buffer(created, timebuffer, MAX_TIMESTAMP_LEN) != 0) { return; } - if (time_format_duration_ago(timebuffer, created_duration, sizeof(created_duration)) != 0) { + if (util_time_format_duration_ago(timebuffer, created_duration, sizeof(created_duration)) != 0) { return; } printf("%-*s", (int)length, created_duration); @@ -405,11 +405,11 @@ static void print_extern_container_info_item(const struct isula_container_summar printf("%-*u", (int)length->rscont_length, in->restart_count); } else if (strcmp(name, "StartAt") == 0) { char startat_duration[TIME_DURATION_MAX_LEN] = { 0 }; - time_format_duration(in->startat, startat_duration, sizeof(startat_duration)); + util_time_format_duration(in->startat, startat_duration, sizeof(startat_duration)); printf("%-*s", (int)length->startat_length, in->startat ? startat_duration : "-"); } else if (strcmp(name, "FinishAt") == 0) { char finishat_duration[TIME_DURATION_MAX_LEN] = { 0 }; - time_format_duration(in->finishat, finishat_duration, sizeof(finishat_duration)); + util_time_format_duration(in->finishat, finishat_duration, sizeof(finishat_duration)); printf("%-*s", (int)length->finishat_length, in->finishat ? finishat_duration : "-"); } else if (strcmp(name, "Runtime") == 0) { printf("%-*s", (int)length->runtime_length, in->runtime ? in->runtime : "lcr"); @@ -531,7 +531,7 @@ static void calculate_time_str_length(const char *str, unsigned int *length) size_t len = 0; char time_duration[TIME_DURATION_MAX_LEN]; - if (time_format_duration_ago(str, time_duration, sizeof(time_duration)) < 0) { + if (util_time_format_duration_ago(str, time_duration, sizeof(time_duration)) < 0) { ERROR("Format time duration failed"); } diff --git a/src/cmd/isula/information/top.c b/src/cmd/isula/information/top.c index bb0fa45..5d0e3f0 100644 --- a/src/cmd/isula/information/top.c +++ b/src/cmd/isula/information/top.c @@ -25,7 +25,6 @@ #include "attach.h" #include "command_parser.h" #include "connect.h" -#include "libisula.h" const char g_cmd_top_desc[] = "Display the running processes of a container"; const char g_cmd_top_usage[] = "top [OPTIONS] CONTAINER [ps OPTIONS]"; diff --git a/src/cmd/isula/information/version.c b/src/cmd/isula/information/version.c index 36e985b..62ee564 100644 --- a/src/cmd/isula/information/version.c +++ b/src/cmd/isula/information/version.c @@ -25,7 +25,6 @@ #include "command_parser.h" #include "connect.h" #include "constants.h" -#include "libisula.h" const char g_cmd_version_desc[] = "Display information about isula"; const char g_cmd_version_usage[] = "version"; diff --git a/src/cmd/isula/information/wait.c b/src/cmd/isula/information/wait.c index 5926536..90a018f 100644 --- a/src/cmd/isula/information/wait.c +++ b/src/cmd/isula/information/wait.c @@ -23,7 +23,7 @@ #include "command_parser.h" #include "connect.h" #include "constants.h" -#include "libisula.h" + #include "utils.h" const char g_cmd_wait_desc[] = "Block until one or more containers stop, then print their exit codes"; diff --git a/src/cmd/isula/isula_commands.c b/src/cmd/isula/isula_commands.c index 8208aa3..2f3298d 100644 --- a/src/cmd/isula/isula_commands.c +++ b/src/cmd/isula/isula_commands.c @@ -17,17 +17,16 @@ #include #include #include -#include #include #include #include #include +#include #include "client_arguments.h" #include "config.h" #include "isula_libutils/log.h" #include "utils.h" -#include "console.h" #include "constants.h" #include "utils_file.h" #include "utils_string.h" @@ -199,239 +198,3 @@ int run_command(struct command *commands, int argc, const char **argv) printf("run `%s --help` for a list of sub-commands\n", argv[0]); return 1; } - -/* free command fifo names */ -void free_command_fifo_config(struct command_fifo_config *fifos) -{ - if (fifos != NULL) { - if (fifos->stdin_path != NULL) { - free(fifos->stdin_path); - fifos->stdin_path = NULL; - } - if (fifos->stdout_path != NULL) { - free(fifos->stdout_path); - fifos->stdout_path = NULL; - } - if (fifos->stderr_path != NULL) { - free(fifos->stderr_path); - fifos->stderr_path = NULL; - } - if (fifos->stdin_name != NULL) { - free(fifos->stdin_name); - fifos->stdin_name = NULL; - } - if (fifos->stdout_name != NULL) { - free(fifos->stdout_name); - fifos->stdout_name = NULL; - } - if (fifos->stderr_name != NULL) { - free(fifos->stderr_name); - fifos->stderr_name = NULL; - } - free(fifos); - } -} - -/* delete command fifo */ -void delete_command_fifo(struct command_fifo_config *fifos) -{ - int ret; - - if (fifos == NULL) { - return; - } - - ret = console_fifo_delete(fifos->stdin_name); - if (ret) { - WARN("Delete fifo failed: %s", fifos->stdin_name); - } - ret = console_fifo_delete(fifos->stdout_name); - if (ret) { - WARN("Delete fifo failed: %s", fifos->stdout_name); - } - ret = console_fifo_delete(fifos->stderr_name); - if (ret) { - WARN("Delete fifo failed: %s", fifos->stderr_name); - } - ret = util_recursive_rmdir(fifos->stdin_path, 0); - if (ret) { - WARN("Remove directory failed: %s", fifos->stdin_path); - } - ret = util_recursive_rmdir(fifos->stdout_path, 0); - if (ret) { - WARN("Remove directory failed: %s", fifos->stdout_path); - } - ret = util_recursive_rmdir(fifos->stderr_path, 0); - if (ret) { - WARN("Remove directory failed: %s", fifos->stderr_path); - } - - free_command_fifo_config(fifos); -} - -static int do_create_console_fifo(const char *subpath, const char *stdflag, char **out_fifo_dir, char **out_fifo_name) -{ - int ret = 0; - char fifo_dir[PATH_MAX] = { 0 }; - char fifo_name[PATH_MAX] = { 0 }; - - ret = console_fifo_name(CLIENT_RUNDIR, subpath, stdflag, fifo_name, sizeof(fifo_name), fifo_dir, sizeof(fifo_dir), - true); - if (ret != 0) { - ERROR("Failed to get console fifo name."); - ret = -1; - goto out; - } - - if (console_fifo_create(fifo_name)) { - ERROR("Failed to create console fifo."); - ret = -1; - goto out; - } - - *out_fifo_dir = util_strdup_s(fifo_dir); - *out_fifo_name = util_strdup_s(fifo_name); - -out: - return ret; -} - -int create_console_fifos(bool attach_stdin, bool attach_stdout, bool attach_stderr, const char *name, const char *type, - struct command_fifo_config **pconsole_fifos) -{ - int ret = 0; - char subpath[PATH_MAX] = { 0 }; - struct command_fifo_config *fifos = NULL; - - fifos = util_common_calloc_s(sizeof(struct command_fifo_config)); - if (fifos == NULL) { - ERROR("Failed to malloc memory for FIFO names."); - return -1; - } - - ret = snprintf(subpath, sizeof(subpath), "%s/%s-%u-%u", name, type, (unsigned int)getpid(), - (unsigned int)pthread_self()); - if (ret < 0 || (size_t)ret >= sizeof(subpath)) { - ERROR("Path is too long"); - goto cleanup; - } - - if (attach_stdin) { - ret = do_create_console_fifo(subpath, "in", &fifos->stdin_path, &fifos->stdin_name); - if (ret != 0) { - goto cleanup; - } - INFO("FIFO:%s create for start success.", fifos->stdin_name); - } - - if (attach_stdout) { - ret = do_create_console_fifo(subpath, "out", &fifos->stdout_path, &fifos->stdout_name); - if (ret != 0) { - goto cleanup; - } - INFO("FIFO:%s create for start success.", fifos->stdout_name); - } - - if (attach_stderr) { - ret = do_create_console_fifo(subpath, "err", &fifos->stderr_path, &fifos->stderr_name); - if (ret != 0) { - goto cleanup; - } - INFO("FIFO:%s create for start success.", fifos->stderr_name); - } - - *pconsole_fifos = fifos; - return 0; - -cleanup: - console_fifo_delete(fifos->stdin_name); - console_fifo_delete(fifos->stdout_name); - console_fifo_delete(fifos->stderr_name); - free_command_fifo_config(fifos); - return -1; -} - -struct console_loop_thread_args { - struct command_fifo_config *fifo_config; - bool tty; -}; - -static void *client_console_loop_thread(void *arg) -{ - int ret = 0; - int fifoinfd = -1; - int fifooutfd = -1; - int fifoerrfd = -1; - const struct console_loop_thread_args *args = arg; - bool tty = args->tty; - struct command_fifo_config *fifo_config = args->fifo_config; - sem_t *wait_open = fifo_config->wait_open; - sem_t *wait_exit = fifo_config->wait_exit; - - ret = pthread_detach(pthread_self()); - if (ret != 0) { - CRIT("Start: set thread detach fail"); - goto err1; - } - - if (fifo_config->stdin_name) { - if (console_fifo_open_withlock(fifo_config->stdin_name, &fifoinfd, O_RDWR | O_NONBLOCK)) { - ERROR("Start: failed to open console fifo."); - goto err2; - } - INFO("FIFO:%s open success for start.", fifo_config->stdin_name); - } - - if (fifo_config->stdout_name) { - if (console_fifo_open(fifo_config->stdout_name, &fifooutfd, O_RDONLY | O_NONBLOCK)) { - ERROR("Failed to open console fifo."); - goto err2; - } - INFO("FIFO:%s open success for start.", fifo_config->stdout_name); - } - - if (fifo_config->stderr_name) { - if (console_fifo_open(fifo_config->stderr_name, &fifoerrfd, O_RDONLY | O_NONBLOCK)) { - ERROR("Start: failed to open console fifo."); - goto err2; - } - INFO("FIFO:%s open success for start.", fifo_config->stderr_name); - } - - sem_post(wait_open); - console_loop_with_std_fd(0, 1, 2, fifoinfd, fifooutfd, fifoerrfd, 1, tty); - -err2: - if (fifoinfd >= 0) { - console_fifo_close(fifoinfd); - } - if (fifooutfd >= 0) { - console_fifo_close(fifooutfd); - } - if (fifoerrfd >= 0) { - console_fifo_close(fifoerrfd); - } -err1: - sem_post(wait_open); - sem_post(wait_exit); - return NULL; -} - -int start_client_console_thread(struct command_fifo_config *console_fifos, bool tty) -{ - int res = 0; - pthread_t a_thread; - struct console_loop_thread_args args; - - args.fifo_config = console_fifos; - args.tty = tty; - res = pthread_create(&a_thread, NULL, client_console_loop_thread, (void *)(&args)); - if (res != 0) { - CRIT("Thread creation failed"); - return -1; - } - - sem_wait(console_fifos->wait_open); - - return 0; -} diff --git a/src/cmd/isula/isula_commands.h b/src/cmd/isula/isula_commands.h index 7ac2501..1e9e166 100644 --- a/src/cmd/isula/isula_commands.h +++ b/src/cmd/isula/isula_commands.h @@ -15,7 +15,6 @@ #ifndef CMD_ISULA_ISULA_COMMANDS_H #define CMD_ISULA_ISULA_COMMANDS_H -#include #include #include "client_arguments.h" @@ -24,15 +23,13 @@ extern "C" { #endif -#define CLIENT_RUNDIR "/var/run/isula" - // A command is described by: // @name: The name which should be passed as a second parameter // @executor: The function that will be executed if the command // matches. Receives the argc of the program minus two, and // the rest os argv // @description: Brief description, will show in help messages -// @longdesc: Long descripton to show when you run `help ` +// @longdesc: Long description to show when you run `help ` struct command { const char * const name; int (*executor)(int, const char **); @@ -41,26 +38,6 @@ struct command { struct client_arguments *args; }; -struct command_fifo_config { - char *stdin_path; - char *stdout_path; - char *stderr_path; - char *stdin_name; - char *stdout_name; - char *stderr_name; - sem_t *wait_open; - sem_t *wait_exit; -}; - -int create_console_fifos(bool attach_stdin, bool attach_stdout, bool attach_stderr, const char *name, const char *type, - struct command_fifo_config **pconsole_fifos); - -int start_client_console_thread(struct command_fifo_config *console_fifos, bool tty); - -void free_command_fifo_config(struct command_fifo_config *fifos); - -void delete_command_fifo(struct command_fifo_config *fifos); - // Gets a pointer to a command, to allow implementing custom behavior // returns null if not found. // @@ -68,7 +45,7 @@ void delete_command_fifo(struct command_fifo_config *fifos); const struct command *command_by_name(const struct command *cmds, const char * const name); // Default help command if implementation doesn't prvide one -int commmand_default_help(const char * const program_name, struct command *commands, int argc, const char **argv); +int command_default_help(const char * const program_name, struct command *commands, int argc, const char **argv); int run_command(struct command *commands, int argc, const char **argv); diff --git a/src/cmd/isula/isula_container_spec.c b/src/cmd/isula/isula_container_spec.c new file mode 100644 index 0000000..2893eb9 --- /dev/null +++ b/src/cmd/isula/isula_container_spec.c @@ -0,0 +1,486 @@ +/****************************************************************************** + * Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved. + * iSulad licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * 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 v2 for more details. + * Author: lifeng + * Create: 2020-09-28 + * Description: provide generate container spec in client + ******************************************************************************/ +#include "isula_container_spec.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "isula_libutils/log.h" +#include "utils.h" +#include "isula_libutils/container_config.h" +#include "utils_array.h" +#include "utils_string.h" +#include "utils_verify.h" + +static int pack_container_custom_config_args(container_config *container_spec, + const isula_container_config_t *custom_conf) +{ + int ret = 0; + int i; + + /* entrypoint */ + if (util_valid_str(custom_conf->entrypoint)) { + container_spec->entrypoint = util_common_calloc_s(sizeof(char *)); + if (container_spec->entrypoint == NULL) { + ret = -1; + goto out; + } + container_spec->entrypoint[0] = util_strdup_s(custom_conf->entrypoint); + container_spec->entrypoint_len++; + } + + /* commands */ + if ((custom_conf->cmd_len != 0 && custom_conf->cmd)) { + if (custom_conf->cmd_len > SIZE_MAX / sizeof(char *)) { + COMMAND_ERROR("The length of cmd is too long!"); + ret = -1; + goto out; + } + container_spec->cmd = util_common_calloc_s(custom_conf->cmd_len * sizeof(char *)); + if (container_spec->cmd == NULL) { + ret = -1; + goto out; + } + for (i = 0; i < (int)custom_conf->cmd_len; i++) { + container_spec->cmd[container_spec->cmd_len] = util_strdup_s(custom_conf->cmd[i]); + container_spec->cmd_len++; + } + } + +out: + return ret; +} + +static int pack_container_custom_config_mounts(container_config *container_spec, + const isula_container_config_t *custom_conf) +{ + int ret = 0; + int i = 0; + + /* mounts to mount filesystem */ + if (custom_conf->mounts != NULL && custom_conf->mounts_len > 0) { + if (custom_conf->mounts_len > SIZE_MAX / sizeof(char *)) { + COMMAND_ERROR("Too many mounts to mount filesystem!"); + ret = -1; + goto out; + } + container_spec->mounts = util_common_calloc_s(custom_conf->mounts_len * sizeof(char *)); + if (container_spec->mounts == NULL) { + ret = -1; + goto out; + } + for (i = 0; i < (int)custom_conf->mounts_len; i++) { + container_spec->mounts[container_spec->mounts_len] = util_strdup_s(custom_conf->mounts[i]); + container_spec->mounts_len++; + } + } +out: + return ret; +} + +static int pack_container_custom_config_array(container_config *container_spec, + const isula_container_config_t *custom_conf) +{ + int ret = 0; + int i = 0; + + /* environment variables */ + if (custom_conf->env_len != 0 && custom_conf->env) { + if (custom_conf->env_len > SIZE_MAX / sizeof(char *)) { + COMMAND_ERROR("Too many environment variables"); + return -1; + } + container_spec->env = util_common_calloc_s(custom_conf->env_len * sizeof(char *)); + if (container_spec->env == NULL) { + ret = -1; + goto out; + } + for (i = 0; i < (int)custom_conf->env_len; i++) { + container_spec->env[container_spec->env_len] = util_strdup_s(custom_conf->env[i]); + container_spec->env_len++; + } + } + +out: + return ret; +} + +static int get_label_key_value(const char *label, char **key, char **value) +{ + int ret = 0; + char **arr = util_string_split_n(label, '=', 2); + if (arr == NULL) { + ERROR("Failed to split input label"); + ret = -1; + goto out; + } + + *key = util_strdup_s(arr[0]); + if (util_array_len((const char **)arr) == 1) { + *value = util_strdup_s(""); + } else { + *value = util_strdup_s(arr[1]); + } + +out: + util_free_array(arr); + return ret; +} + +static int pack_container_custom_config_labels(container_config *container_spec, + const isula_container_config_t *custom_conf) +{ + int ret = 0; + int i; + char *key = NULL; + char *value = NULL; + + if (custom_conf->label_len == 0 || custom_conf->label == NULL) { + return 0; + } + + /* labels */ + container_spec->labels = util_common_calloc_s(sizeof(json_map_string_string)); + if (container_spec->labels == NULL) { + ERROR("Out of memory"); + ret = -1; + goto out; + } + + for (i = 0; i < custom_conf->label_len; i++) { + if (get_label_key_value(custom_conf->label[i], &key, &value) != 0) { + ERROR("Failed to get key and value of label"); + ret = -1; + goto out; + } + + if (append_json_map_string_string(container_spec->labels, key, value)) { + ERROR("Append map failed"); + ret = -1; + goto out; + } + free(key); + key = NULL; + free(value); + value = NULL; + } + +out: + free(key); + free(value); + return ret; +} + +static bool have_health_check(const isula_container_config_t *custom_conf) +{ + bool have_health_settings = false; + + if ((custom_conf->health_cmd != NULL && strlen(custom_conf->health_cmd) != 0) || + custom_conf->health_interval != 0 || custom_conf->health_timeout != 0 || + custom_conf->health_start_period != 0 || custom_conf->health_retries != 0) { + have_health_settings = true; + } + + return have_health_settings; +} + +static int pack_custom_no_health_check(container_config *container_spec, bool have_health_settings, + defs_health_check *health_config) +{ + int ret = 0; + + if (have_health_settings) { + COMMAND_ERROR("--no-healthcheck conflicts with --health-* options"); + ret = -1; + goto out; + } + health_config->test = util_common_calloc_s(sizeof(char *)); + if (health_config->test == NULL) { + ret = -1; + goto out; + } + health_config->test[health_config->test_len++] = util_strdup_s("NONE"); + container_spec->healthcheck = health_config; + +out: + return ret; +} + +static int pack_custom_with_health_check(container_config *container_spec, const isula_container_config_t *custom_conf, + bool have_health_settings, defs_health_check *health_config) +{ + int ret = 0; + + if (custom_conf->health_cmd != NULL && strlen(custom_conf->health_cmd) != 0) { + health_config->test = util_common_calloc_s(2 * sizeof(char *)); + if (health_config->test == NULL) { + ret = -1; + goto out; + } + health_config->test[health_config->test_len++] = util_strdup_s("CMD-SHELL"); + health_config->test[health_config->test_len++] = util_strdup_s(custom_conf->health_cmd); + } else { + COMMAND_ERROR("--health-cmd required!"); + ret = -1; + goto out; + } + health_config->interval = custom_conf->health_interval; + health_config->timeout = custom_conf->health_timeout; + health_config->start_period = custom_conf->health_start_period; + health_config->retries = custom_conf->health_retries; + health_config->exit_on_unhealthy = custom_conf->exit_on_unhealthy; + if (container_spec->healthcheck != NULL) { + free_defs_health_check(container_spec->healthcheck); + } + container_spec->healthcheck = health_config; + +out: + return ret; +} + +static int pack_container_custom_config_health(container_config *container_spec, + const isula_container_config_t *custom_conf) +{ + int ret = 0; + bool have_health_settings = false; + defs_health_check *health_config = NULL; + + if (container_spec == NULL || custom_conf == NULL) { + return 0; + } + + have_health_settings = have_health_check(custom_conf); + + health_config = util_common_calloc_s(sizeof(defs_health_check)); + if (health_config == NULL) { + ret = -1; + goto out; + } + + if (custom_conf->no_healthcheck) { + ret = pack_custom_no_health_check(container_spec, have_health_settings, health_config); + if (ret != 0) { + goto out; + } + } else if (have_health_settings) { + ret = pack_custom_with_health_check(container_spec, custom_conf, have_health_settings, health_config); + if (ret != 0) { + goto out; + } + } else { + goto out; + } + + return ret; + +out: + free_defs_health_check(health_config); + return ret; +} + +static int pack_container_custom_config_annotation(container_config *container_spec, + const isula_container_config_t *custom_conf) +{ + int ret = 0; + size_t j; + + container_spec->annotations = util_common_calloc_s(sizeof(json_map_string_string)); + if (container_spec->annotations == NULL) { + ERROR("Out of memory"); + ret = -1; + goto out; + } + if (custom_conf->annotations != NULL) { + for (j = 0; j < custom_conf->annotations->len; j++) { + if (append_json_map_string_string(container_spec->annotations, custom_conf->annotations->keys[j], + custom_conf->annotations->values[j])) { + ERROR("Append map failed"); + ret = -1; + goto out; + } + } + } +out: + return ret; +} + +static int pack_container_custom_config_pre(container_config *container_spec, + const isula_container_config_t *custom_conf) +{ + int ret = 0; + + ret = pack_container_custom_config_args(container_spec, custom_conf); + if (ret != 0) { + goto out; + } + + ret = pack_container_custom_config_mounts(container_spec, custom_conf); + if (ret != 0) { + goto out; + } + + ret = pack_container_custom_config_array(container_spec, custom_conf); + if (ret != 0) { + goto out; + } + + ret = pack_container_custom_config_labels(container_spec, custom_conf); + if (ret != 0) { + goto out; + } + + ret = pack_container_custom_config_health(container_spec, custom_conf); + if (ret != 0) { + goto out; + } +out: + return ret; +} + +/* translate create_custom_config to container_config */ +static int pack_container_custom_config(container_config *container_spec, const isula_container_config_t *custom_conf) +{ + int ret = -1; + + if (container_spec == NULL || custom_conf == NULL) { + return ret; + } + + ret = pack_container_custom_config_pre(container_spec, custom_conf); + if (ret != 0) { + goto out; + } + + if (custom_conf->hostname != NULL) { + container_spec->hostname = util_strdup_s(custom_conf->hostname); + } + container_spec->log_driver = util_strdup_s(custom_conf->log_driver); + + /* console config */ + container_spec->tty = custom_conf->tty; + container_spec->open_stdin = custom_conf->open_stdin; + container_spec->attach_stdin = custom_conf->attach_stdin; + container_spec->attach_stdout = custom_conf->attach_stdout; + container_spec->attach_stderr = custom_conf->attach_stderr; + + /* user and group */ + if (custom_conf->user != NULL) { + container_spec->user = util_strdup_s(custom_conf->user); + } + + /* settings for system container */ + if (custom_conf->system_container) { + container_spec->system_container = custom_conf->system_container; + } + + if (custom_conf->ns_change_opt != NULL) { + container_spec->ns_change_opt = util_strdup_s(custom_conf->ns_change_opt); + } + + ret = pack_container_custom_config_annotation(container_spec, custom_conf); + if (ret != 0) { + goto out; + } + + if (custom_conf->workdir != NULL) { + container_spec->working_dir = util_strdup_s(custom_conf->workdir); + } + +out: + return ret; +} + +int generate_container_config(const isula_container_config_t *custom_conf, char **container_config_str) +{ + int ret = 0; + container_config *container_spec = NULL; + struct parser_context ctx = { OPT_GEN_SIMPLIFY, 0 }; + parser_error err = NULL; + + /* step 1: malloc the container config */ + container_spec = util_common_calloc_s(sizeof(container_config)); + if (container_spec == NULL) { + ERROR("Memory out"); + ret = -1; + goto out; + } + + /* step 2: pack the container custom config */ + ret = pack_container_custom_config(container_spec, custom_conf); + if (ret != 0) { + ERROR("Failed to pack the container custom config"); + ret = -1; + goto out; + } + + /* step 3: generate the config string */ + *container_config_str = container_config_generate_json(container_spec, &ctx, &err); + if (*container_config_str == NULL) { + ERROR("Failed to generate OCI specification json string"); + ret = -1; + goto out; + } + +out: + free_container_config(container_spec); + free(err); + + return ret; +} + +/* isula container config free */ +void isula_container_config_free(isula_container_config_t *config) +{ + if (config == NULL) { + return; + } + + util_free_array_by_len(config->env, config->env_len); + config->env = NULL; + config->env_len = 0; + + free(config->hostname); + config->hostname = NULL; + + free(config->user); + config->user = NULL; + + util_free_array_by_len(config->mounts, config->mounts_len); + config->mounts = NULL; + config->mounts_len = 0; + + util_free_array_by_len(config->cmd, config->cmd_len); + config->cmd = NULL; + config->cmd_len = 0; + + free(config->entrypoint); + config->entrypoint = NULL; + + free(config->log_driver); + config->log_driver = NULL; + + free_json_map_string_string(config->annotations); + config->annotations = NULL; + + free(config->workdir); + config->workdir = NULL; + + free(config); +} \ No newline at end of file diff --git a/src/cmd/isula/isula_container_spec.h b/src/cmd/isula/isula_container_spec.h new file mode 100644 index 0000000..1a1b616 --- /dev/null +++ b/src/cmd/isula/isula_container_spec.h @@ -0,0 +1,92 @@ +/****************************************************************************** + * Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved. + * iSulad licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * 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 v2 for more details. + * Author: lifeng + * Create: 2020-09-28 + * Description: provide generate container spec in client + ******************************************************************************/ +#ifndef CMD_ISULA_GENERATE_CONTAINER_SPEC_H +#define CMD_ISULA_GENERATE_CONTAINER_SPEC_H + +#include +#include +#include +#include "isula_libutils/json_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct isula_container_config { + char **env; + size_t env_len; + + char **label; + size_t label_len; + + char *hostname; + + char *user; + + bool attach_stdin; + + bool attach_stdout; + + bool attach_stderr; + + bool open_stdin; + + bool tty; + + bool readonly; + + bool all_devices; + + bool system_container; + char *ns_change_opt; + + char **mounts; + size_t mounts_len; + + char *entrypoint; + + char **cmd; + size_t cmd_len; + + char *log_driver; + + json_map_string_string *annotations; + + char *workdir; + + char *health_cmd; + + int64_t health_interval; + + int health_retries; + + int64_t health_timeout; + + int64_t health_start_period; + + bool no_healthcheck; + + bool exit_on_unhealthy; + +} isula_container_config_t; + +int generate_container_config(const isula_container_config_t *custom_conf, char **container_config_str); + +void isula_container_config_free(isula_container_config_t *config); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/client/connect/pack_config.c b/src/cmd/isula/isula_host_spec.c similarity index 51% rename from src/client/connect/pack_config.c rename to src/cmd/isula/isula_host_spec.c index fbcd7b4..9c51e73 100644 --- a/src/client/connect/pack_config.c +++ b/src/cmd/isula/isula_host_spec.c @@ -8,10 +8,12 @@ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR * PURPOSE. * See the Mulan PSL v2 for more details. - * Author: tanyifeng - * Create: 2018-11-08 - * Description: provide container package configure functions + * Author: lifeng + * Create: 2020-09-28 + * Description: provide generate host spec in client ******************************************************************************/ +#include "isula_host_spec.h" + #include #include #include @@ -25,17 +27,16 @@ #include #include "isula_libutils/log.h" -#include "pack_config.h" #include "isula_libutils/host_config.h" #include "utils.h" #include "isula_libutils/parse_common.h" #include "path.h" -#include "isula_libutils/container_config.h" #include "utils_array.h" #include "utils_convert.h" #include "utils_file.h" #include "utils_string.h" #include "utils_verify.h" +#include "opt_ulimit.h" static bool parse_restart_policy(const char *policy, host_config_restart_policy **rp) { @@ -79,32 +80,13 @@ cleanup: static int pack_host_config_ns_change_files(host_config *dstconfig, const isula_host_config_t *srcconfig) { - int ret = 0; - size_t i = 0; - - if (dstconfig == NULL || srcconfig == NULL) { + if (util_dup_array_of_strings((const char **)srcconfig->ns_change_files, srcconfig->ns_change_files_len, + &dstconfig->ns_change_files, &dstconfig->ns_change_files_len) != 0) { + COMMAND_ERROR("Failed to dup ns change files"); return -1; } - if (srcconfig->ns_change_files_len != 0 && srcconfig->ns_change_files != NULL) { - if (srcconfig->ns_change_files_len > SIZE_MAX / sizeof(char *)) { - COMMAND_ERROR("Too many capabilities to add!"); - ret = -1; - goto out; - } - dstconfig->ns_change_files = util_common_calloc_s(srcconfig->ns_change_files_len * sizeof(char *)); - if (dstconfig->ns_change_files == NULL) { - ret = -1; - goto out; - } - for (i = 0; i < srcconfig->ns_change_files_len; i++) { - dstconfig->ns_change_files[dstconfig->ns_change_files_len] = util_strdup_s(srcconfig->ns_change_files[i]); - dstconfig->ns_change_files_len++; - } - } - -out: - return ret; + return 0; } static int pack_host_config_cap_add(host_config *dstconfig, const isula_host_config_t *srcconfig) @@ -113,21 +95,10 @@ static int pack_host_config_cap_add(host_config *dstconfig, const isula_host_con size_t i = 0; /* cap-add */ - if (srcconfig->cap_add_len != 0 && srcconfig->cap_add != NULL) { - if (srcconfig->cap_add_len > SIZE_MAX / sizeof(char *)) { - COMMAND_ERROR("Too many capabilities to add!"); - ret = -1; - goto out; - } - dstconfig->cap_add = util_common_calloc_s(srcconfig->cap_add_len * sizeof(char *)); - if (dstconfig->cap_add == NULL) { - ret = -1; - goto out; - } - for (i = 0; i < srcconfig->cap_add_len; i++) { - dstconfig->cap_add[dstconfig->cap_add_len] = util_strdup_s(srcconfig->cap_add[i]); - dstconfig->cap_add_len++; - } + if (util_dup_array_of_strings((const char **)srcconfig->cap_add, srcconfig->cap_add_len, &dstconfig->cap_add, + &dstconfig->cap_add_len) != 0) { + COMMAND_ERROR("Failed to dup cap add"); + return -1; } for (i = 0; i < dstconfig->cap_add_len; i++) { @@ -152,21 +123,10 @@ static int pack_host_config_cap_drop(host_config *dstconfig, const isula_host_co size_t i = 0; /* cap-drops */ - if (srcconfig->cap_drop_len != 0 && srcconfig->cap_drop != NULL) { - if (srcconfig->cap_drop_len > SIZE_MAX / sizeof(char *)) { - COMMAND_ERROR("Too many capabilities to drop!"); - ret = -1; - goto out; - } - dstconfig->cap_drop = util_common_calloc_s(srcconfig->cap_drop_len * sizeof(char *)); - if (dstconfig->cap_drop == NULL) { - ret = -1; - goto out; - } - for (i = 0; i < srcconfig->cap_drop_len; i++) { - dstconfig->cap_drop[dstconfig->cap_drop_len] = util_strdup_s(srcconfig->cap_drop[i]); - dstconfig->cap_drop_len++; - } + if (util_dup_array_of_strings((const char **)srcconfig->cap_drop, srcconfig->cap_drop_len, &dstconfig->cap_drop, + &dstconfig->cap_drop_len) != 0) { + COMMAND_ERROR("Failed to dup cap drop"); + return -1; } for (i = 0; i < dstconfig->cap_drop_len; i++) { @@ -208,119 +168,43 @@ out: static int pack_host_network_extra_hosts(host_config *dstconfig, const isula_host_config_t *srcconfig) { - int ret = 0; - size_t i = 0; - /* extra hosts */ - if (srcconfig->extra_hosts_len != 0 && srcconfig->extra_hosts != NULL) { - if (srcconfig->extra_hosts_len > SIZE_MAX / sizeof(char *)) { - COMMAND_ERROR("Too many extra hosts to add!"); - ret = -1; - goto out; - } - dstconfig->extra_hosts = util_common_calloc_s(srcconfig->extra_hosts_len * sizeof(char *)); - if (dstconfig->extra_hosts == NULL) { - ret = -1; - goto out; - } - for (i = 0; i < srcconfig->extra_hosts_len; i++) { - dstconfig->extra_hosts[dstconfig->extra_hosts_len] = util_strdup_s(srcconfig->extra_hosts[i]); - dstconfig->extra_hosts_len++; - } + if (util_dup_array_of_strings((const char **)srcconfig->extra_hosts, srcconfig->extra_hosts_len, + &dstconfig->extra_hosts, &dstconfig->extra_hosts_len) != 0) { + COMMAND_ERROR("Failed to dup extra hosts"); + return -1; } -out: - return ret; + + return 0; } static int pack_host_network_dns(host_config *dstconfig, const isula_host_config_t *srcconfig) { - int ret = 0; - size_t i = 0; - - /* dns */ - if (srcconfig->dns_len != 0 && srcconfig->dns != NULL) { - if (srcconfig->dns_len > SIZE_MAX / sizeof(char *)) { - COMMAND_ERROR("Too many dns to add!"); - ret = -1; - goto out; - } - dstconfig->dns = util_common_calloc_s(srcconfig->dns_len * sizeof(char *)); - if (dstconfig->dns == NULL) { - ret = -1; - goto out; - } - for (i = 0; i < srcconfig->dns_len; i++) { - dstconfig->dns[dstconfig->dns_len] = util_strdup_s(srcconfig->dns[i]); - dstconfig->dns_len++; - } + if (util_dup_array_of_strings((const char **)srcconfig->dns, srcconfig->dns_len, &dstconfig->dns, + &dstconfig->dns_len) != 0) { + COMMAND_ERROR("Failed to dup dns"); + return -1; } -out: - return ret; -} - -static int pack_host_network_dns_options(host_config *dstconfig, const isula_host_config_t *srcconfig) -{ - int ret = 0; - size_t i = 0; - - /* dns options */ - if (srcconfig->dns_options_len != 0 && srcconfig->dns_options != NULL) { - if (srcconfig->dns_options_len > SIZE_MAX / sizeof(char *)) { - COMMAND_ERROR("Too many dns options to add!"); - ret = -1; - goto out; - } - dstconfig->dns_options = util_common_calloc_s(srcconfig->dns_options_len * sizeof(char *)); - if (dstconfig->dns_options == NULL) { - ret = -1; - goto out; - } - for (i = 0; i < srcconfig->dns_options_len; i++) { - dstconfig->dns_options[dstconfig->dns_options_len] = util_strdup_s(srcconfig->dns_options[i]); - dstconfig->dns_options_len++; - } + if (util_dup_array_of_strings((const char **)srcconfig->dns_options, srcconfig->dns_options_len, + &dstconfig->dns_options, &dstconfig->dns_options_len) != 0) { + COMMAND_ERROR("Failed to dup dns options"); + return -1; } -out: - return ret; -} - -static int pack_host_network_dns_search(host_config *dstconfig, const isula_host_config_t *srcconfig) -{ - int ret = 0; - size_t i = 0; - - /* dns search */ - if (srcconfig->dns_search_len != 0 && srcconfig->dns_search != NULL) { - if (srcconfig->dns_search_len > SIZE_MAX / sizeof(char *)) { - COMMAND_ERROR("Too many dns search to add!"); - ret = -1; - goto out; - } - dstconfig->dns_search = util_common_calloc_s(srcconfig->dns_search_len * sizeof(char *)); - if (dstconfig->dns_search == NULL) { - ret = -1; - goto out; - } - for (i = 0; i < srcconfig->dns_search_len; i++) { - dstconfig->dns_search[dstconfig->dns_search_len] = util_strdup_s(srcconfig->dns_search[i]); - dstconfig->dns_search_len++; - } + if (util_dup_array_of_strings((const char **)srcconfig->dns_search, srcconfig->dns_search_len, + &dstconfig->dns_search, &dstconfig->dns_search_len) != 0) { + COMMAND_ERROR("Failed to dup dns search"); + return -1; } -out: - return ret; + return 0; } static int pack_host_config_network(host_config *dstconfig, const isula_host_config_t *srcconfig) { int ret = 0; - if (dstconfig == NULL) { - return -1; - } - ret = pack_host_network_extra_hosts(dstconfig, srcconfig); if (ret != 0) { goto out; @@ -331,16 +215,6 @@ static int pack_host_config_network(host_config *dstconfig, const isula_host_con goto out; } - ret = pack_host_network_dns_options(dstconfig, srcconfig); - if (ret != 0) { - goto out; - } - - ret = pack_host_network_dns_search(dstconfig, srcconfig); - if (ret != 0) { - goto out; - } - out: return ret; } @@ -356,9 +230,8 @@ static int check_parsed_device(const host_config_devices_element *device_map) } if (!util_file_exists(device_map->path_on_host)) { - COMMAND_ERROR( - "Error gathering device information while adding device \"%s\",stat %s:no such file or directory", - device_map->path_on_host, device_map->path_on_host); + COMMAND_ERROR("Error gathering device information while adding device \"%s\",stat %s:no such file or directory", + device_map->path_on_host, device_map->path_on_host); ret = -1; goto out; } @@ -428,169 +301,6 @@ erro_out: return NULL; } -static int check_ulimit_input(const char *val) -{ - int ret = 0; - if (val == NULL || strcmp(val, "") == 0) { - COMMAND_ERROR("ulimit argument can't be empty"); - ret = -1; - goto out; - } - - if (val[0] == '=' || val[strlen(val) - 1] == '=') { - COMMAND_ERROR("Invalid ulimit argument: \"%s\", delimiter '=' can't" - " be the first or the last character", val); - ret = -1; - } - -out: - return ret; -} - -static void get_ulimit_split_parts(const char *val, char ***parts, size_t *parts_len, char deli) -{ - *parts = util_string_split_multi(val, deli); - if (*parts == NULL) { - COMMAND_ERROR("Out of memory"); - return; - } - *parts_len = util_array_len((const char **)(*parts)); -} - -static int parse_soft_hard_ulimit(const char *val, char **limitvals, size_t limitvals_len, int64_t *soft, int64_t *hard) -{ - int ret = 0; - // parse soft - ret = util_safe_llong(limitvals[0], (long long *)soft); - if (ret < 0) { - COMMAND_ERROR("Invalid ulimit soft value: \"%s\", parse int64 failed: %s", val, strerror(-ret)); - ret = -1; - goto out; - } - - // parse hard if exists - if (limitvals_len > 1) { - ret = util_safe_llong(limitvals[1], (long long *)hard); - if (ret < 0) { - COMMAND_ERROR("Invalid ulimit hard value: \"%s\", parse int64 failed: %s", val, strerror(-ret)); - ret = -1; - goto out; - } - - if (*soft > *hard) { - COMMAND_ERROR("Ulimit soft limit must be less than or equal to hard limit: %lld > %lld", - (long long int)(*soft), (long long int)(*hard)); - ret = -1; - goto out; - } - } else { - *hard = *soft; // default to soft in case no hard was set - } -out: - return ret; -} - -static int check_ulimit_type(const char *type) -{ - int ret = 0; - char **tmptype = NULL; - char *ulimit_valid_type[] = { - // "as", // Disabled since this doesn't seem usable with the way Docker inits a container. - "core", "cpu", "data", "fsize", "locks", "memlock", "msgqueue", "nice", - "nofile", "nproc", "rss", "rtprio", "rttime", "sigpending", "stack", NULL - }; - - for (tmptype = ulimit_valid_type; *tmptype != NULL; tmptype++) { - if (strcmp(type, *tmptype) == 0) { - break; - } - } - - if (*tmptype == NULL) { - COMMAND_ERROR("Invalid ulimit type: %s", type); - ret = -1; - } - return ret; -} - -static host_config_ulimits_element *parse_ulimit(const char *val) -{ - int ret = 0; - int64_t soft = 0; - int64_t hard = 0; - size_t parts_len = 0; - size_t limitvals_len = 0; - char **parts = NULL; - char **limitvals = NULL; - host_config_ulimits_element *ulimit = NULL; - - ret = check_ulimit_input(val); - if (ret != 0) { - return NULL; - } - - get_ulimit_split_parts(val, &parts, &parts_len, '='); - if (parts == NULL) { - ERROR("Out of memory"); - return NULL; - } else if (parts_len != 2) { - COMMAND_ERROR("Invalid ulimit argument: %s", val); - ret = -1; - goto out; - } - - ret = check_ulimit_type(parts[0]); - if (ret != 0) { - ret = -1; - goto out; - } - - if (parts[1][0] == ':' || parts[1][strlen(parts[1]) - 1] == ':') { - COMMAND_ERROR("Invalid ulimit value: \"%s\", delimiter ':' can't be the first" - " or the last character", val); - ret = -1; - goto out; - } - - // parse value - get_ulimit_split_parts(parts[1], &limitvals, &limitvals_len, ':'); - if (limitvals == NULL) { - ret = -1; - goto out; - } - - if (limitvals_len > 2) { - COMMAND_ERROR("Too many limit value arguments - %s, can only have up to two, `soft[:hard]`", - parts[1]); - ret = -1; - goto out; - } - - ret = parse_soft_hard_ulimit(val, limitvals, limitvals_len, &soft, &hard); - if (ret < 0) { - goto out; - } - - ulimit = util_common_calloc_s(sizeof(host_config_ulimits_element)); - if (ulimit == NULL) { - ret = -1; - goto out; - } - ulimit->name = util_strdup_s(parts[0]); - ulimit->hard = hard; - ulimit->soft = soft; - -out: - util_free_array(parts); - util_free_array(limitvals); - if (ret != 0) { - free_host_config_ulimits_element(ulimit); - ulimit = NULL; - } - - return ulimit; -} - static void pack_cgroup_resources_cpu(host_config *dstconfig, const isula_host_config_t *srcconfig) { /* cgroup blkio weight */ @@ -598,6 +308,11 @@ static void pack_cgroup_resources_cpu(host_config *dstconfig, const isula_host_c dstconfig->blkio_weight = srcconfig->cr->blkio_weight; } + /* cpus */ + if (srcconfig->cr->nano_cpus != 0) { + dstconfig->nano_cpus = srcconfig->cr->nano_cpus; + } + /* cpu shares */ if (srcconfig->cr->cpu_shares) { dstconfig->cpu_shares = srcconfig->cr->cpu_shares; @@ -703,7 +418,7 @@ static int pack_hostconfig_ulimits(host_config *dstconfig, const isula_host_conf bool exists = false; host_config_ulimits_element *tmp = NULL; - tmp = parse_ulimit(srcconfig->ulimits[i]); + tmp = parse_opt_ulimit(srcconfig->ulimits[i]); if (tmp == NULL) { ret = -1; goto out; @@ -739,19 +454,19 @@ static int pack_hostconfig_cgroup(host_config *dstconfig, const isula_host_confi return ret; } -static host_config_blkio_weight_device_element *pack_blkio_weight_devices(const char *devices) +static defs_blkio_weight_device *pack_blkio_weight_devices(const char *devices) { char **tmp_str = NULL; unsigned int weight = 0; size_t tmp_str_len = 0; - host_config_blkio_weight_device_element *weight_dev = NULL; + defs_blkio_weight_device *weight_dev = NULL; if (devices == NULL || !strcmp(devices, "")) { COMMAND_ERROR("Weight devices can't be empty"); return NULL; } - weight_dev = util_common_calloc_s(sizeof(host_config_blkio_weight_device_element)); + weight_dev = util_common_calloc_s(sizeof(defs_blkio_weight_device)); if (weight_dev == NULL) { ERROR("Out of memory"); return NULL; @@ -793,11 +508,11 @@ static host_config_blkio_weight_device_element *pack_blkio_weight_devices(const erro_out: util_free_array(tmp_str); - free_host_config_blkio_weight_device_element(weight_dev); + free_defs_blkio_weight_device(weight_dev); return NULL; } -static int parse_blkio_throttle_bps_device(const char *device, char **path, const uint64_t *rate) +static int parse_blkio_throttle_bps_device(const char *device, char **path, uint64_t *rate) { int ret = 0; char **split = NULL; @@ -817,7 +532,8 @@ static int parse_blkio_throttle_bps_device(const char *device, char **path, cons if (util_parse_byte_size_string(split[1], (int64_t *)rate) != 0) { COMMAND_ERROR("invalid rate for device: %s. The correct format is :[]." - " Number must be a positive integer. Unit is optional and can be kb, mb, or gb", device); + " Number must be a positive integer. Unit is optional and can be kb, mb, or gb", + device); ret = -1; goto out; } @@ -829,19 +545,19 @@ out: } // validate that the specified string has a valid device-rate format. -static host_config_blkio_device_read_bps_element *pack_throttle_read_bps_device(const char *device) +static defs_blkio_device *pack_throttle_bps_device(const char *device) { char *path = NULL; uint64_t rate = 0; - host_config_blkio_device_read_bps_element *read_bps_dev = NULL; + defs_blkio_device *bps_dev = NULL; if (device == NULL || !strcmp(device, "")) { COMMAND_ERROR("blkio throttle read bps device can't be empty"); return NULL; } - read_bps_dev = util_common_calloc_s(sizeof(host_config_blkio_device_read_bps_element)); - if (read_bps_dev == NULL) { + bps_dev = util_common_calloc_s(sizeof(defs_blkio_device)); + if (bps_dev == NULL) { ERROR("Out of memory"); return NULL; } @@ -850,47 +566,88 @@ static host_config_blkio_device_read_bps_element *pack_throttle_read_bps_device( goto error_out; } - read_bps_dev->path = path; - read_bps_dev->rate = rate; + bps_dev->path = path; + bps_dev->rate = rate; - return read_bps_dev; + return bps_dev; error_out: free(path); - free_host_config_blkio_device_read_bps_element(read_bps_dev); + free_defs_blkio_device(bps_dev); return NULL; } +static int parse_blkio_throttle_iops_device(const char *device, char **path, uint64_t *rate) +{ + int ret = 0; + char **split = NULL; + + split = util_string_split_multi(device, ':'); + if (split == NULL || util_array_len((const char **)split) != 2) { + COMMAND_ERROR("bad format: %s", device); + ret = -1; + goto out; + } + + if (strncmp(split[0], "/dev/", strlen("/dev/")) != 0) { + COMMAND_ERROR("bad format for device path: %s", device); + ret = -1; + goto out; + } + + if (!util_valid_positive_interger(split[1])) { + COMMAND_ERROR("invalid rate for device: %s. The correct format is :." + " Number must be unsigned 64 bytes integer.", + device); + ret = -1; + goto out; + } + + if (util_safe_uint64(split[1], rate) != 0) { + COMMAND_ERROR("invalid rate for device: %s. The correct format is :." + " Number must be unsigned 64 bytes integer.", + device); + ret = -1; + goto out; + } + + *path = util_strdup_s(split[0]); + +out: + util_free_array(split); + return ret; +} + // validate that the specified string has a valid device-rate format. -static host_config_blkio_device_write_bps_element *pack_throttle_write_bps_device(const char *device) +static defs_blkio_device *pack_throttle_iops_device(const char *device) { char *path = NULL; uint64_t rate = 0; - host_config_blkio_device_write_bps_element *write_bps_dev = NULL; + defs_blkio_device *iops_dev = NULL; if (device == NULL || !strcmp(device, "")) { - COMMAND_ERROR("blkio throttle write bps device can't be empty"); + COMMAND_ERROR("blkio throttle read bps device can't be empty"); return NULL; } - write_bps_dev = util_common_calloc_s(sizeof(host_config_blkio_device_write_bps_element)); - if (write_bps_dev == NULL) { + iops_dev = util_common_calloc_s(sizeof(defs_blkio_device)); + if (iops_dev == NULL) { ERROR("Out of memory"); return NULL; } - if (parse_blkio_throttle_bps_device(device, &path, &rate) != 0) { + if (parse_blkio_throttle_iops_device(device, &path, &rate) != 0) { goto error_out; } - write_bps_dev->path = path; - write_bps_dev->rate = rate; + iops_dev->path = path; + iops_dev->rate = rate; - return write_bps_dev; + return iops_dev; error_out: free(path); - free_host_config_blkio_device_write_bps_element(write_bps_dev); + free_defs_blkio_device(iops_dev); return NULL; } @@ -1034,7 +791,7 @@ static bool parse_host_path(const char *input, const char *token, host_config_ho COMMAND_ERROR("Host channel host path should be absolute: %s", token); return false; } - if (cleanpath(token, real_path, sizeof(real_path)) == NULL) { + if (util_clean_path(token, real_path, sizeof(real_path)) == NULL) { ERROR("Failed to clean path: '%s'", token); return false; } @@ -1058,7 +815,7 @@ static bool parse_container_path(const char *input, const char *token, host_conf COMMAND_ERROR("Host channel container path should be absolute: %s", token); return false; } - if (cleanpath(token, real_path, sizeof(real_path)) == NULL) { + if (util_clean_path(token, real_path, sizeof(real_path)) == NULL) { ERROR("Failed to clean path: '%s'", token); return false; } @@ -1178,25 +935,10 @@ erro_out: } static int append_no_new_privileges_to_security_opts(host_config *dstconfig) { - int ret = 0; - size_t new_size, old_size; - char **tmp_security_opt = NULL; - - if (dstconfig->security_opt_len > (SIZE_MAX / sizeof(char *)) - 1) { - COMMAND_ERROR("Out of memory"); - return -1; - } - new_size = (dstconfig->security_opt_len + 1) * sizeof(char *); - old_size = dstconfig->security_opt_len * sizeof(char *); - ret = mem_realloc((void **)(&tmp_security_opt), new_size, (void *)dstconfig->security_opt, old_size); - if (ret != 0) { - COMMAND_ERROR("Out of memory"); - return ret; - } - dstconfig->security_opt = tmp_security_opt; - dstconfig->security_opt[dstconfig->security_opt_len++] = util_strdup_s("no-new-privileges"); + dstconfig->security_opt[dstconfig->security_opt_len] = util_strdup_s("no-new-privileges"); + dstconfig->security_opt_len++; - return ret; + return 0; } static int append_seccomp_to_security_opts(const char *full_opt, const char *seccomp_file, host_config *dstconfig) @@ -1218,8 +960,7 @@ static int append_seccomp_to_security_opts(const char *full_opt, const char *sec seccomp_spec = get_seccomp_security_opt_spec(seccomp_file); if (seccomp_spec == NULL) { - ERROR("Failed to parse docker format seccomp specification file \"%s\", error message: %s", - seccomp_file, err); + ERROR("Failed to parse docker format seccomp specification file \"%s\", error message: %s", seccomp_file, err); COMMAND_ERROR("failed to parse seccomp file: %s", seccomp_file); ret = -1; goto out; @@ -1262,29 +1003,15 @@ out: return ret; } +#ifdef ENABLE_SELINUX static int append_selinux_label_to_security_opts(const char *selinux_label, host_config *dstconfig) { - int ret = 0; - size_t new_size; - size_t old_size; - char **tmp_security_opt = NULL; - - if (dstconfig->security_opt_len > (SIZE_MAX / sizeof(char *)) - 1) { - COMMAND_ERROR("Too large security options"); - return -1; - } - new_size = (dstconfig->security_opt_len + 1) * sizeof(char *); - old_size = dstconfig->security_opt_len * sizeof(char *); - ret = mem_realloc((void **)(&tmp_security_opt), new_size, (void *)dstconfig->security_opt, old_size); - if (ret != 0) { - COMMAND_ERROR("Out of memory"); - return ret; - } - dstconfig->security_opt = tmp_security_opt; - dstconfig->security_opt[dstconfig->security_opt_len++] = util_strdup_s(selinux_label); + dstconfig->security_opt[dstconfig->security_opt_len] = util_strdup_s(selinux_label); + dstconfig->security_opt_len++; - return ret; + return 0; } +#endif static int parse_security_opts(const isula_host_config_t *srcconfig, host_config *dstconfig) { @@ -1303,8 +1030,10 @@ static int parse_security_opts(const isula_host_config_t *srcconfig, host_config } else { if (strcmp(items[0], "seccomp") == 0) { ret = append_seccomp_to_security_opts(srcconfig->security[i], items[1], dstconfig); +#ifdef ENABLE_SELINUX } else if (strcmp(items[0], "label") == 0) { ret = append_selinux_label_to_security_opts(srcconfig->security[i], dstconfig); +#endif } else { ret = -1; } @@ -1325,61 +1054,55 @@ out: return ret; } -int generate_storage_opts(host_config **dstconfig, const isula_host_config_t *srcconfig) +int generate_storage_opts(host_config *dstconfig, const isula_host_config_t *srcconfig) { int ret = 0; - size_t j; - if (srcconfig->storage_opts == NULL || dstconfig == NULL) { + if (srcconfig->storage_opts == NULL) { goto out; } - (*dstconfig)->storage_opt = util_common_calloc_s(sizeof(json_map_string_string)); - if ((*dstconfig)->storage_opt == NULL) { + dstconfig->storage_opt = util_common_calloc_s(sizeof(json_map_string_string)); + if (dstconfig->storage_opt == NULL) { ret = -1; goto out; } - for (j = 0; j < srcconfig->storage_opts->len; j++) { - ret = append_json_map_string_string((*dstconfig)->storage_opt, - srcconfig->storage_opts->keys[j], - srcconfig->storage_opts->values[j]); - if (ret != 0) { - ERROR("Append map failed"); - ret = -1; - goto out; - } - } -out: + if (dup_json_map_string_string(srcconfig->storage_opts, dstconfig->storage_opt) != 0) { + COMMAND_ERROR("Failed to dup storage opts"); + ret = -1; + goto out; + } + +out: return ret; } -static int generate_sysctls(host_config **dstconfig, const isula_host_config_t *srcconfig) +static int generate_sysctls(host_config *dstconfig, const isula_host_config_t *srcconfig) { int ret = 0; - size_t j; - if (srcconfig->sysctls == NULL || dstconfig == NULL) { + if (srcconfig->sysctls == NULL) { goto out; } - (*dstconfig)->sysctls = util_common_calloc_s(sizeof(json_map_string_string)); - if ((*dstconfig)->sysctls == NULL) { + dstconfig->sysctls = util_common_calloc_s(sizeof(json_map_string_string)); + if (dstconfig->sysctls == NULL) { ret = -1; goto out; } - for (j = 0; j < srcconfig->sysctls->len; j++) { - ret = append_json_map_string_string((*dstconfig)->sysctls, srcconfig->sysctls->keys[j], - srcconfig->sysctls->values[j]); - if (ret < 0) { - goto out; - } + + if (dup_json_map_string_string(srcconfig->sysctls, dstconfig->sysctls) != 0) { + COMMAND_ERROR("Failed to dup sysctls"); + ret = -1; + goto out; } + out: return ret; } -int generate_devices(host_config **dstconfig, const isula_host_config_t *srcconfig) +int generate_devices(host_config *dstconfig, const isula_host_config_t *srcconfig) { int ret = 0; size_t i = 0; @@ -1393,26 +1116,26 @@ int generate_devices(host_config **dstconfig, const isula_host_config_t *srcconf ret = -1; goto out; } - (*dstconfig)->devices = util_common_calloc_s(sizeof(host_config_devices_element *) * srcconfig->devices_len); - if ((*dstconfig)->devices == NULL) { + dstconfig->devices = util_common_calloc_s(sizeof(host_config_devices_element *) * srcconfig->devices_len); + if (dstconfig->devices == NULL) { ret = -1; goto out; } for (i = 0; i < srcconfig->devices_len; i++) { - (*dstconfig)->devices[i] = parse_device(srcconfig->devices[i]); - if ((*dstconfig)->devices[i] == NULL) { + dstconfig->devices[i] = parse_device(srcconfig->devices[i]); + if (dstconfig->devices[i] == NULL) { ERROR("Failed to parse devices:%s", srcconfig->devices[i]); ret = -1; goto out; } - (*dstconfig)->devices_len++; + dstconfig->devices_len++; } out: return ret; } -static int generate_blkio_weight_device(host_config **dstconfig, const isula_host_config_t *srcconfig) +static int generate_blkio_weight_device(host_config *dstconfig, const isula_host_config_t *srcconfig) { int ret = 0; size_t i = 0; @@ -1421,118 +1144,153 @@ static int generate_blkio_weight_device(host_config **dstconfig, const isula_hos goto out; } - if (srcconfig->blkio_weight_device_len > SIZE_MAX / sizeof(host_config_blkio_weight_device_element *)) { - ERROR("Too many blkio weight devies to get!"); + dstconfig->blkio_weight_device = + util_smart_calloc_s(sizeof(defs_blkio_weight_device *), srcconfig->blkio_weight_device_len); + if (dstconfig->blkio_weight_device == NULL) { ret = -1; goto out; } - (*dstconfig)->blkio_weight_device = - util_common_calloc_s(srcconfig->blkio_weight_device_len * sizeof(host_config_blkio_weight_device_element *)); - if ((*dstconfig)->blkio_weight_device == NULL) { - ret = -1; - goto out; - } for (i = 0; i < srcconfig->blkio_weight_device_len; i++) { - (*dstconfig)->blkio_weight_device[(*dstconfig)->blkio_weight_device_len] = + dstconfig->blkio_weight_device[dstconfig->blkio_weight_device_len] = pack_blkio_weight_devices(srcconfig->blkio_weight_device[i]); - if ((*dstconfig)->blkio_weight_device[(*dstconfig)->blkio_weight_device_len] == NULL) { + if (dstconfig->blkio_weight_device[dstconfig->blkio_weight_device_len] == NULL) { ERROR("Failed to get blkio weight devies"); ret = -1; goto out; } - (*dstconfig)->blkio_weight_device_len++; + dstconfig->blkio_weight_device_len++; } out: return ret; } -static int generate_blkio_throttle_read_bps_device(host_config **dstconfig, const isula_host_config_t *srcconfig) +static int generate_blkio_throttle_read_bps_device(host_config *dstconfig, const isula_host_config_t *srcconfig) { int ret = 0; size_t i = 0; - if (dstconfig == NULL || *dstconfig == NULL) { + if (srcconfig->blkio_throttle_read_bps_device == NULL || srcconfig->blkio_throttle_read_bps_device_len == 0) { goto out; } - if (srcconfig->blkio_throttle_read_bps_device == NULL || srcconfig->blkio_throttle_read_bps_device_len == 0) { + dstconfig->blkio_device_read_bps = + util_smart_calloc_s(sizeof(defs_blkio_device *), srcconfig->blkio_throttle_read_bps_device_len); + if (dstconfig->blkio_device_read_bps == NULL) { + ret = -1; goto out; } - if (srcconfig->blkio_throttle_read_bps_device_len > - SIZE_MAX / sizeof(host_config_blkio_device_read_bps_element *)) { - ERROR("Too many blkio throttle read bps devies to get!"); - ret = -1; + for (i = 0; i < srcconfig->blkio_throttle_read_bps_device_len; i++) { + dstconfig->blkio_device_read_bps[dstconfig->blkio_device_read_bps_len] = + pack_throttle_bps_device(srcconfig->blkio_throttle_read_bps_device[i]); + if (dstconfig->blkio_device_read_bps[dstconfig->blkio_device_read_bps_len] == NULL) { + ERROR("Failed to get blkio throttle read bps devices"); + ret = -1; + goto out; + } + + dstconfig->blkio_device_read_bps_len++; + } +out: + return ret; +} + +static int generate_blkio_throttle_write_bps_device(host_config *dstconfig, const isula_host_config_t *srcconfig) +{ + int ret = 0; + size_t i = 0; + + if (srcconfig->blkio_throttle_write_bps_device == NULL || srcconfig->blkio_throttle_write_bps_device_len == 0) { goto out; } - (*dstconfig)->blkio_device_read_bps = - util_common_calloc_s(srcconfig->blkio_throttle_read_bps_device_len * - sizeof(host_config_blkio_device_read_bps_element *)); - if ((*dstconfig)->blkio_device_read_bps == NULL) { + dstconfig->blkio_device_write_bps = + util_smart_calloc_s(sizeof(defs_blkio_device *), srcconfig->blkio_throttle_write_bps_device_len); + if (dstconfig->blkio_device_write_bps == NULL) { ret = -1; goto out; } - for (i = 0; i < srcconfig->blkio_throttle_read_bps_device_len; i++) { - (*dstconfig)->blkio_device_read_bps[(*dstconfig)->blkio_device_read_bps_len] = - pack_throttle_read_bps_device(srcconfig->blkio_throttle_read_bps_device[i]); - if ((*dstconfig)->blkio_device_read_bps[(*dstconfig)->blkio_device_read_bps_len] == NULL) { - ERROR("Failed to get blkio throttle read bps devices"); + + for (i = 0; i < srcconfig->blkio_throttle_write_bps_device_len; i++) { + dstconfig->blkio_device_write_bps[dstconfig->blkio_device_write_bps_len] = + pack_throttle_bps_device(srcconfig->blkio_throttle_write_bps_device[i]); + if (dstconfig->blkio_device_write_bps[dstconfig->blkio_device_write_bps_len] == NULL) { + ERROR("Failed to get blkio throttle write bps devices"); ret = -1; goto out; } - (*dstconfig)->blkio_device_read_bps_len++; + dstconfig->blkio_device_write_bps_len++; } out: return ret; } -static int generate_blkio_throttle_write_bps_device(host_config **dstconfig, const isula_host_config_t *srcconfig) +static int generate_blkio_throttle_read_iops_device(host_config *dstconfig, const isula_host_config_t *srcconfig) { int ret = 0; size_t i = 0; - if (dstconfig == NULL || *dstconfig == NULL) { + if (srcconfig->blkio_throttle_read_iops_device == NULL || srcconfig->blkio_throttle_read_iops_device_len == 0) { goto out; } - if (srcconfig->blkio_throttle_write_bps_device == NULL || srcconfig->blkio_throttle_write_bps_device_len == 0) { + dstconfig->blkio_device_read_iops = + util_smart_calloc_s(sizeof(defs_blkio_device *), srcconfig->blkio_throttle_read_iops_device_len); + if (dstconfig->blkio_device_read_iops == NULL) { + ret = -1; goto out; } + for (i = 0; i < srcconfig->blkio_throttle_read_iops_device_len; i++) { + dstconfig->blkio_device_read_iops[dstconfig->blkio_device_read_iops_len] = + pack_throttle_iops_device(srcconfig->blkio_throttle_read_iops_device[i]); + if (dstconfig->blkio_device_read_iops[dstconfig->blkio_device_read_iops_len] == NULL) { + ERROR("Failed to get blkio throttle read iops devices"); + ret = -1; + goto out; + } - if (srcconfig->blkio_throttle_write_bps_device_len > - SIZE_MAX / sizeof(host_config_blkio_device_write_bps_element *)) { - ERROR("Too many blkio throttle write bps devies to get!"); - ret = -1; + dstconfig->blkio_device_read_iops_len++; + } +out: + return ret; +} + +static int generate_blkio_throttle_write_iops_device(host_config *dstconfig, const isula_host_config_t *srcconfig) +{ + int ret = 0; + size_t i = 0; + + if (srcconfig->blkio_throttle_write_iops_device == NULL || srcconfig->blkio_throttle_write_iops_device_len == 0) { goto out; } - (*dstconfig)->blkio_device_write_bps = util_common_calloc_s(srcconfig->blkio_throttle_write_bps_device_len * - sizeof(host_config_blkio_device_write_bps_element *)); - if ((*dstconfig)->blkio_device_write_bps == NULL) { + dstconfig->blkio_device_write_iops = + util_smart_calloc_s(sizeof(defs_blkio_device *), srcconfig->blkio_throttle_write_iops_device_len); + if (dstconfig->blkio_device_write_iops == NULL) { ret = -1; goto out; } - for (i = 0; i < srcconfig->blkio_throttle_write_bps_device_len; i++) { - (*dstconfig)->blkio_device_write_bps[(*dstconfig)->blkio_device_write_bps_len] = - pack_throttle_write_bps_device(srcconfig->blkio_throttle_write_bps_device[i]); - if ((*dstconfig)->blkio_device_write_bps[(*dstconfig)->blkio_device_write_bps_len] == NULL) { - ERROR("Failed to get blkio throttle write bps devices"); + + for (i = 0; i < srcconfig->blkio_throttle_write_iops_device_len; i++) { + dstconfig->blkio_device_write_iops[dstconfig->blkio_device_write_iops_len] = + pack_throttle_iops_device(srcconfig->blkio_throttle_write_iops_device[i]); + if (dstconfig->blkio_device_write_iops[dstconfig->blkio_device_write_iops_len] == NULL) { + ERROR("Failed to get blkio throttle write iops devices"); ret = -1; goto out; } - (*dstconfig)->blkio_device_write_bps_len++; + dstconfig->blkio_device_write_iops_len++; } out: return ret; } -static int generate_blkio(host_config **dstconfig, const isula_host_config_t *srcconfig) +static int generate_blkio(host_config *dstconfig, const isula_host_config_t *srcconfig) { int ret; @@ -1541,6 +1299,7 @@ static int generate_blkio(host_config **dstconfig, const isula_host_config_t *sr if (ret < 0) { goto out; } + /* blkio throttle read bps devies */ ret = generate_blkio_throttle_read_bps_device(dstconfig, srcconfig); if (ret < 0) { @@ -1553,11 +1312,23 @@ static int generate_blkio(host_config **dstconfig, const isula_host_config_t *sr goto out; } + /* blkio throttle read iops devies */ + ret = generate_blkio_throttle_read_iops_device(dstconfig, srcconfig); + if (ret < 0) { + goto out; + } + + /* blkio throttle write iops devies */ + ret = generate_blkio_throttle_write_iops_device(dstconfig, srcconfig); + if (ret < 0) { + goto out; + } + out: return ret; } -int generate_hugetlb_limits(host_config **dstconfig, const isula_host_config_t *srcconfig) +int generate_hugetlb_limits(host_config *dstconfig, const isula_host_config_t *srcconfig) { int ret = 0; size_t i = 0; @@ -1572,83 +1343,59 @@ int generate_hugetlb_limits(host_config **dstconfig, const isula_host_config_t * goto out; } - (*dstconfig)->hugetlbs = util_common_calloc_s(srcconfig->hugetlbs_len * sizeof(host_config_hugetlbs_element *)); - if ((*dstconfig)->hugetlbs == NULL) { + dstconfig->hugetlbs = util_common_calloc_s(srcconfig->hugetlbs_len * sizeof(host_config_hugetlbs_element *)); + if (dstconfig->hugetlbs == NULL) { ret = -1; goto out; } for (i = 0; i < srcconfig->hugetlbs_len; i++) { - (*dstconfig)->hugetlbs[(*dstconfig)->hugetlbs_len] = pase_hugetlb_limit(srcconfig->hugetlbs[i]); - if ((*dstconfig)->hugetlbs[(*dstconfig)->hugetlbs_len] == NULL) { + dstconfig->hugetlbs[dstconfig->hugetlbs_len] = pase_hugetlb_limit(srcconfig->hugetlbs[i]); + if (dstconfig->hugetlbs[dstconfig->hugetlbs_len] == NULL) { ERROR("Failed to get hugepage limits"); ret = -1; goto out; } - (*dstconfig)->hugetlbs_len++; + dstconfig->hugetlbs_len++; } out: return ret; } -int generate_binds(host_config **dstconfig, const isula_host_config_t *srcconfig) +int generate_binds(host_config *dstconfig, const isula_host_config_t *srcconfig) { - int ret = 0; - size_t i = 0; - - if (srcconfig->binds == NULL || srcconfig->binds_len == 0) { - goto out; + if (util_dup_array_of_strings((const char **)srcconfig->binds, srcconfig->binds_len, &dstconfig->binds, + &dstconfig->binds_len) != 0) { + COMMAND_ERROR("Failed to dup binds"); + return -1; } - if (srcconfig->binds_len > SIZE_MAX / sizeof(char *)) { - COMMAND_ERROR("Too many binds to mount!"); - ret = -1; - goto out; - } + return 0; +} - (*dstconfig)->binds = util_common_calloc_s(srcconfig->binds_len * sizeof(char *)); - if ((*dstconfig)->binds == NULL) { - ret = -1; - goto out; - } - for (i = 0; i < srcconfig->binds_len; i++) { - (*dstconfig)->binds[(*dstconfig)->binds_len] = util_strdup_s(srcconfig->binds[i]); - (*dstconfig)->binds_len++; +int generate_device_cgroup_rules(host_config *dstconfig, const isula_host_config_t *srcconfig) +{ + if (util_dup_array_of_strings((const char **)srcconfig->device_cgroup_rules, srcconfig->device_cgroup_rules_len, + &dstconfig->device_cgroup_rules, &dstconfig->device_cgroup_rules_len) != 0) { + COMMAND_ERROR("Failed to dup device cgroup rules"); + return -1; } -out: - return ret; + return 0; } -int generate_groups(host_config **dstconfig, const isula_host_config_t *srcconfig) +int generate_groups(host_config *dstconfig, const isula_host_config_t *srcconfig) { - int ret = 0; - size_t i = 0; - - if (srcconfig->group_add == NULL || srcconfig->group_add_len == 0 || dstconfig == NULL) { - goto out; - } - - if (srcconfig->group_add_len > SIZE_MAX / sizeof(char *)) { - COMMAND_ERROR("Too many groups to add!"); - ret = -1; - goto out; + if (util_dup_array_of_strings((const char **)srcconfig->group_add, srcconfig->group_add_len, &dstconfig->group_add, + &dstconfig->group_add_len) != 0) { + COMMAND_ERROR("Failed to dup device group add"); + return -1; } - (*dstconfig)->group_add = util_common_calloc_s(srcconfig->group_add_len * sizeof(char *)); - if ((*dstconfig)->group_add == NULL) { - ret = -1; - goto out; - } - for (i = 0; i < srcconfig->group_add_len; i++) { - (*dstconfig)->group_add[(*dstconfig)->group_add_len] = util_strdup_s(srcconfig->group_add[i]); - (*dstconfig)->group_add_len++; - } -out: - return ret; + return 0; } -int generate_security(host_config **dstconfig, const isula_host_config_t *srcconfig) +int generate_security(host_config *dstconfig, const isula_host_config_t *srcconfig) { int ret = 0; @@ -1662,13 +1409,13 @@ int generate_security(host_config **dstconfig, const isula_host_config_t *srccon goto out; } - (*dstconfig)->security_opt = util_common_calloc_s(srcconfig->security_len * sizeof(char *)); - if ((*dstconfig)->security_opt == NULL) { + dstconfig->security_opt = util_common_calloc_s(srcconfig->security_len * sizeof(char *)); + if (dstconfig->security_opt == NULL) { ret = -1; goto out; } - if (parse_security_opts(srcconfig, (*dstconfig)) != 0) { + if (parse_security_opts(srcconfig, dstconfig) != 0) { ret = -1; goto out; } @@ -1703,12 +1450,12 @@ static int pack_host_config_common(host_config *dstconfig, const isula_host_conf goto out; } - ret = generate_storage_opts(&dstconfig, srcconfig); + ret = generate_storage_opts(dstconfig, srcconfig); if (ret < 0) { goto out; } - ret = generate_sysctls(&dstconfig, srcconfig); + ret = generate_sysctls(dstconfig, srcconfig); if (ret < 0) { goto out; } @@ -1719,40 +1466,47 @@ static int pack_host_config_common(host_config *dstconfig, const isula_host_conf } /* devices which will be populated into container */ - ret = generate_devices(&dstconfig, srcconfig); + ret = generate_devices(dstconfig, srcconfig); if (ret < 0) { goto out; } /* blkio device */ - ret = generate_blkio(&dstconfig, srcconfig); + ret = generate_blkio(dstconfig, srcconfig); if (ret < 0) { goto out; } /* hugepage limits */ - ret = generate_hugetlb_limits(&dstconfig, srcconfig); + ret = generate_hugetlb_limits(dstconfig, srcconfig); if (ret < 0) { goto out; } /* binds to mount */ - ret = generate_binds(&dstconfig, srcconfig); + ret = generate_binds(dstconfig, srcconfig); if (ret < 0) { goto out; } /* groups to add */ - ret = generate_groups(&dstconfig, srcconfig); + ret = generate_groups(dstconfig, srcconfig); if (ret < 0) { goto out; } /* security opt */ - ret = generate_security(&dstconfig, srcconfig); + ret = generate_security(dstconfig, srcconfig); + if (ret < 0) { + goto out; + } + + /* device cgroup rules*/ + ret = generate_device_cgroup_rules(dstconfig, srcconfig); if (ret < 0) { goto out; } + out: return ret; } @@ -1764,7 +1518,7 @@ int generate_hostconfig(const isula_host_config_t *srcconfig, char **hostconfigs host_config *dstconfig = NULL; struct parser_context ctx = { OPT_GEN_SIMPLIFY, 0 }; - dstconfig = util_common_calloc_s(sizeof(*dstconfig)); + dstconfig = util_common_calloc_s(sizeof(host_config)); if (dstconfig == NULL) { ret = -1; goto out; @@ -1823,421 +1577,155 @@ out: return ret; } -static int pack_container_custom_config_args(container_config *container_spec, - const isula_container_config_t *custom_conf) +void isula_ns_change_files_free(isula_host_config_t *hostconfig) { - int ret = 0; - int i; - - /* entrypoint */ - if (util_valid_str(custom_conf->entrypoint)) { - container_spec->entrypoint = util_common_calloc_s(sizeof(char *)); - if (container_spec->entrypoint == NULL) { - ret = -1; - goto out; - } - container_spec->entrypoint[0] = util_strdup_s(custom_conf->entrypoint); - container_spec->entrypoint_len++; - } - - /* commands */ - if ((custom_conf->cmd_len != 0 && custom_conf->cmd)) { - if (custom_conf->cmd_len > SIZE_MAX / sizeof(char *)) { - COMMAND_ERROR("The length of cmd is too long!"); - ret = -1; - goto out; - } - container_spec->cmd = util_common_calloc_s(custom_conf->cmd_len * sizeof(char *)); - if (container_spec->cmd == NULL) { - ret = -1; - goto out; - } - for (i = 0; i < (int)custom_conf->cmd_len; i++) { - container_spec->cmd[container_spec->cmd_len] = util_strdup_s(custom_conf->cmd[i]); - container_spec->cmd_len++; - } - } - -out: - return ret; -} - -static int pack_container_custom_config_mounts(container_config *container_spec, - const isula_container_config_t *custom_conf) -{ - int ret = 0; - int i = 0; - - /* mounts to mount filesystem */ - if (custom_conf->mounts != NULL && custom_conf->mounts_len > 0) { - if (custom_conf->mounts_len > SIZE_MAX / sizeof(char *)) { - COMMAND_ERROR("Too many mounts to mount filesystem!"); - ret = -1; - goto out; - } - container_spec->mounts = util_common_calloc_s(custom_conf->mounts_len * sizeof(char *)); - if (container_spec->mounts == NULL) { - ret = -1; - goto out; - } - for (i = 0; i < (int)custom_conf->mounts_len; i++) { - container_spec->mounts[container_spec->mounts_len] = util_strdup_s(custom_conf->mounts[i]); - container_spec->mounts_len++; - } - } -out: - return ret; -} - -static int pack_container_custom_config_array(container_config *container_spec, - const isula_container_config_t *custom_conf) -{ - int ret = 0; - int i = 0; - - /* environment variables */ - if (custom_conf->env_len != 0 && custom_conf->env) { - if (custom_conf->env_len > SIZE_MAX / sizeof(char *)) { - COMMAND_ERROR("Too many environment variables"); - return -1; - } - container_spec->env = util_common_calloc_s(custom_conf->env_len * sizeof(char *)); - if (container_spec->env == NULL) { - ret = -1; - goto out; - } - for (i = 0; i < (int)custom_conf->env_len; i++) { - container_spec->env[container_spec->env_len] = util_strdup_s(custom_conf->env[i]); - container_spec->env_len++; - } - } - -out: - return ret; -} - -static int get_label_key_value(const char *label, char **key, char **value) -{ - int ret = 0; - char **arr = util_string_split_n(label, '=', 2); - if (arr == NULL) { - ERROR("Failed to split input label"); - ret = -1; - goto out; - } - - *key = util_strdup_s(arr[0]); - if (util_array_len((const char **)arr) == 1) { - *value = util_strdup_s(""); - } else { - *value = util_strdup_s(arr[1]); + if (hostconfig == NULL) { + return; } -out: - util_free_array(arr); - return ret; + util_free_array_by_len(hostconfig->ns_change_files, hostconfig->ns_change_files_len); + hostconfig->ns_change_files = NULL; + hostconfig->ns_change_files_len = 0; } -static int pack_container_custom_config_labels(container_config *container_spec, - const isula_container_config_t *custom_conf) +void isula_host_config_storage_opts_free(isula_host_config_t *hostconfig) { - int ret = 0; - int i; - char *key = NULL; - char *value = NULL; - - if (custom_conf->label_len == 0 || custom_conf->label == NULL) { - return 0; - } - - /* labels */ - container_spec->labels = util_common_calloc_s(sizeof(json_map_string_string)); - if (container_spec->labels == NULL) { - ERROR("Out of memory"); - ret = -1; - goto out; - } - - for (i = 0; i < custom_conf->label_len; i++) { - if (get_label_key_value(custom_conf->label[i], &key, &value) != 0) { - ERROR("Failed to get key and value of label"); - ret = -1; - goto out; - } - - if (append_json_map_string_string(container_spec->labels, key, value)) { - ERROR("Append map failed"); - ret = -1; - goto out; - } - free(key); - key = NULL; - free(value); - value = NULL; + if (hostconfig == NULL) { + return; } -out: - free(key); - free(value); - return ret; + free_json_map_string_string(hostconfig->storage_opts); + hostconfig->storage_opts = NULL; } -static bool have_health_check(const isula_container_config_t *custom_conf) +void isula_host_config_sysctl_free(isula_host_config_t *hostconfig) { - bool have_health_settings = false; - - if ((custom_conf->health_cmd != NULL && strlen(custom_conf->health_cmd) != 0) || - custom_conf->health_interval != 0 || custom_conf->health_timeout != 0 || - custom_conf->health_start_period != 0 || custom_conf->health_retries != 0) { - have_health_settings = true; + if (hostconfig == NULL) { + return; } - return have_health_settings; + free_json_map_string_string(hostconfig->sysctls); + hostconfig->sysctls = NULL; } -static int pack_custom_no_health_check(container_config *container_spec, bool have_health_settings, - defs_health_check *health_config) +/* container cgroup resources free */ +static void container_cgroup_resources_free(container_cgroup_resources_t *cr) { - int ret = 0; - - if (have_health_settings) { - COMMAND_ERROR("--no-healthcheck conflicts with --health-* options"); - ret = -1; - goto out; - } - health_config->test = util_common_calloc_s(sizeof(char *)); - if (health_config->test == NULL) { - ret = -1; - goto out; + if (cr == NULL) { + return; } - health_config->test[health_config->test_len++] = util_strdup_s("NONE"); - container_spec->healthcheck = health_config; - -out: - return ret; -} + free(cr->cpuset_cpus); + cr->cpuset_cpus = NULL; -static int pack_custom_with_health_check(container_config *container_spec, - const isula_container_config_t *custom_conf, bool have_health_settings, - defs_health_check *health_config) -{ - int ret = 0; + free(cr->cpuset_mems); + cr->cpuset_mems = NULL; - if (custom_conf->health_cmd != NULL && strlen(custom_conf->health_cmd) != 0) { - health_config->test = util_common_calloc_s(2 * sizeof(char *)); - if (health_config->test == NULL) { - ret = -1; - goto out; - } - health_config->test[health_config->test_len++] = util_strdup_s("CMD-SHELL"); - health_config->test[health_config->test_len++] = util_strdup_s(custom_conf->health_cmd); - } else { - COMMAND_ERROR("--health-cmd required!"); - ret = -1; - goto out; - } - health_config->interval = custom_conf->health_interval; - health_config->timeout = custom_conf->health_timeout; - health_config->start_period = custom_conf->health_start_period; - health_config->retries = custom_conf->health_retries; - health_config->exit_on_unhealthy = custom_conf->exit_on_unhealthy; - if (container_spec->healthcheck != NULL) { - free_defs_health_check(container_spec->healthcheck); - } - container_spec->healthcheck = health_config; - -out: - return ret; + free(cr); } -static int pack_container_custom_config_health(container_config *container_spec, - const isula_container_config_t *custom_conf) +/* isula host config free */ +void isula_host_config_free(isula_host_config_t *hostconfig) { - int ret = 0; - bool have_health_settings = false; - defs_health_check *health_config = NULL; - - if (container_spec == NULL || custom_conf == NULL) { - return 0; - } - - have_health_settings = have_health_check(custom_conf); - - health_config = util_common_calloc_s(sizeof(defs_health_check)); - if (health_config == NULL) { - ret = -1; - goto out; - } - - if (custom_conf->no_healthcheck) { - ret = pack_custom_no_health_check(container_spec, have_health_settings, health_config); - if (ret != 0) { - goto out; - } - } else if (have_health_settings) { - ret = pack_custom_with_health_check(container_spec, custom_conf, have_health_settings, health_config); - if (ret != 0) { - goto out; - } - } else { - goto out; + if (hostconfig == NULL) { + return; } - return ret; + util_free_array_by_len(hostconfig->cap_add, hostconfig->cap_add_len); + hostconfig->cap_add = NULL; + hostconfig->cap_add_len = 0; -out: - free_defs_health_check(health_config); - return ret; -} + util_free_array_by_len(hostconfig->cap_drop, hostconfig->cap_drop_len); + hostconfig->cap_drop = NULL; + hostconfig->cap_drop_len = 0; -static int pack_container_custom_config_annotation(container_config *container_spec, - const isula_container_config_t *custom_conf) -{ - int ret = 0; - size_t j; + free_json_map_string_string(hostconfig->storage_opts); + hostconfig->storage_opts = NULL; - container_spec->annotations = util_common_calloc_s(sizeof(json_map_string_string)); - if (container_spec->annotations == NULL) { - ERROR("Out of memory"); - ret = -1; - goto out; - } - if (custom_conf->annotations != NULL) { - for (j = 0; j < custom_conf->annotations->len; j++) { - if (append_json_map_string_string(container_spec->annotations, custom_conf->annotations->keys[j], - custom_conf->annotations->values[j])) { - ERROR("Append map failed"); - ret = -1; - goto out; - } - } - } -out: - return ret; -} + free_json_map_string_string(hostconfig->sysctls); + hostconfig->sysctls = NULL; -static int pack_container_custom_config_pre(container_config *container_spec, - const isula_container_config_t *custom_conf) -{ - int ret = 0; + util_free_array_by_len(hostconfig->devices, hostconfig->devices_len); + hostconfig->devices = NULL; + hostconfig->devices_len = 0; - ret = pack_container_custom_config_args(container_spec, custom_conf); - if (ret != 0) { - goto out; - } + util_free_array_by_len(hostconfig->ns_change_files, hostconfig->ns_change_files_len); + hostconfig->ns_change_files = NULL; + hostconfig->ns_change_files_len = 0; - ret = pack_container_custom_config_mounts(container_spec, custom_conf); - if (ret != 0) { - goto out; - } + util_free_array_by_len(hostconfig->hugetlbs, hostconfig->hugetlbs_len); + hostconfig->hugetlbs = NULL; + hostconfig->hugetlbs_len = 0; - ret = pack_container_custom_config_array(container_spec, custom_conf); - if (ret != 0) { - goto out; - } + free(hostconfig->network_mode); + hostconfig->network_mode = NULL; - ret = pack_container_custom_config_labels(container_spec, custom_conf); - if (ret != 0) { - goto out; - } + free(hostconfig->ipc_mode); + hostconfig->ipc_mode = NULL; - ret = pack_container_custom_config_health(container_spec, custom_conf); - if (ret != 0) { - goto out; - } -out: - return ret; -} + free(hostconfig->pid_mode); + hostconfig->pid_mode = NULL; -/* translate create_custom_config to container_config */ -static int pack_container_custom_config(container_config *container_spec, - const isula_container_config_t *custom_conf) -{ - int ret = -1; + free(hostconfig->uts_mode); + hostconfig->uts_mode = NULL; - if (container_spec == NULL || custom_conf == NULL) { - return ret; - } + free(hostconfig->userns_mode); + hostconfig->userns_mode = NULL; - ret = pack_container_custom_config_pre(container_spec, custom_conf); - if (ret != 0) { - goto out; - } + free(hostconfig->user_remap); + hostconfig->user_remap = NULL; - if (custom_conf->hostname != NULL) { - container_spec->hostname = util_strdup_s(custom_conf->hostname); - } - container_spec->log_driver = util_strdup_s(custom_conf->log_driver); + util_free_array_by_len(hostconfig->ulimits, hostconfig->ulimits_len); + hostconfig->ulimits = NULL; + hostconfig->ulimits_len = 0; - /* console config */ - container_spec->tty = custom_conf->tty; - container_spec->open_stdin = custom_conf->open_stdin; - container_spec->attach_stdin = custom_conf->attach_stdin; - container_spec->attach_stdout = custom_conf->attach_stdout; - container_spec->attach_stderr = custom_conf->attach_stderr; + free(hostconfig->restart_policy); + hostconfig->restart_policy = NULL; - /* user and group */ - if (custom_conf->user != NULL) { - container_spec->user = util_strdup_s(custom_conf->user); - } + free(hostconfig->host_channel); + hostconfig->host_channel = NULL; - /* settings for system container */ - if (custom_conf->system_container) { - container_spec->system_container = custom_conf->system_container; - } + free(hostconfig->hook_spec); + hostconfig->hook_spec = NULL; - if (custom_conf->ns_change_opt != NULL) { - container_spec->ns_change_opt = util_strdup_s(custom_conf->ns_change_opt); - } + free(hostconfig->env_target_file); + hostconfig->env_target_file = NULL; - ret = pack_container_custom_config_annotation(container_spec, custom_conf); - if (ret != 0) { - goto out; - } + free(hostconfig->cgroup_parent); + hostconfig->cgroup_parent = NULL; - if (custom_conf->workdir != NULL) { - container_spec->working_dir = util_strdup_s(custom_conf->workdir); - } + util_free_array_by_len(hostconfig->binds, hostconfig->binds_len); + hostconfig->binds = NULL; + hostconfig->binds_len = 0; -out: - return ret; -} + util_free_array_by_len(hostconfig->blkio_weight_device, hostconfig->blkio_weight_device_len); + hostconfig->blkio_weight_device = NULL; + hostconfig->blkio_weight_device_len = 0; -int generate_container_config(const isula_container_config_t *custom_conf, char **container_config_str) -{ - int ret = 0; - container_config *container_spec = NULL; - struct parser_context ctx = { OPT_GEN_SIMPLIFY, 0 }; - parser_error err = NULL; + util_free_array_by_len(hostconfig->blkio_throttle_read_bps_device, hostconfig->blkio_throttle_read_bps_device_len); + hostconfig->blkio_throttle_read_bps_device = NULL; + hostconfig->blkio_throttle_read_bps_device_len = 0; - /* step 1: malloc the container config */ - container_spec = util_common_calloc_s(sizeof(container_config)); - if (container_spec == NULL) { - ERROR("Memory out"); - ret = -1; - goto out; - } + util_free_array_by_len(hostconfig->blkio_throttle_write_bps_device, + hostconfig->blkio_throttle_write_bps_device_len); + hostconfig->blkio_throttle_write_bps_device = NULL; + hostconfig->blkio_throttle_write_bps_device_len = 0; - /* step 2: pack the container custom config */ - ret = pack_container_custom_config(container_spec, custom_conf); - if (ret != 0) { - ERROR("Failed to pack the container custom config"); - ret = -1; - goto out; - } + util_free_array_by_len(hostconfig->blkio_throttle_read_iops_device, + hostconfig->blkio_throttle_read_iops_device_len); + hostconfig->blkio_throttle_read_iops_device = NULL; + hostconfig->blkio_throttle_read_iops_device_len = 0; - /* step 3: generate the config string */ - *container_config_str = container_config_generate_json(container_spec, &ctx, &err); - if (*container_config_str == NULL) { - ERROR("Failed to generate OCI specification json string"); - ret = -1; - goto out; - } + util_free_array_by_len(hostconfig->blkio_throttle_write_iops_device, + hostconfig->blkio_throttle_write_iops_device_len); + hostconfig->blkio_throttle_write_iops_device = NULL; + hostconfig->blkio_throttle_write_iops_device_len = 0; -out: - free_container_config(container_spec); - free(err); + util_free_array_by_len(hostconfig->device_cgroup_rules, hostconfig->device_cgroup_rules_len); + hostconfig->device_cgroup_rules = NULL; + hostconfig->device_cgroup_rules_len = 0; - return ret; -} + container_cgroup_resources_free(hostconfig->cr); + hostconfig->cr = NULL; + free(hostconfig); +} \ No newline at end of file diff --git a/src/cmd/isula/isula_host_spec.h b/src/cmd/isula/isula_host_spec.h new file mode 100644 index 0000000..d464494 --- /dev/null +++ b/src/cmd/isula/isula_host_spec.h @@ -0,0 +1,156 @@ +/****************************************************************************** + * Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved. + * iSulad licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * 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 v2 for more details. + * Author: lifeng + * Create: 2020-09-28 + * Description: provide generate host spec in client + ******************************************************************************/ +#ifndef CMD_ISULA_GENERATE_HOST_SPEC_H +#define CMD_ISULA_GENERATE_HOST_SPEC_H + +#include +#include +#include +#include "isula_libutils/json_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct container_cgroup_resources { + uint16_t blkio_weight; + int64_t cpu_shares; + int64_t cpu_period; + int64_t cpu_quota; + int64_t cpu_realtime_period; + int64_t cpu_realtime_runtime; + char *cpuset_cpus; + char *cpuset_mems; + int64_t memory; + int64_t memory_swap; + int64_t memory_reservation; + int64_t kernel_memory; + int64_t pids_limit; + int64_t files_limit; + int64_t oom_score_adj; + int64_t swappiness; + int64_t nano_cpus; +} container_cgroup_resources_t; + +typedef struct isula_host_config { + char **devices; + size_t devices_len; + + char **hugetlbs; + size_t hugetlbs_len; + + char **group_add; + size_t group_add_len; + + char *network_mode; + + char *ipc_mode; + + char *pid_mode; + + char *uts_mode; + + char *userns_mode; + + char *user_remap; + + char **ulimits; + size_t ulimits_len; + + char *restart_policy; + + char *host_channel; + + char **cap_add; + size_t cap_add_len; + + char **cap_drop; + size_t cap_drop_len; + + json_map_string_string *storage_opts; + + json_map_string_string *sysctls; + + char **dns; + size_t dns_len; + + char **dns_options; + size_t dns_options_len; + + char **dns_search; + size_t dns_search_len; + + char **extra_hosts; + size_t extra_hosts_len; + + char *hook_spec; + + char **binds; + size_t binds_len; + + char **blkio_weight_device; + size_t blkio_weight_device_len; + + char **blkio_throttle_read_bps_device; + size_t blkio_throttle_read_bps_device_len; + + char **blkio_throttle_write_bps_device; + size_t blkio_throttle_write_bps_device_len; + + char **blkio_throttle_read_iops_device; + size_t blkio_throttle_read_iops_device_len; + + char **blkio_throttle_write_iops_device; + size_t blkio_throttle_write_iops_device_len; + + char **device_cgroup_rules; + size_t device_cgroup_rules_len; + + bool privileged; + bool system_container; + char **ns_change_files; + size_t ns_change_files_len; + bool auto_remove; + + bool oom_kill_disable; + + int64_t shm_size; + + bool readonly_rootfs; + + char *env_target_file; + + char *cgroup_parent; + + container_cgroup_resources_t *cr; + + char **security; + size_t security_len; +} isula_host_config_t; + +int generate_hostconfig(const isula_host_config_t *srcconfig, char **hostconfigstr); +void isula_host_config_free(isula_host_config_t *hostconfig); + +void isula_ns_change_files_free(isula_host_config_t *hostconfig); + +void isula_host_config_storage_opts_free(isula_host_config_t *hostconfig); + +void isula_host_config_sysctl_free(isula_host_config_t *hostconfig); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/cmd/isula/stream/attach.c b/src/cmd/isula/stream/attach.c index 669bb70..eadd0e9 100644 --- a/src/cmd/isula/stream/attach.c +++ b/src/cmd/isula/stream/attach.c @@ -36,7 +36,6 @@ #include "command_parser.h" #include "connect.h" #include "constants.h" -#include "libisula.h" const char g_cmd_attach_desc[] = "Attach to a running container"; const char g_cmd_attach_usage[] = "attach [OPTIONS] CONTAINER"; diff --git a/src/cmd/isula/stream/cp.c b/src/cmd/isula/stream/cp.c index b894b37..37107fb 100644 --- a/src/cmd/isula/stream/cp.c +++ b/src/cmd/isula/stream/cp.c @@ -30,7 +30,7 @@ #include "command_parser.h" #include "connect.h" #include "io_wrapper.h" -#include "libisula.h" + #include "utils.h" #define FromContainer 0x01u @@ -48,12 +48,12 @@ static char *resolve_local_path(const char *path) { char abs_path[PATH_MAX] = { 0 }; - if (cleanpath(path, abs_path, sizeof(abs_path)) == NULL) { + if (util_clean_path(path, abs_path, sizeof(abs_path)) == NULL) { ERROR("Failed to clean path"); return NULL; } - return preserve_trailing_dot_or_separator(abs_path, path); + return util_preserve_trailing_dot_or_separator(abs_path, path); } static void print_copy_from_container_error(const char *ops_err, const char *archive_err, int ret, diff --git a/src/cmd/isula/stream/exec.c b/src/cmd/isula/stream/exec.c index 6ac1a7a..761c4c0 100644 --- a/src/cmd/isula/stream/exec.c +++ b/src/cmd/isula/stream/exec.c @@ -12,11 +12,10 @@ * Create: 2018-11-08 * Description: provide container exec functions ******************************************************************************/ +#include "exec.h" #include #include #include -#include -#include #include #include #include @@ -24,7 +23,7 @@ #include #include "client_arguments.h" -#include "exec.h" +#include "client_console.h" #include "isula_libutils/log.h" #include "isula_connect.h" #include "console.h" @@ -33,7 +32,7 @@ #include "isula_libutils/container_inspect.h" #include "connect.h" #include "constants.h" -#include "libisula.h" + #include "utils_array.h" #include "utils_string.h" @@ -67,8 +66,8 @@ static int fill_exec_request(const struct client_arguments *args, const struct c request->user = util_strdup_s(args->custom_conf.user); - if (dup_array_of_strings((const char **)args->argv, args->argc, &(request->argv), (size_t *) & (request->argc)) != - 0) { + if (util_dup_array_of_strings((const char **)args->argv, args->argc, &(request->argv), + (size_t *) & (request->argc)) != 0) { ERROR("Failed to dup args"); ret = -1; goto out; @@ -76,7 +75,7 @@ static int fill_exec_request(const struct client_arguments *args, const struct c /* environment variables */ for (i = 0; i < util_array_len((const char **)(args->extra_env)); i++) { - if (util_validate_env(args->extra_env[i], &new_env) != 0) { + if (util_valid_env(args->extra_env[i], &new_env) != 0) { ERROR("Invalid environment %s", args->extra_env[i]); ret = -1; goto out; @@ -151,6 +150,45 @@ out: return ret; } +static int do_resize_exec_console(const struct client_arguments *args, unsigned int height, unsigned int width) +{ + int ret = 0; + isula_connect_ops *ops = NULL; + struct isula_resize_request request = { 0 }; + struct isula_resize_response *response = NULL; + client_connect_config_t config = { 0 }; + + ops = get_connect_client_ops(); + if (ops == NULL || ops->container.resize == NULL) { + ERROR("Unimplemented ops"); + ret = -1; + goto out; + } + + request.id = args->name; + request.suffix = args->exec_suffix; + request.height = height; + request.width = width; + + response = util_common_calloc_s(sizeof(struct isula_resize_response)); + if (response == NULL) { + ERROR("Out of memory"); + ret = -1; + goto out; + } + + config = get_connect_config(args); + ret = ops->container.resize(&request, response, &config); + if (ret != 0) { + ERROR("Failed to call resize"); + goto out; + } + +out: + isula_resize_response_free(response); + return ret; +} + static int exec_cmd_init(int argc, const char **argv) { command_t cmd; @@ -197,6 +235,8 @@ static int exec_cmd_init(int argc, const char **argv) return ECOMMON; } + g_cmd_exec_args.resize_cb = do_resize_exec_console; + return 0; } @@ -367,98 +407,6 @@ out: return exec_suffix; } -static int do_resize_exec_console(const struct client_arguments *args, unsigned int height, unsigned int width) -{ - int ret = 0; - isula_connect_ops *ops = NULL; - struct isula_resize_request request = { 0 }; - struct isula_resize_response *response = NULL; - client_connect_config_t config = { 0 }; - - ops = get_connect_client_ops(); - if (ops == NULL || ops->container.resize == NULL) { - ERROR("Unimplemented ops"); - ret = -1; - goto out; - } - - request.id = args->name; - request.suffix = args->exec_suffix; - request.height = height; - request.width = width; - - response = util_common_calloc_s(sizeof(struct isula_resize_response)); - if (response == NULL) { - ERROR("Out of memory"); - ret = -1; - goto out; - } - - config = get_connect_config(args); - ret = ops->container.resize(&request, response, &config); - if (ret != 0) { - ERROR("Failed to call resize"); - goto out; - } - -out: - isula_resize_response_free(response); - return ret; -} - -static void *exec_console_resize_thread(void *arg) -{ - int ret = 0; - const struct client_arguments *args = arg; - static struct winsize s_pre_wsz; - struct winsize wsz; - - if (!isatty(STDIN_FILENO)) { - goto out; - } - - ret = pthread_detach(pthread_self()); - if (ret != 0) { - CRIT("Start: set thread detach fail"); - goto out; - } - - while (true) { - sleep(1); // check the windows size per 1s - ret = ioctl(STDIN_FILENO, TIOCGWINSZ, &wsz); - if (ret < 0) { - WARN("Failed to get window size"); - continue; - } - if (wsz.ws_row == s_pre_wsz.ws_row && wsz.ws_col == s_pre_wsz.ws_col) { - continue; - } - ret = do_resize_exec_console(args, wsz.ws_row, wsz.ws_col); - if (ret != 0) { - continue; - } - s_pre_wsz.ws_row = wsz.ws_row; - s_pre_wsz.ws_col = wsz.ws_col; - } - -out: - return NULL; -} - -int exec_client_console_resize_thread(struct client_arguments *args) -{ - int res = 0; - pthread_t a_thread; - - res = pthread_create(&a_thread, NULL, exec_console_resize_thread, (void *)(args)); - if (res != 0) { - CRIT("Thread creation failed"); - return -1; - } - - return 0; -} - int cmd_exec_main(int argc, const char **argv) { int ret = 0; @@ -503,7 +451,7 @@ int cmd_exec_main(int argc, const char **argv) if (custom_cfg->tty && isatty(STDIN_FILENO) && (custom_cfg->attach_stdin || custom_cfg->attach_stdout || custom_cfg->attach_stderr)) { - (void)exec_client_console_resize_thread(&g_cmd_exec_args); + (void)start_client_console_resize_thread(&g_cmd_exec_args); } if (strncmp(g_cmd_exec_args.socket, "tcp://", strlen("tcp://")) == 0) { diff --git a/src/cmd/isulad-shim/main.c b/src/cmd/isulad-shim/main.c index 50b864d..3ab22d8 100644 --- a/src/cmd/isulad-shim/main.c +++ b/src/cmd/isulad-shim/main.c @@ -71,7 +71,7 @@ static int parse_args(int argc, char **argv, char **cid, char **bundle, char **r *cid = strdup(argv[1]); *bundle = strdup(argv[2]); *rt_name = strdup(argv[3]); - if (*cid == NULL || *bundle == NULL || rt_name == NULL) { + if (*cid == NULL || *bundle == NULL || *rt_name == NULL) { return SHIM_ERR; } @@ -85,7 +85,10 @@ static int parse_args(int argc, char **argv, char **cid, char **bundle, char **r return SHIM_OK; } - +/* + * Note: + * All files created in the working directory are cleared by the parent process isulad + */ int main(int argc, char **argv) { char *container_id = NULL; @@ -101,6 +104,10 @@ int main(int argc, char **argv) _exit(EXIT_FAILURE); } + /* + * The default value of DEFAULT_TIME is 120 seconds, + * which is the same as the default value of containerd + */ set_timeout_exit(DEFAULT_TIMEOUT); ret = set_subreaper(); @@ -121,7 +128,11 @@ int main(int argc, char **argv) exit(EXIT_FAILURE); } - // open exit pipe + /* + * Open exit pipe + * The exit pipe exists only when the container is started, + * and the exec operation does not contain the exit pipe. + */ if (!p->state->exec) { if (p->state->exit_fifo != NULL) { efd = open_no_inherit("exit_fifo", O_WRONLY, -1); @@ -133,7 +144,7 @@ int main(int argc, char **argv) } } - // create main loop and start epoll + /* create main loop and start epoll for io copy */ ret = process_io_init(p); if (ret != SHIM_OK) { write_message(g_log_fd, ERR_MSG, "process io init failed:%d", ret); @@ -147,6 +158,9 @@ int main(int argc, char **argv) ret = create_process(p); if (ret != SHIM_OK) { + if (p->console_sock_path != NULL) { + (void)unlink(p->console_sock_path); + } exit(EXIT_FAILURE); } diff --git a/src/cmd/isulad-shim/process.c b/src/cmd/isulad-shim/process.c index 0baa615..c693cb8 100644 --- a/src/cmd/isulad-shim/process.c +++ b/src/cmd/isulad-shim/process.c @@ -57,14 +57,13 @@ static shim_client_process_state *load_process() { parser_error err = NULL; shim_client_process_state *p_state = NULL; + p_state = shim_client_process_state_parse_file("process.json", NULL, &err); if (p_state == NULL) { write_message(g_log_fd, ERR_MSG, "parse process state failed"); } - - if (err != NULL) { - free(err); - } + /* "err" will definitely be allocated memory in the function above */ + free(err); return p_state; } @@ -73,7 +72,7 @@ static int open_fifo_noblock(const char *path, mode_t mode) { int fd = -1; - // By default, We consider that the file has been created by isulad + /* By default, We consider that the file has been created by isulad */ fd = open_no_inherit(path, mode | O_NONBLOCK, -1); if (fd < 0) { write_message(g_log_fd, ERR_MSG, "open fifo file failed:%d", SHIM_SYS_ERR(errno)); @@ -99,6 +98,7 @@ static int receive_fd(int sock) iov[0].iov_len = sizeof(buf); struct msghdr msg; + (void)memset(&msg, 0, sizeof(struct msghdr)); msg.msg_iov = iov; msg.msg_iovlen = 1; msg.msg_name = NULL; @@ -106,10 +106,16 @@ static int receive_fd(int sock) msg.msg_control = cmptr; msg.msg_controllen = cmsgsize; + /* + * return value: + * 0: the peer has performed an orderly shutdown + * -1: an error occurred + * >0: the number of bytes received + */ int ret = recvmsg(sock, &msg, 0); - if (ret == -1) { - free(cmptr); + if (ret <= 0) { write_message(g_log_fd, ERR_MSG, "get console fd failed:%d", SHIM_SYS_ERR(errno)); + free(cmptr); return -1; } @@ -140,19 +146,11 @@ static int add_io_dispatch(int epfd, io_thread_t *io_thd, int from, int to) } io_copy_t *ioc = io_thd->ioc; - fd_node_t *fn = (fd_node_t *)calloc(1, sizeof(fd_node_t)); - if (fn == NULL) { + + if (pthread_mutex_lock(&(ioc->mutex)) != 0) { 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)); - // add src fd + /* add src fd */ if (from != -1 && ioc->fd_from == -1) { ioc->fd_from = from; struct epoll_event ev; @@ -161,15 +159,27 @@ static int add_io_dispatch(int epfd, io_thread_t *io_thd, int from, int to) ret = epoll_ctl(epfd, EPOLL_CTL_ADD, from, &ev); if (ret != SHIM_OK) { - free(fn); write_message(g_log_fd, ERR_MSG, "add fd %d to epoll loop failed:%d", from, SHIM_SYS_ERR(errno)); pthread_mutex_unlock(&(ioc->mutex)); return SHIM_ERR; } } - // add dest fd + /* add dest fd */ if (to != -1) { + /* new fd_node_t for dest fd */ + fd_node_t *fn = (fd_node_t *)calloc(1, sizeof(fd_node_t)); + if (fn == NULL) { + pthread_mutex_unlock(&(ioc->mutex)); + 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; + if (ioc->fd_to == NULL) { ioc->fd_to = fn; } else { @@ -192,10 +202,13 @@ static void remove_io_dispatch(io_thread_t *io_thd, int from, int to) } io_copy_t *ioc = io_thd->ioc; - pthread_mutex_lock(&(ioc->mutex)); + if (pthread_mutex_lock(&(ioc->mutex))) { + return; + } + fd_node_t *tmp = NULL; do { - // remove src fd + /* remove src fd */ if (from != -1 && from == ioc->fd_from) { struct epoll_event ev; ev.events = EPOLLIN; @@ -203,12 +216,12 @@ static void remove_io_dispatch(io_thread_t *io_thd, int from, int to) (void)epoll_ctl(io_thd->epfd, EPOLL_CTL_DEL, ioc->fd_from, &ev); } - // remove dest fd + /* remove dest fd */ if (ioc->fd_to == NULL) { break; } if (ioc->fd_to->fd == to) { - // remove the first fd node + /* remove the first fd node */ tmp = ioc->fd_to; ioc->fd_to = ioc->fd_to->next; break; @@ -225,6 +238,7 @@ static void remove_io_dispatch(io_thread_t *io_thd, int from, int to) } while (0); if (tmp != NULL) { free(tmp); + tmp = NULL; } pthread_mutex_unlock(&(ioc->mutex)); } @@ -238,7 +252,7 @@ static void *task_io_copy(void *data) io_copy_t *ioc = io_thd->ioc; char *buf = calloc(1, DEFAULT_IO_COPY_BUF + 1); if (buf == NULL) { - _exit(EXIT_FAILURE); + return NULL; } for (;;) { @@ -250,13 +264,12 @@ static void *task_io_copy(void *data) int r_count = read(ioc->fd_from, buf, DEFAULT_IO_COPY_BUF); if (r_count == -1) { - // If errno == EAGAIN, that means we have read all data if (errno == EAGAIN || errno == EINTR) { continue; } break; } else if (r_count == 0) { - // End of file. The remote has closed the connection. + /* End of file. The remote has closed the connection */ break; } else { fd_node_t *fn = ioc->fd_to; @@ -265,10 +278,9 @@ static void *task_io_copy(void *data) 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); + int w_count = write_nointr(fn->fd, buf, r_count); if (w_count < 0) { - // remove the write fd + /* When any error occurs, remove the write fd */ remove_io_dispatch(io_thd, -1, fn->fd); } } @@ -366,6 +378,7 @@ static int start_io_copy_threads(process_t *p) int ret = SHIM_ERR; int i; + /* 3 threads for stdin, stdout and stderr */ for (i = 0; i < 3; i++) { ret = process_io_start(p, i); if (ret != SHIM_OK) { @@ -423,7 +436,7 @@ static int connect_to_isulad(process_t *p, int std_id, const char *isulad_stdio, return add_io_dispatch(p->io_loop_fd, p->io_threads[std_id], *fd_from, *fd_to); } - // if no I/O source is available, the I/O thread nead to be destroyed + /* if no I/O source is available, the I/O thread nead to be destroyed */ destroy_io_thread(p, std_id); return SHIM_OK; @@ -448,36 +461,43 @@ static void *task_console_accept(void *data) goto out; } - // do console io copy - // - // p.state.stdin---->runtime.console + /* do console io copy */ + + /* p.state.stdin---->runtime.console */ ret = connect_to_isulad(ac->p, stdid_in, ac->p->state->isulad_stdin, recv_fd); if (ret != SHIM_OK) { goto out; } - // p.state.stdout<------runtime.console + /* p.state.stdout<------runtime.console */ ret = connect_to_isulad(ac->p, stdid_out, ac->p->state->isulad_stdout, recv_fd); if (ret != SHIM_OK) { goto out; } - // if the terminal is used, we do not need to active the io copy of stderr pipe + /* + * if the terminal is used, we do not need to active the io copy of stderr pipe, + * for stderr and stdout are mixed together + */ destroy_io_thread(ac->p, stdid_err); out: - // release listen socket + /* release listen socket at the first time */ close_fd(&ac->listen_fd); if (ac->p->console_sock_path != NULL) { - unlink(ac->p->console_sock_path); + (void)unlink(ac->p->console_sock_path); free(ac->p->console_sock_path); ac->p->console_sock_path = NULL; } free(ac); if (ret != SHIM_OK) { + /* + * When an error occurs during the receiving of the fd , the process + * exits directly. The files created in the working directory will be + * deleted by its parent process isulad + */ exit(EXIT_FAILURE); } - return NULL; } @@ -495,8 +515,7 @@ static void *task_io_loop(void *data) } (void)sem_post(&p->sem_mainloop); - // begin wait - while (1) { + for (;;) { wait_fds = epoll_wait(p->io_loop_fd, evs, MAX_EVENTS, -1); if (wait_fds < 0) { if (errno == EINTR) { @@ -526,7 +545,12 @@ static int new_temp_console_path(process_t *p) if (p->console_sock_path == NULL) { return SHIM_ERR; } - snprintf(p->console_sock_path, MAX_CONSOLE_SOCK_LEN, "/run/isulad%s-pty.sock", str_rand); + int nret = snprintf(p->console_sock_path, MAX_CONSOLE_SOCK_LEN, "/run/isulad%s-pty.sock", str_rand); + if (nret < 0 || nret >= MAX_CONSOLE_SOCK_LEN) { + free(p->console_sock_path); + p->console_sock_path = NULL; + return SHIM_ERR; + } return SHIM_OK; } @@ -548,14 +572,12 @@ static int console_init(process_t *p) addr.sun_family = AF_UNIX; (void)strcpy(addr.sun_path, p->console_sock_path); - // bind ret = bind(fd, (struct sockaddr *)&addr, sizeof(addr)); if (ret < 0) { write_message(g_log_fd, ERR_MSG, "bind console fd failed:%d", SHIM_SYS_ERR(errno)); goto failure; } - // listen ret = listen(fd, 2); if (ret < 0) { write_message(g_log_fd, ERR_MSG, "listen console fd failed:%d", SHIM_SYS_ERR(errno)); @@ -584,17 +606,44 @@ failure: close_fd(&fd); if (ac != NULL) { free(ac); + ac = NULL; } - unlink(p->console_sock_path); + (void)unlink(p->console_sock_path); return SHIM_ERR; } +static int stdio_chown(int (*stdio_fd)[2], int uid, int gid) +{ + int i, j; + + for (i = 0; i < 3; i++) { + for (j = 0; j < 2; j++) { + int ret = fchown(stdio_fd[i][j], uid, gid); + if (ret != SHIM_OK) { + return SHIM_ERR; + } + } + } + return SHIM_OK; +} + +static void stdio_release(int (*stdio_fd)[2]) +{ + int i, j; + + for (i = 0; i < 3; i++) { + for (j = 0; j < 2; j++) { + if (stdio_fd[i][j] > 0) { + close(stdio_fd[i][j]); + } + } + } +} + static stdio_t *initialize_io(process_t *p) { - int ret = SHIM_ERR; int stdio_fd[3][2] = { { -1, -1 }, { -1, -1 }, { -1, -1 } }; - int i, j; stdio_t *stdio = (stdio_t *)calloc(1, sizeof(stdio_t)); p->stdio = (stdio_t *)calloc(1, sizeof(stdio_t)); @@ -615,13 +664,8 @@ static stdio_t *initialize_io(process_t *p) p->stdio->err = stdio_fd[2][1]; // w stdio->err = stdio_fd[2][0]; // r - for (i = 0; i < 3; i++) { - for (j = 0; j < 2; j++) { - ret = fchown(stdio_fd[i][j], p->state->root_uid, p->state->root_gid); - if (ret != SHIM_OK) { - goto failure; - } - } + if (stdio_chown(stdio_fd, p->state->root_uid, p->state->root_gid) != SHIM_OK) { + goto failure; } return stdio; @@ -635,13 +679,7 @@ failure: free(p->stdio); p->stdio = NULL; } - for (i = 0; i < 3; i++) { - for (j = 0; j < 2; j++) { - if (stdio_fd[i][j] > 0) { - close(stdio_fd[i][j]); - } - } - } + stdio_release(stdio_fd); return NULL; } @@ -656,7 +694,7 @@ static int open_terminal_io(process_t *p) return SHIM_ERR; } - // begin listen and accept fd from p->console_sock_path + /* begin listen and accept fd from p->console_sock_path */ return console_init(p); } @@ -669,17 +707,17 @@ static int open_generic_io(process_t *p) return SHIM_ERR; } p->shim_io = io; - // stdin + /* stdin */ ret = connect_to_isulad(p, stdid_in, p->state->isulad_stdin, io->in); if (ret != SHIM_OK) { return SHIM_ERR; } - // stdout + /* stdout */ ret = connect_to_isulad(p, stdid_out, p->state->isulad_stdout, io->out); if (ret != SHIM_OK) { return SHIM_ERR; } - // stderr + /* stderr */ ret = connect_to_isulad(p, stdid_err, p->state->isulad_stderr, io->err); if (ret != SHIM_OK) { return SHIM_ERR; @@ -690,7 +728,7 @@ static int open_generic_io(process_t *p) static void adapt_for_isulad_stdin(process_t *p) { - // iSulad: close stdin pipe if we do not want open_stdin with container stdin just like lxc + /* iSulad: close stdin pipe if we do not want open_stdin with container stdin just like lxc */ if (!p->state->open_stdin && !file_exists(p->state->isulad_stdin)) { if (p->shim_io != NULL && p->shim_io->in != -1) { close(p->shim_io->in); @@ -931,7 +969,11 @@ static void process_delete(process_t *p) write_message(g_log_fd, ERR_MSG, "get cwd failed when do process delete"); return; } - snprintf(log_path, PATH_MAX, "%s/log.json", cwd); + int nret = snprintf(log_path, PATH_MAX, "%s/log.json", cwd); + if (nret < 0 || nret >= PATH_MAX) { + free(cwd); + return; + } params[i++] = p->runtime; for (j = 0; j < p->state->runtime_args_len; j++) { @@ -952,9 +994,66 @@ static void process_delete(process_t *p) return; } +static void exec_runtime_process(process_t *p, int exec_fd) +{ + if (p->shim_io != NULL) { + if (p->shim_io->in != -1) { + close(p->shim_io->in); + p->shim_io->in = -1; + dup2(p->stdio->in, 0); + } + if (p->shim_io->out != -1) { + close(p->shim_io->out); + p->shim_io->out = -1; + dup2(p->stdio->out, 1); + } + if (p->shim_io->err != -1) { + close(p->shim_io->err); + p->shim_io->err = -1; + dup2(p->stdio->err, 2); + } + } + + char *cwd = getcwd(NULL, 0); + char *log_path = (char *)calloc(1, PATH_MAX); + char *pid_path = (char *)calloc(1, PATH_MAX); + if (cwd == NULL || log_path == NULL || pid_path == NULL) { + (void)dprintf(exec_fd, "memory error: %s", strerror(errno)); + _exit(EXIT_FAILURE); + } + + int nret = snprintf(log_path, PATH_MAX, "%s/log.json", cwd); + if (nret < 0 || nret >= PATH_MAX) { + _exit(EXIT_FAILURE); + } + nret = snprintf(pid_path, PATH_MAX, "%s/pid", cwd); + if (nret < 0 || nret >= PATH_MAX) { + _exit(EXIT_FAILURE); + } + + char *process_desc = NULL; + if (p->state->exec) { + process_desc = (char *)calloc(1, PATH_MAX); + if (process_desc == NULL) { + (void)dprintf(exec_fd, "memory error: %s", strerror(errno)); + _exit(EXIT_FAILURE); + } + nret = snprintf(process_desc, PATH_MAX, "%s/process.json", cwd); + if (nret < 0 || nret >= PATH_MAX) { + _exit(EXIT_FAILURE); + } + } + + const char *params[MAX_RUNTIME_ARGS] = { 0 }; + get_runtime_cmd(p, log_path, pid_path, process_desc, params); + execvp(p->runtime, (char * const *)params); + (void)dprintf(exec_fd, "fork/exec error: %s", strerror(errno)); + _exit(EXIT_FAILURE); +} + int create_process(process_t *p) { - int ret = -1; + int ret = SHIM_ERR; char *data = NULL; int exec_fd[2] = { -1, -1 }; char exec_buff[BUFSIZ + 1] = { 0 }; @@ -971,56 +1070,13 @@ int create_process(process_t *p) return SHIM_ERR; } - // child:runtime + /* child:runtime process */ if (pid == (pid_t)0) { close_fd(&exec_fd[0]); - if (p->shim_io != NULL) { - if (p->shim_io->in != -1) { - close(p->shim_io->in); - p->shim_io->in = -1; - dup2(p->stdio->in, 0); - } - if (p->shim_io->out != -1) { - close(p->shim_io->out); - p->shim_io->out = -1; - dup2(p->stdio->out, 1); - } - if (p->shim_io->err != -1) { - close(p->shim_io->err); - p->shim_io->err = -1; - dup2(p->stdio->err, 2); - } - } - - char *cwd = getcwd(NULL, 0); - char *log_path = (char *)calloc(1, PATH_MAX); - char *pid_path = (char *)calloc(1, PATH_MAX); - if (cwd == NULL || log_path == NULL || pid_path == NULL) { - (void)dprintf(exec_fd[1], "memory error: %s", strerror(errno)); - _exit(EXIT_FAILURE); - } - - snprintf(log_path, PATH_MAX, "%s/log.json", cwd); - snprintf(pid_path, PATH_MAX, "%s/pid", cwd); - - char *process_desc = NULL; - if (p->state->exec) { - process_desc = (char *)calloc(1, PATH_MAX); - if (process_desc == NULL) { - (void)dprintf(exec_fd[1], "memory error: %s", strerror(errno)); - _exit(EXIT_FAILURE); - } - snprintf(process_desc, PATH_MAX, "%s/process.json", cwd); - } - - const char *params[MAX_RUNTIME_ARGS] = { 0 }; - get_runtime_cmd(p, log_path, pid_path, process_desc, params); - execvp(p->runtime, (char * const *)params); - (void)dprintf(exec_fd[1], "fork/exec error: %s", strerror(errno)); - _exit(EXIT_FAILURE); + exec_runtime_process(p, exec_fd[1]); } - // parent + /* parent:isulad-shim process */ close_fd(&exec_fd[1]); if (p->stdio != NULL) { close_fd(&p->stdio->in); @@ -1034,7 +1090,7 @@ int create_process(process_t *p) goto out; } - // block to wait pid exit + /* block to wait runtime pid exit */ ret = waitpid(pid, NULL, 0); if (ret != pid) { write_message(g_log_fd, ERR_MSG, "wait runtime failed:%d", SHIM_SYS_ERR(errno)); @@ -1042,7 +1098,7 @@ int create_process(process_t *p) goto out; } - // save pid + /* save runtime pid */ data = read_text_file("pid"); if (data == NULL) { write_message(g_log_fd, ERR_MSG, "read pid of runtime failed"); @@ -1061,6 +1117,7 @@ out: close_fd(&exec_fd[0]); if (data != NULL) { free(data); + data = NULL; } return ret; @@ -1089,7 +1146,7 @@ int process_signal_handle_routine(process_t *p) } } } else if (ret == SHIM_ERR_WAIT) { - // avoid thread entering the infinite loop + /* avoid thread entering the infinite loop */ usleep(1000); continue; } diff --git a/src/cmd/isulad-shim/terminal.c b/src/cmd/isulad-shim/terminal.c index 0be4b4d..657c187 100644 --- a/src/cmd/isulad-shim/terminal.c +++ b/src/cmd/isulad-shim/terminal.c @@ -170,7 +170,7 @@ static int shim_json_data_write(log_terminal *terminal, const char *buf, int rea return (read_count - ret); } -static bool get_time_buffer(struct timespec *timestamp, char *timebuffer, size_t maxsize) +static bool util_get_time_buffer(struct timespec *timestamp, char *timebuffer, size_t maxsize) { struct tm tm_utc = { 0 }; int32_t nanos = 0; @@ -196,7 +196,7 @@ static bool get_time_buffer(struct timespec *timestamp, char *timebuffer, size_t return true; } -static bool get_now_time_buffer(char *timebuffer, size_t maxsize) +static bool util_get_now_time_buffer(char *timebuffer, size_t maxsize) { int err = 0; struct timespec ts; @@ -206,7 +206,7 @@ static bool get_now_time_buffer(char *timebuffer, size_t maxsize) return false; } - return get_time_buffer(&ts, timebuffer, maxsize); + return util_get_time_buffer(&ts, timebuffer, maxsize); } static ssize_t shim_logger_write(log_terminal *terminal, const char *type, const char *buf, int read_count) @@ -236,7 +236,7 @@ static ssize_t shim_logger_write(log_terminal *terminal, const char *type, const msg->log_len = read_count; msg->stream = type ? safe_strdup(type) : safe_strdup("stdout"); - get_now_time_buffer(timebuffer, sizeof(timebuffer)); + util_get_now_time_buffer(timebuffer, sizeof(timebuffer)); msg->time = safe_strdup(timebuffer); json = logger_json_file_generate_json(msg, &ctx, &err); if (!json) { diff --git a/src/cmd/isulad/isulad_commands.c b/src/cmd/isulad/isulad_commands.c index 4b1ace0..2826aae 100644 --- a/src/cmd/isulad/isulad_commands.c +++ b/src/cmd/isulad/isulad_commands.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include "isulad_commands.h" @@ -30,9 +29,9 @@ #include "constants.h" #include "isula_libutils/isulad_daemon_configs.h" #include "utils_array.h" -#include "utils_convert.h" #include "utils_string.h" #include "utils_verify.h" +#include "opt_ulimit.h" const char isulad_desc[] = "GLOBAL OPTIONS:"; const char isulad_usage[] = "[global options]"; @@ -42,171 +41,6 @@ void print_version() printf("Version %s, commit %s\n", VERSION, ISULAD_GIT_COMMIT); } -static int check_default_ulimit_input(const char *val) -{ - int ret = 0; - if (val == NULL || strcmp(val, "") == 0) { - COMMAND_ERROR("ulimit argument can't be empty"); - ret = -1; - goto out; - } - - if (val[0] == '=' || val[strlen(val) - 1] == '=') { - COMMAND_ERROR("Invalid ulimit argument: \"%s\", delimiter '=' can't" - " be the first or the last character", - val); - ret = -1; - } - -out: - return ret; -} - -static void get_default_ulimit_split_parts(const char *val, char ***parts, size_t *parts_len, char deli) -{ - *parts = util_string_split_multi(val, deli); - if (*parts == NULL) { - ERROR("Out of memory"); - return; - } - *parts_len = util_array_len((const char **)(*parts)); -} - -static int parse_soft_hard_default_ulimit(const char *val, char **limitvals, size_t limitvals_len, int64_t *soft, - int64_t *hard) -{ - int ret = 0; - // parse soft - ret = util_safe_llong(limitvals[0], (long long *)soft); - if (ret < 0) { - COMMAND_ERROR("Invalid ulimit soft value: \"%s\", parse int64 failed: %s", val, strerror(-ret)); - ret = -1; - goto out; - } - - // parse hard if exists - if (limitvals_len > 1) { - ret = util_safe_llong(limitvals[1], (long long *)hard); - if (ret < 0) { - COMMAND_ERROR("Invalid ulimit hard value: \"%s\", parse int64 failed: %s", val, strerror(-ret)); - ret = -1; - goto out; - } - - if (*soft > *hard) { - COMMAND_ERROR("Ulimit soft limit must be less than or equal to hard limit: %lld > %lld", - (long long int)(*soft), (long long int)(*hard)); - ret = -1; - goto out; - } - } else { - *hard = *soft; // default to soft in case no hard was set - } -out: - return ret; -} - -int check_default_ulimit_type(const char *type) -{ - int ret = 0; - char **tmptype = NULL; - char *ulimit_valid_type[] = { - // "as", // Disabled since this doesn't seem usable with the way Docker inits a container. - "core", "cpu", "data", "fsize", "locks", "memlock", "msgqueue", "nice", - "nofile", "nproc", "rss", "rtprio", "rttime", "sigpending", "stack", NULL - }; - - for (tmptype = ulimit_valid_type; *tmptype != NULL; tmptype++) { - if (strcmp(type, *tmptype) == 0) { - break; - } - } - - if (*tmptype == NULL) { - COMMAND_ERROR("Invalid ulimit type: %s", type); - ret = -1; - } - return ret; -} - -static host_config_ulimits_element *parse_default_ulimit(const char *val) -{ - int ret = 0; - int64_t soft = 0; - int64_t hard = 0; - size_t parts_len = 0; - size_t limitvals_len = 0; - char **parts = NULL; - char **limitvals = NULL; - host_config_ulimits_element *ulimit = NULL; - - ret = check_default_ulimit_input(val); - if (ret != 0) { - return NULL; - } - - get_default_ulimit_split_parts(val, &parts, &parts_len, '='); - if (parts == NULL) { - ERROR("Out of memory"); - return NULL; - } else if (parts_len != 2) { - COMMAND_ERROR("Invalid ulimit argument: %s", val); - ret = -1; - goto out; - } - - ret = check_default_ulimit_type(parts[0]); - if (ret != 0) { - ret = -1; - goto out; - } - - if (parts[1][0] == ':' || parts[1][strlen(parts[1]) - 1] == ':') { - COMMAND_ERROR("Invalid ulimit value: \"%s\", delimiter ':' can't be the first" - " or the last character", - val); - ret = -1; - goto out; - } - - // parse value - get_default_ulimit_split_parts(parts[1], &limitvals, &limitvals_len, ':'); - if (limitvals == NULL) { - ret = -1; - goto out; - } - - if (limitvals_len > 2) { - COMMAND_ERROR("Too many limit value arguments - %s, can only have up to two, `soft[:hard]`", parts[1]); - ret = -1; - goto out; - } - - ret = parse_soft_hard_default_ulimit(val, limitvals, limitvals_len, &soft, &hard); - if (ret < 0) { - goto out; - } - - ulimit = util_common_calloc_s(sizeof(host_config_ulimits_element)); - if (ulimit == NULL) { - ret = -1; - goto out; - } - ulimit->name = util_strdup_s(parts[0]); - ulimit->hard = hard; - ulimit->soft = soft; - -out: - util_free_array(parts); - util_free_array(limitvals); - if (ret != 0) { - free_host_config_ulimits_element(ulimit); - ulimit = NULL; - } - - return ulimit; -} - int command_default_ulimit_append(command_option_t *option, const char *arg) { int ret = 0; @@ -219,7 +53,7 @@ int command_default_ulimit_append(command_option_t *option, const char *arg) goto out; } - tmp = parse_default_ulimit(arg); + tmp = parse_opt_ulimit(arg); if (tmp == NULL) { ERROR("parse default ulimit from arg failed"); ret = -1; @@ -368,7 +202,7 @@ static int check_args_graph_path(struct service_arguments *args) ret = -1; goto out; } - if (cleanpath(args->json_confs->graph, dstpath, sizeof(dstpath)) == NULL) { + if (util_clean_path(args->json_confs->graph, dstpath, sizeof(dstpath)) == NULL) { ERROR("failed to get clean path"); ret = -1; goto out; @@ -391,7 +225,7 @@ static int check_args_state_path(struct service_arguments *args) ret = -1; goto out; } - if (cleanpath(args->json_confs->state, dstpath, sizeof(dstpath)) == NULL) { + if (util_clean_path(args->json_confs->state, dstpath, sizeof(dstpath)) == NULL) { ERROR("failed to get clean path"); ret = -1; goto out; @@ -722,7 +556,7 @@ static int check_conf_default_ulimit(const struct service_arguments *args) goto out; } - ret = check_default_ulimit_type(type); + ret = check_opt_ulimit_type(type); if (ret != 0) { goto out; } diff --git a/src/cmd/isulad/isulad_commands.h b/src/cmd/isulad/isulad_commands.h index 68dca4e..78ec584 100644 --- a/src/cmd/isulad/isulad_commands.h +++ b/src/cmd/isulad/isulad_commands.h @@ -29,7 +29,7 @@ void print_common_help(); void print_version(); // Default help command if implementation doesn't prvide one -int commmand_default_help(const char * const program_name, int argc, char **argv); +int command_default_help(const char * const program_name, int argc, char **argv); int command_isulad_valid_socket(command_option_t *option, const char *arg); int parse_args(struct service_arguments *args, int argc, const char **argv); int check_args(struct service_arguments *args); @@ -105,7 +105,7 @@ int command_default_ulimit_append(command_option_t *option, const char *arg); "group", \ 'G', \ &(cmdargs)->json_confs->group, \ - "Group for the unix socket(default is isulad)", \ + "Group for the unix socket(default is isula)", \ NULL }, \ { CMD_OPT_TYPE_STRING_DUP, \ false, \ diff --git a/src/cmd/isulad/main.c b/src/cmd/isulad/main.c index b019ac0..7a932b6 100644 --- a/src/cmd/isulad/main.c +++ b/src/cmd/isulad/main.c @@ -58,7 +58,9 @@ #include "log_gather_api.h" #include "container_api.h" #include "plugin_api.h" +#ifdef ENABLE_SELINUX #include "selinux_label.h" +#endif #include "http.h" #include "runtime_api.h" #include "daemon_arguments.h" @@ -747,6 +749,7 @@ out: return ret; } +#ifdef ENABLE_SELINUX static int overlay_supports_selinux(bool *supported) { #define KALLSYMS_ITEM_MAX_LEN 100 @@ -820,6 +823,7 @@ static int configure_kernel_security_support(const struct service_arguments *arg } return 0; } +#endif static int update_server_args(struct service_arguments *args) { @@ -868,12 +872,14 @@ static int update_server_args(struct service_arguments *args) goto out; } +#ifdef ENABLE_SELINUX // Configure and validate the kernels security support. Note this is a Linux/FreeBSD // operation only, so it is safe to pass *just* the runtime OS graphdriver. if (configure_kernel_security_support(args)) { ret = -1; goto out; } +#endif out: return ret; @@ -949,7 +955,7 @@ static int init_log_gather_thread(const char *log_full_path, struct isula_libuti return -1; } while (1) { - usleep_nointerupt(1000); + util_usleep_nointerupt(1000); if (log_gather_exitcode >= 0) { break; } @@ -1398,11 +1404,6 @@ int main(int argc, char **argv) goto failure; } - if (init_cgroups_path("/lxc", 0)) { - msg = g_isulad_errmsg ? g_isulad_errmsg : "Failed to init cgroups path"; - goto failure; - } - if (add_sighandler()) { msg = "Failed to add sig handlers"; goto failure; diff --git a/src/cmd/options/CMakeLists.txt b/src/cmd/options/CMakeLists.txt new file mode 100644 index 0000000..358634b --- /dev/null +++ b/src/cmd/options/CMakeLists.txt @@ -0,0 +1,5 @@ +# get current directory sources files +aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} top_srcs) + +set(OPT_SRCS ${top_srcs} PARENT_SCOPE) +set(OPT_INCS ${CMAKE_CURRENT_SOURCE_DIR} PARENT_SCOPE) diff --git a/src/cmd/options/opt_ulimit.c b/src/cmd/options/opt_ulimit.c new file mode 100644 index 0000000..1a9c616 --- /dev/null +++ b/src/cmd/options/opt_ulimit.c @@ -0,0 +1,190 @@ +/****************************************************************************** + * Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved. + * iSulad licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * 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 v2 for more details. + * Author: lifeng + * Create: 2020-09-28 + * Description: provide ulimit options parse function + ******************************************************************************/ +#include "opt_ulimit.h" + +#include +#include +#include +#include + +#include "isula_libutils/log.h" +#include "utils.h" +#include "utils_array.h" +#include "utils_convert.h" +#include "utils_string.h" + +static int check_ulimit_input(const char *val) +{ + int ret = 0; + if (val == NULL || strcmp(val, "") == 0) { + COMMAND_ERROR("ulimit argument can't be empty"); + ret = -1; + goto out; + } + + if (val[0] == '=' || val[strlen(val) - 1] == '=') { + COMMAND_ERROR("Invalid ulimit argument: \"%s\", delimiter '=' can't" + " be the first or the last character", + val); + ret = -1; + } + +out: + return ret; +} + +static void get_ulimit_split_parts(const char *val, char ***parts, size_t *parts_len, char deli) +{ + *parts = util_string_split_multi(val, deli); + if (*parts == NULL) { + COMMAND_ERROR("Out of memory"); + return; + } + *parts_len = util_array_len((const char **)(*parts)); +} + +static int parse_soft_hard_ulimit(const char *val, char **limitvals, size_t limitvals_len, int64_t *soft, int64_t *hard) +{ + int ret = 0; + // parse soft + ret = util_safe_llong(limitvals[0], (long long *)soft); + if (ret < 0) { + COMMAND_ERROR("Invalid ulimit soft value: \"%s\", parse int64 failed: %s", val, strerror(-ret)); + ret = -1; + goto out; + } + + // parse hard if exists + if (limitvals_len > 1) { + ret = util_safe_llong(limitvals[1], (long long *)hard); + if (ret < 0) { + COMMAND_ERROR("Invalid ulimit hard value: \"%s\", parse int64 failed: %s", val, strerror(-ret)); + ret = -1; + goto out; + } + + if (*soft > *hard) { + COMMAND_ERROR("Ulimit soft limit must be less than or equal to hard limit: %lld > %lld", + (long long int)(*soft), (long long int)(*hard)); + ret = -1; + goto out; + } + } else { + *hard = *soft; // default to soft in case no hard was set + } +out: + return ret; +} + +int check_opt_ulimit_type(const char *type) +{ + int ret = 0; + char **tmptype = NULL; + char *ulimit_valid_type[] = { + // "as", // Disabled since this doesn't seem usable with the way Docker inits a container. + "core", "cpu", "data", "fsize", "locks", "memlock", "msgqueue", "nice", + "nofile", "nproc", "rss", "rtprio", "rttime", "sigpending", "stack", NULL + }; + + for (tmptype = ulimit_valid_type; *tmptype != NULL; tmptype++) { + if (strcmp(type, *tmptype) == 0) { + break; + } + } + + if (*tmptype == NULL) { + COMMAND_ERROR("Invalid ulimit type: %s", type); + ret = -1; + } + return ret; +} + +host_config_ulimits_element *parse_opt_ulimit(const char *val) +{ + int ret = 0; + int64_t soft = 0; + int64_t hard = 0; + size_t parts_len = 0; + size_t limitvals_len = 0; + char **parts = NULL; + char **limitvals = NULL; + host_config_ulimits_element *ulimit = NULL; + + ret = check_ulimit_input(val); + if (ret != 0) { + return NULL; + } + + get_ulimit_split_parts(val, &parts, &parts_len, '='); + if (parts == NULL) { + ERROR("Out of memory"); + return NULL; + } else if (parts_len != 2) { + COMMAND_ERROR("Invalid ulimit argument: %s", val); + ret = -1; + goto out; + } + + ret = check_opt_ulimit_type(parts[0]); + if (ret != 0) { + ret = -1; + goto out; + } + + if (parts[1][0] == ':' || parts[1][strlen(parts[1]) - 1] == ':') { + COMMAND_ERROR("Invalid ulimit value: \"%s\", delimiter ':' can't be the first" + " or the last character", + val); + ret = -1; + goto out; + } + + // parse value + get_ulimit_split_parts(parts[1], &limitvals, &limitvals_len, ':'); + if (limitvals == NULL) { + ret = -1; + goto out; + } + + if (limitvals_len > 2) { + COMMAND_ERROR("Too many limit value arguments - %s, can only have up to two, `soft[:hard]`", parts[1]); + ret = -1; + goto out; + } + + ret = parse_soft_hard_ulimit(val, limitvals, limitvals_len, &soft, &hard); + if (ret < 0) { + goto out; + } + + ulimit = util_common_calloc_s(sizeof(host_config_ulimits_element)); + if (ulimit == NULL) { + ret = -1; + goto out; + } + ulimit->name = util_strdup_s(parts[0]); + ulimit->hard = hard; + ulimit->soft = soft; + +out: + util_free_array(parts); + util_free_array(limitvals); + if (ret != 0) { + free_host_config_ulimits_element(ulimit); + ulimit = NULL; + } + + return ulimit; +} \ No newline at end of file diff --git a/src/client/connect/pack_config.h b/src/cmd/options/opt_ulimit.h similarity index 65% rename from src/client/connect/pack_config.h rename to src/cmd/options/opt_ulimit.h index c1062fa..657955d 100644 --- a/src/client/connect/pack_config.h +++ b/src/cmd/options/opt_ulimit.h @@ -8,27 +8,28 @@ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR * PURPOSE. * See the Mulan PSL v2 for more details. - * Author: tanyifeng - * Create: 2018-11-08 - * Description: provide container package configure definition + * Author: lifeng + * Create: 2020-09-28 + * Description: provide ulimit options parse function ******************************************************************************/ -#ifndef CLIENT_CONNECT_PACK_CONFIG_H -#define CLIENT_CONNECT_PACK_CONFIG_H +#ifndef CMD_OPTIONS_ULIMIT_H +#define CMD_OPTIONS_ULIMIT_H -#include "libisula.h" +#include +#include +#include + +#include "isula_libutils/host_config.h" #ifdef __cplusplus extern "C" { #endif -int generate_hostconfig(const isula_host_config_t *srcconfig, char **hostconfigstr); - -int generate_container_config(const isula_container_config_t *custom_conf, - char **container_config_str); +int check_opt_ulimit_type(const char *type); +host_config_ulimits_element *parse_opt_ulimit(const char *val); #ifdef __cplusplus } #endif #endif - diff --git a/src/common/constants.h b/src/common/constants.h index 5aca48e..420ac92 100644 --- a/src/common/constants.h +++ b/src/common/constants.h @@ -113,9 +113,6 @@ extern "C" { #define AUTH_PLUGIN "authz-broker" -#define ISULAD_ISULA_ADAPTER "isula-adapter" -#define ISULAD_ISULA_ACCEL_ARGS "isulad.accel.args" -#define ISULAD_ISULA_ACCEL_ARGS_SEPERATOR ";" #define ISULAD_ENABLE_PLUGINS "ISULAD_ENABLE_PLUGINS" #define ISULAD_ENABLE_PLUGINS_SEPERATOR "," #define ISULAD_ENABLE_PLUGINS_SEPERATOR_CHAR ',' diff --git a/src/contrib/config/config.json b/src/contrib/config/config.json index e87420d..b14c4a9 100644 --- a/src/contrib/config/config.json +++ b/src/contrib/config/config.json @@ -49,7 +49,6 @@ "path": "rootfs", "readonly": false }, - "hostname": "ubuntu", "mounts": [ { "destination": "/proc", diff --git a/src/contrib/config/daemon.json b/src/contrib/config/daemon.json index 2eac55e..9ffb08e 100644 --- a/src/contrib/config/daemon.json +++ b/src/contrib/config/daemon.json @@ -1,5 +1,5 @@ { - "group": "isulad", + "group": "isula", "default-runtime": "lcr", "graph": "/var/lib/isulad", "state": "/var/run/isulad", diff --git a/src/contrib/config/systemcontainer_config.json b/src/contrib/config/systemcontainer_config.json index b9e6e8c..c7e2ebd 100644 --- a/src/contrib/config/systemcontainer_config.json +++ b/src/contrib/config/systemcontainer_config.json @@ -49,7 +49,6 @@ "path": "rootfs", "readonly": false }, - "hostname": "ubuntu", "mounts": [ { "destination": "/proc", diff --git a/src/daemon/common/CMakeLists.txt b/src/daemon/common/CMakeLists.txt index f84830a..bd1badc 100644 --- a/src/daemon/common/CMakeLists.txt +++ b/src/daemon/common/CMakeLists.txt @@ -1,13 +1,18 @@ # get current directory sources files -aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/ daemon_common_top_srcs) +aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} daemon_common_top_srcs) + +if (NOT ENABLE_SELINUX) + list(REMOVE_ITEM daemon_common_top_srcs "${CMAKE_CURRENT_SOURCE_DIR}/selinux_label.c") +endif() + set(local_daemon_common_srcs ${daemon_common_top_srcs}) -set(local_daemon_common_incs ${CMAKE_CURRENT_SOURCE_DIR}) set(DAEMON_COMMON_SRCS ${local_daemon_common_srcs} PARENT_SCOPE ) + set(DAEMON_COMMON_INCS - ${local_daemon_common_incs} + ${CMAKE_CURRENT_SOURCE_DIR} PARENT_SCOPE ) diff --git a/src/daemon/common/selinux_label.c b/src/daemon/common/selinux_label.c index b97e07f..33c06a8 100644 --- a/src/daemon/common/selinux_label.c +++ b/src/daemon/common/selinux_label.c @@ -219,7 +219,7 @@ static int read_con(const char *fpath, char **content) return -1; } - tmp = isula_utils_read_file(fpath); + tmp = util_read_content_from_file(fpath); if (tmp == NULL) { ERROR("Failed to read file: %s", fpath); ret = -1; diff --git a/src/daemon/common/sysinfo.c b/src/daemon/common/sysinfo.c index f147aee..e5de393 100644 --- a/src/daemon/common/sysinfo.c +++ b/src/daemon/common/sysinfo.c @@ -18,6 +18,7 @@ #include #include #include +#include #include "err_msg.h" #include "sysinfo.h" @@ -106,7 +107,7 @@ static int add_null_to_list(void ***list) } newsize = (index + 2) * sizeof(void **); oldsize = index * sizeof(void **); - ret = mem_realloc((void **)&newlist, newsize, (*list), oldsize); + ret = util_mem_realloc((void **)&newlist, newsize, (*list), oldsize); if (ret < 0) { ERROR("Out of memory"); return -1; @@ -798,7 +799,7 @@ static void check_cgroup_cpuset_info(struct layer **layers, bool quiet, cgroup_c goto error; } - cpusetinfo->cpus = isula_utils_read_file(cpuset_cpus_path); + cpusetinfo->cpus = util_read_content_from_file(cpuset_cpus_path); if (cpusetinfo->cpus == NULL) { ERROR("Failed to read the file: %s", cpuset_cpus_path); goto error; @@ -810,7 +811,7 @@ static void check_cgroup_cpuset_info(struct layer **layers, bool quiet, cgroup_c goto error; } - cpusetinfo->mems = isula_utils_read_file(cpuset_mems_path); + cpusetinfo->mems = util_read_content_from_file(cpuset_mems_path); if (cpusetinfo->mems == NULL) { ERROR("Failed to read the file: %s", cpuset_mems_path); goto error; @@ -1170,6 +1171,8 @@ sysinfo_t *get_sys_info(bool quiet) goto out; } + sysinfo->ncpus = get_nprocs(); + check_cgroup_mem(layers, quiet, &sysinfo->cgmeminfo); check_cgroup_cpu(layers, quiet, &sysinfo->cgcpuinfo); check_cgroup_hugetlb(layers, quiet, &sysinfo->hugetlbinfo); diff --git a/src/daemon/common/sysinfo.h b/src/daemon/common/sysinfo.h index 7089c4e..8468e00 100644 --- a/src/daemon/common/sysinfo.h +++ b/src/daemon/common/sysinfo.h @@ -71,6 +71,7 @@ typedef struct { } cgroup_files_info_t; typedef struct { + int ncpus; cgroup_mem_info_t cgmeminfo; cgroup_cpu_info_t cgcpuinfo; cgroup_hugetlb_info_t hugetlbinfo; @@ -143,4 +144,3 @@ void free_mounts_info(mountinfo_t **minfos); #endif #endif // DAEMON_COMMON_SYSINFO_H - diff --git a/src/daemon/config/daemon_arguments.c b/src/daemon/config/daemon_arguments.c index 63e525b..ef28764 100644 --- a/src/daemon/config/daemon_arguments.c +++ b/src/daemon/config/daemon_arguments.c @@ -109,7 +109,7 @@ int service_arguments_init(struct service_arguments *args) goto free_out; } args->json_confs->engine = util_strdup_s("lcr"); - args->json_confs->group = util_strdup_s("isulad"); + args->json_confs->group = util_strdup_s("isula"); args->json_confs->graph = util_strdup_s(ISULAD_ROOT_PATH); args->json_confs->state = util_strdup_s(ISULAD_STATE_PATH); args->json_confs->log_level = util_strdup_s("INFO"); @@ -279,7 +279,7 @@ int ulimit_array_append(host_config_ulimits_element ***ulimit_array, const host_ new_size = (len + 2) * sizeof(host_config_ulimits_element *); old_size = len * sizeof(host_config_ulimits_element *); - ret = mem_realloc((void **)(&new_ulimit_array), new_size, (void *)*ulimit_array, old_size); + ret = util_mem_realloc((void **)(&new_ulimit_array), new_size, (void *)*ulimit_array, old_size); if (ret != 0) { ERROR("Failed to realloc memory for append ulimit"); return -1; diff --git a/src/daemon/config/isulad_config.c b/src/daemon/config/isulad_config.c index dac0332..c79c6a1 100644 --- a/src/daemon/config/isulad_config.c +++ b/src/daemon/config/isulad_config.c @@ -223,6 +223,30 @@ free_out: return epath; } +int conf_get_cgroup_cpu_rt(int64_t *cpu_rt_period, int64_t *cpu_rt_runtime) +{ + struct service_arguments *conf = NULL; + + if (isulad_server_conf_rdlock() != 0) { + return -1; + } + + conf = conf_get_server_conf(); + if (conf == NULL) { + (void)isulad_server_conf_unlock(); + return -1; + } + + *cpu_rt_period = conf->json_confs->cpu_rt_period; + *cpu_rt_runtime = conf->json_confs->cpu_rt_runtime; + + if (isulad_server_conf_unlock() != 0) { + return -1; + } + + return 0; +} + /* conf get graph checked flag file path */ char *conf_get_graph_check_flag_file() { @@ -857,16 +881,16 @@ out: return check_flag; } -#define OCI_STR_ARRAY_DUP(src, dest, srclen, destlen, ret) \ - do { \ - if ((src) != NULL) { \ - (dest) = str_array_dup((const char **)(src), (srclen)); \ - if ((dest) == NULL) { \ - (ret) = -1; \ - goto out; \ - } \ - (destlen) = (srclen); \ - } \ +#define OCI_STR_ARRAY_DUP(src, dest, srclen, destlen, ret) \ + do { \ + if ((src) != NULL) { \ + (dest) = util_str_array_dup((const char **)(src), (srclen)); \ + if ((dest) == NULL) { \ + (ret) = -1; \ + goto out; \ + } \ + (destlen) = (srclen); \ + } \ } while (0) #define HOOKS_ELEM_DUP_DEF(item) \ @@ -1049,7 +1073,7 @@ char *conf_get_default_runtime() goto out; } - result = strings_to_lower(conf->json_confs->default_runtime); + result = util_strings_to_lower(conf->json_confs->default_runtime); out: (void)isulad_server_conf_unlock(); @@ -1149,7 +1173,7 @@ static int set_path_group(const char *rpath, const char *group) return -1; } } else { - if (strcmp(group, "docker") == 0 || strcmp(group, "isulad") == 0) { + if (strcmp(group, "docker") == 0 || strcmp(group, "isula") == 0) { DEBUG("Warning: could not change group %s to %s", rpath, group); } else { ERROR("Group %s not found", group); @@ -1202,172 +1226,6 @@ out: return ret; } -/* maybe create cpu realtime file */ -static int maybe_create_cpu_realtime_file(bool present, int64_t value, const char *file, const char *path) -{ - int ret; - int fd = 0; - ssize_t nwrite; - char fpath[PATH_MAX] = { 0 }; - char buf[ISULAD_NUMSTRLEN64] = { 0 }; - - if (!present || value == 0) { - return 0; - } - - ret = util_mkdir_p(path, CONFIG_DIRECTORY_MODE); - if (ret != 0) { - ERROR("Failed to mkdir: %s", path); - return -1; - } - - int nret = snprintf(fpath, sizeof(fpath), "%s/%s", path, file); - if (nret < 0 || nret >= sizeof(fpath)) { - ERROR("Failed to print string"); - return -1; - } - nret = snprintf(buf, sizeof(buf), "%lld", (long long int)value); - if (nret < 0 || (size_t)nret >= sizeof(buf)) { - ERROR("Failed to print string"); - return -1; - } - - fd = util_open(fpath, O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, 0700); - if (fd < 0) { - ERROR("Failed to open file: %s: %s", fpath, strerror(errno)); - isulad_set_error_message("Failed to open file: %s: %s", fpath, strerror(errno)); - return -1; - } - nwrite = util_write_nointr(fd, buf, strlen(buf)); - if (nwrite < 0) { - ERROR("Failed to write %s to %s: %s", buf, fpath, strerror(errno)); - isulad_set_error_message("Failed to write '%s' to '%s': %s", buf, fpath, strerror(errno)); - close(fd); - return -1; - } - close(fd); - - return 0; -} - -static int get_cgroup_cpu_rt(int64_t *cpu_rt_period, int64_t *cpu_rt_runtime) -{ - struct service_arguments *conf = NULL; - - if (isulad_server_conf_rdlock() != 0) { - return -1; - } - - conf = conf_get_server_conf(); - if (conf == NULL) { - (void)isulad_server_conf_unlock(); - return -1; - } - - *cpu_rt_period = conf->json_confs->cpu_rt_period; - *cpu_rt_runtime = conf->json_confs->cpu_rt_runtime; - - if (isulad_server_conf_unlock() != 0) { - return -1; - } - - return 0; -} - -static int recursively_create_cgroup(const char *path, int recursive_depth, int64_t cpu_rt_period, - int64_t cpu_rt_runtime) -{ - int ret = 0; - sysinfo_t *sysinfo = NULL; - char *dup = NULL; - char *dirpath = NULL; - char *mnt = NULL; - char *root = NULL; - char fpath[PATH_MAX] = { 0 }; - - dup = util_strdup_s(path); - dirpath = dirname(dup); - ret = init_cgroups_path(dirpath, (recursive_depth + 1)); - free(dup); - if (ret != 0) { - return ret; - } - - ret = find_cgroup_mountpoint_and_root("cpu", &mnt, &root); - if (ret != 0 || mnt == NULL || root == NULL) { - ERROR("Can not find cgroup mnt and root path for subsystem 'cpu'"); - isulad_set_error_message("Can not find cgroup mnt and root path for subsystem 'cpu'"); - ret = -1; - goto out; - } - - // When iSulad is run inside iSulad/docker, the root is based of the host cgroup. - // Replace root to "/" - if (strncmp(root, "/lxc/", strlen("/lxc/")) != 0) { - root[1] = '\0'; - } - - int nret = snprintf(fpath, sizeof(fpath), "%s/%s/%s", mnt, root, path); - if (nret < 0 || (size_t)nret >= sizeof(fpath)) { - ERROR("Failed to print string"); - ret = -1; - goto out; - } - - sysinfo = get_sys_info(true); - if (sysinfo == NULL) { - ERROR("Can not get system info"); - ret = -1; - goto out; - } - - ret = maybe_create_cpu_realtime_file(sysinfo->cgcpuinfo.cpu_rt_period, cpu_rt_period, "cpu.rt_period_us", fpath); - if (ret != 0) { - goto out; - } - ret = maybe_create_cpu_realtime_file(sysinfo->cgcpuinfo.cpu_rt_runtime, cpu_rt_runtime, "cpu.rt_runtime_us", fpath); - if (ret != 0) { - goto out; - } -out: - free(mnt); - free(root); - free_sysinfo(sysinfo); - return ret; -} - -/* init cgroups path */ -int init_cgroups_path(const char *path, int recursive_depth) -{ - int64_t cpu_rt_period = 0; - int64_t cpu_rt_runtime = 0; - - if ((recursive_depth + 1) > MAX_PATH_DEPTH) { - ERROR("Reach the max cgroup depth:%s", path); - return -1; - } - - if (path == NULL || strcmp(path, "/") == 0 || strcmp(path, ".") == 0) { - return 0; - } - - if (get_cgroup_cpu_rt(&cpu_rt_period, &cpu_rt_runtime)) { - return -1; - } - - if (cpu_rt_period == 0 && cpu_rt_runtime == 0) { - return 0; - } - - // Recursively create cgroup to ensure that the system and all parent cgroups have values set - // for the period and runtime as this limits what the children can be set to. - if (recursively_create_cgroup(path, recursive_depth, cpu_rt_period, cpu_rt_runtime)) { - return -1; - } - - return 0; -} - #define OVERRIDE_STRING_VALUE(dst, src) \ do { \ if ((src) != NULL && strlen((src)) != 0) { \ @@ -1658,7 +1516,9 @@ int merge_json_confs_into_global(struct service_arguments *args) goto out; } +#ifdef ENABLE_SELINUX args->json_confs->selinux_enabled = tmp_json_confs->selinux_enabled; +#endif out: free(err); diff --git a/src/daemon/config/isulad_config.h b/src/daemon/config/isulad_config.h index c4dd8c1..b5c64c5 100644 --- a/src/daemon/config/isulad_config.h +++ b/src/daemon/config/isulad_config.h @@ -49,6 +49,8 @@ char *conf_get_isulad_logdriver(); int conf_get_daemon_log_config(char **loglevel, char **logdriver, char **engine_log_path); char *conf_get_isulad_log_gather_fifo_path(); +int conf_get_cgroup_cpu_rt(int64_t *cpu_rt_period, int64_t *cpu_rt_runtime); + char *conf_get_isulad_log_file(); char *conf_get_engine_log_file(); char *conf_get_enable_plugins(); @@ -74,8 +76,6 @@ int conf_get_isulad_default_ulimit(host_config_ulimits_element ***ulimit); unsigned int conf_get_start_timeout(); -int init_cgroups_path(const char *path, int recursive_depth); - char **conf_get_insecure_registry_list(); char **conf_get_registry_list(); diff --git a/src/daemon/entry/connect/grpc/grpc_server_tls_auth.cc b/src/daemon/entry/connect/grpc/grpc_server_tls_auth.cc index 18f2719..1bb1b92 100644 --- a/src/daemon/entry/connect/grpc/grpc_server_tls_auth.cc +++ b/src/daemon/entry/connect/grpc/grpc_server_tls_auth.cc @@ -28,7 +28,7 @@ Status auth(ServerContext *context, std::string action) const std::multimap init_metadata = context->client_metadata(); auto tls_mode_kv = init_metadata.find("tls_mode"); if (tls_mode_kv == init_metadata.end()) { - return Status(StatusCode::UNKNOWN, "unkown error"); + return Status(StatusCode::UNKNOWN, "unknown error"); } std::string tls_mode = std::string(tls_mode_kv->second.data(), tls_mode_kv->second.length()); if (tls_mode == "0") { @@ -39,7 +39,7 @@ Status auth(ServerContext *context, std::string action) } else if (AuthorizationPluginConfig::auth_plugin == "authz-broker") { auto username_kv = init_metadata.find("username"); if (username_kv == init_metadata.end()) { - return Status(StatusCode::UNKNOWN, "unkown error"); + return Status(StatusCode::UNKNOWN, "unknown error"); } std::string username = std::string(username_kv->second.data(), username_kv->second.length()); char *errmsg = nullptr; diff --git a/src/daemon/entry/cri/cni_network_plugin.cc b/src/daemon/entry/cri/cni_network_plugin.cc index 3442560..c1a4e1e 100644 --- a/src/daemon/entry/cri/cni_network_plugin.cc +++ b/src/daemon/entry/cri/cni_network_plugin.cc @@ -42,7 +42,7 @@ static auto GetLoNetwork(std::vector binDirs) -> std::unique_ptr lo) } } -void CniNetworkPlugin::SetDefaultNetwork(std::unique_ptr network, - std::vector &binDirs, Errors &err) +void CniNetworkPlugin::SetDefaultNetwork(std::unique_ptr network, std::vector &binDirs, + Errors &err) { if (network == nullptr) { return; @@ -154,8 +154,8 @@ void CniNetworkPlugin::PlatformInit(Errors &error) free(tpath); } -auto CniNetworkPlugin::GetCNIConfFiles(const std::string &pluginDir, std::vector &vect_files, - Errors &err) -> int +auto CniNetworkPlugin::GetCNIConfFiles(const std::string &pluginDir, std::vector &vect_files, Errors &err) +-> int { int ret { 0 }; std::string usePluginDir { pluginDir }; @@ -280,7 +280,8 @@ void CniNetworkPlugin::GetDefaultCNINetwork(const std::string &confDir, std::vec continue; } - SetDefaultNetwork(std::unique_ptr(new (std::nothrow) CNINetwork(n_list->name, n_list)), binDirs, err); + SetDefaultNetwork(std::unique_ptr(new (std::nothrow) CNINetwork(n_list->name, n_list)), binDirs, + err); found = true; break; } @@ -349,9 +350,8 @@ void CniNetworkPlugin::Status(Errors &err) CheckInitialized(err); } -void CniNetworkPlugin::SetUpPod(const std::string &ns, const std::string &name, - const std::string &interfaceName, const std::string &id, - const std::map &annotations, +void CniNetworkPlugin::SetUpPod(const std::string &ns, const std::string &name, const std::string &interfaceName, + const std::string &id, const std::map &annotations, const std::map &options, Errors &err) { CheckInitialized(err); @@ -393,8 +393,8 @@ void CniNetworkPlugin::SetUpPod(const std::string &ns, const std::string &name, } void CniNetworkPlugin::TearDownPod(const std::string &ns, const std::string &name, const std::string &interfaceName, - const std::string &id, - const std::map &annotations, Errors &err) + const std::string &id, const std::map &annotations, + Errors &err) { CheckInitialized(err); if (err.NotEmpty()) { @@ -493,12 +493,12 @@ out: INFO("get_pod_network_status: %s", podSandboxID.c_str()); } -void CniNetworkPlugin::AddToNetwork(CNINetwork *snetwork, const std::string &podName, - const std::string &podNamespace, const std::string &interfaceName, - const std::string &podSandboxID, const std::string &podNetnsPath, +void CniNetworkPlugin::AddToNetwork(CNINetwork *snetwork, const std::string &podName, const std::string &podNamespace, + const std::string &interfaceName, const std::string &podSandboxID, + const std::string &podNetnsPath, const std::map &annotations, - const std::map &options, - struct result **presult, Errors &err) + const std::map &options, struct result **presult, + Errors &err) { struct runtime_conf *rc { nullptr @@ -510,7 +510,8 @@ void CniNetworkPlugin::AddToNetwork(CNINetwork *snetwork, const std::string &pod return; } - BuildCNIRuntimeConf(podName, podNamespace, interfaceName, podSandboxID, podNetnsPath, annotations, options, &rc, err); + BuildCNIRuntimeConf(podName, podNamespace, interfaceName, podSandboxID, podNetnsPath, annotations, options, &rc, + err); if (err.NotEmpty()) { ERROR("Error adding network when building cni runtime conf: %s", err.GetCMessage()); return; @@ -536,12 +537,10 @@ void CniNetworkPlugin::AddToNetwork(CNINetwork *snetwork, const std::string &pod free(serr); } -void CniNetworkPlugin::DeleteFromNetwork(CNINetwork *network, - const std::string &podName, const std::string &podNamespace, - const std::string &interfaceName, const std::string &podSandboxID, - const std::string &podNetnsPath, - const std::map &annotations, - Errors &err) +void CniNetworkPlugin::DeleteFromNetwork(CNINetwork *network, const std::string &podName, + const std::string &podNamespace, const std::string &interfaceName, + const std::string &podSandboxID, const std::string &podNetnsPath, + const std::map &annotations, Errors &err) { struct runtime_conf *rc { nullptr @@ -553,7 +552,8 @@ void CniNetworkPlugin::DeleteFromNetwork(CNINetwork *network, return; } std::map options; - BuildCNIRuntimeConf(podName, podNamespace, interfaceName, podSandboxID, podNetnsPath, annotations, options, &rc, err); + BuildCNIRuntimeConf(podName, podNamespace, interfaceName, podSandboxID, podNetnsPath, annotations, options, &rc, + err); if (err.NotEmpty()) { ERROR("Error deleting network when building cni runtime conf: %s", err.GetCMessage()); return; @@ -579,11 +579,10 @@ void CniNetworkPlugin::DeleteFromNetwork(CNINetwork *network, free(serr); } -static void PrepareRuntimeConf(const std::string &podName, - const std::string &podNs, const std::string &interfaceName, +static void PrepareRuntimeConf(const std::string &podName, const std::string &podNs, const std::string &interfaceName, const std::string &podSandboxID, const std::string &podNetnsPath, - const std::map &options, - struct runtime_conf **cni_rc, Errors &err) + const std::map &options, struct runtime_conf **cni_rc, + Errors &err) { const size_t defaultLen = 5; if (cni_rc == nullptr) { @@ -633,9 +632,9 @@ free_out: free_runtime_conf(rt); } -void CniNetworkPlugin::BuildCNIRuntimeConf(const std::string &podName, - const std::string &podNs, const std::string &interfaceName, - const std::string &podSandboxID, const std::string &podNetnsPath, +void CniNetworkPlugin::BuildCNIRuntimeConf(const std::string &podName, const std::string &podNs, + const std::string &interfaceName, const std::string &podSandboxID, + const std::string &podNetnsPath, const std::map &annotations, const std::map &options, struct runtime_conf **cni_rc, Errors &err) @@ -697,7 +696,7 @@ void CniNetworkPlugin::BuildCNIRuntimeConf(const std::string &podName, rt->p_mapping[rt->p_mapping_len]->container_port = *(portMapping.GetContainerPort()); } if (portMapping.GetProtocol() != nullptr) { - rt->p_mapping[rt->p_mapping_len]->protocol = strings_to_lower(portMapping.GetProtocol()->c_str()); + rt->p_mapping[rt->p_mapping_len]->protocol = util_strings_to_lower(portMapping.GetProtocol()->c_str()); } // ignore hostip, because GetPodPortMappings() don't set (rt->p_mapping_len)++; diff --git a/src/daemon/entry/cri/cri_container.cc b/src/daemon/entry/cri/cri_container.cc index f6a2558..c6d9599 100644 --- a/src/daemon/entry/cri/cri_container.cc +++ b/src/daemon/entry/cri/cri_container.cc @@ -37,8 +37,7 @@ #include "url.h" #include "ws_server.h" -auto CRIRuntimeServiceImpl::GetRealContainerOrSandboxID(const std::string &id, bool isSandbox, - Errors &error) -> std::string +std::string CRIRuntimeServiceImpl::GetRealContainerOrSandboxID(const std::string &id, bool isSandbox, Errors &error) { std::string realID; @@ -121,20 +120,20 @@ void CRIRuntimeServiceImpl::GetContainerTimeStamps(container_inspect *inspect, i return; } if (createdAt != nullptr) { - if (to_unix_nanos_from_str(inspect->created, createdAt) != 0) { + if (util_to_unix_nanos_from_str(inspect->created, createdAt) != 0) { err.Errorf("Parse createdAt failed: %s", inspect->created); return; } } if (inspect->state != nullptr) { if (startedAt != nullptr) { - if (to_unix_nanos_from_str(inspect->state->started_at, startedAt) != 0) { + if (util_to_unix_nanos_from_str(inspect->state->started_at, startedAt) != 0) { err.Errorf("Parse startedAt failed: %s", inspect->state->started_at); return; } } if (finishedAt != nullptr) { - if (to_unix_nanos_from_str(inspect->state->finished_at, finishedAt) != 0) { + if (util_to_unix_nanos_from_str(inspect->state->finished_at, finishedAt) != 0) { err.Errorf("Parse finishedAt failed: %s", inspect->state->finished_at); return; } @@ -169,14 +168,15 @@ auto CRIRuntimeServiceImpl::GenerateCreateContainerCustomConfig( if (!podSandboxConfig.log_directory().empty() || !containerConfig.log_path().empty()) { std::string logpath = podSandboxConfig.log_directory() + "/" + containerConfig.log_path(); char real_logpath[PATH_MAX] { 0 }; - if (cleanpath(logpath.c_str(), real_logpath, sizeof(real_logpath)) == nullptr) { + if (util_clean_path(logpath.c_str(), real_logpath, sizeof(real_logpath)) == nullptr) { ERROR("Failed to clean path: %s", logpath.c_str()); error.Errorf("Failed to clean path: %s", logpath.c_str()); goto cleanup; } if (append_json_map_string_string(custom_config->labels, - CRIHelpers::Constants::CONTAINER_LOGPATH_LABEL_KEY.c_str(), real_logpath) != 0) { + CRIHelpers::Constants::CONTAINER_LOGPATH_LABEL_KEY.c_str(), + real_logpath) != 0) { error.SetError("Append map string string failed"); goto cleanup; } @@ -269,7 +269,7 @@ auto CRIRuntimeServiceImpl::PackCreateContainerHostConfigSecurityContext( } size_t newSize = (hostconfig->security_opt_len + securityOpts.size()) * sizeof(char *); size_t oldSize = hostconfig->security_opt_len * sizeof(char *); - int ret = mem_realloc((void **)(&tmp_security_opt), newSize, (void *)hostconfig->security_opt, oldSize); + int ret = util_mem_realloc((void **)(&tmp_security_opt), newSize, (void *)hostconfig->security_opt, oldSize); if (ret != 0) { error.Errorf("Out of memory"); return -1; @@ -322,10 +322,11 @@ cleanup: return nullptr; } -auto CRIRuntimeServiceImpl::GenerateCreateContainerRequest(const std::string &realPodSandboxID, - const runtime::v1alpha2::ContainerConfig &containerConfig, - const runtime::v1alpha2::PodSandboxConfig &podSandboxConfig, - const std::string &podSandboxRuntime, Errors &error) -> container_create_request * +container_create_request * +CRIRuntimeServiceImpl::GenerateCreateContainerRequest(const std::string &realPodSandboxID, + const runtime::v1alpha2::ContainerConfig &containerConfig, + const runtime::v1alpha2::PodSandboxConfig &podSandboxConfig, + const std::string &podSandboxRuntime, Errors &error) { struct parser_context ctx { OPT_GEN_SIMPLIFY, 0 @@ -393,10 +394,10 @@ cleanup: return request; } -auto CRIRuntimeServiceImpl::CreateContainer(const std::string &podSandboxID, - const runtime::v1alpha2::ContainerConfig &containerConfig, - const runtime::v1alpha2::PodSandboxConfig &podSandboxConfig, - Errors &error) -> std::string +std::string CRIRuntimeServiceImpl::CreateContainer(const std::string &podSandboxID, + const runtime::v1alpha2::ContainerConfig &containerConfig, + const runtime::v1alpha2::PodSandboxConfig &podSandboxConfig, + Errors &error) { std::string response_id; std::string podSandboxRuntime; @@ -1186,8 +1187,8 @@ void CRIRuntimeServiceImpl::ContainerStatusToGRPC(container_inspect *inspect, ConvertMountsToStatus(inspect, contStatus); } -auto CRIRuntimeServiceImpl::ContainerStatus(const std::string &containerID, - Errors &error) -> std::unique_ptr +std::unique_ptr +CRIRuntimeServiceImpl::ContainerStatus(const std::string &containerID, Errors &error) { if (containerID.empty()) { error.SetError("Empty pod sandbox id"); diff --git a/src/daemon/entry/cri/cri_helpers.cc b/src/daemon/entry/cri/cri_helpers.cc index bfb1d4a..8aa939c 100644 --- a/src/daemon/entry/cri/cri_helpers.cc +++ b/src/daemon/entry/cri/cri_helpers.cc @@ -52,18 +52,18 @@ const std::string Constants::SANDBOX_ID_ANNOTATION_KEY { "io.kubernetes.cri.sand const std::string Constants::NET_PLUGIN_EVENT_POD_CIDR_CHANGE { "pod-cidr-change" }; const std::string Constants::NET_PLUGIN_EVENT_POD_CIDR_CHANGE_DETAIL_CIDR { "pod-cidr" }; -const char *InternalLabelKeys[] = { - CRIHelpers::Constants::CONTAINER_TYPE_LABEL_KEY.c_str(), - CRIHelpers::Constants::CONTAINER_LOGPATH_LABEL_KEY.c_str(), - CRIHelpers::Constants::SANDBOX_ID_LABEL_KEY.c_str(), nullptr -}; +const char *InternalLabelKeys[] = { CRIHelpers::Constants::CONTAINER_TYPE_LABEL_KEY.c_str(), + CRIHelpers::Constants::CONTAINER_LOGPATH_LABEL_KEY.c_str(), + CRIHelpers::Constants::SANDBOX_ID_LABEL_KEY.c_str(), nullptr + }; auto GetDefaultSandboxImage(Errors &err) -> std::string { const std::string defaultPodSandboxImageName { "pause" }; const std::string defaultPodSandboxImageVersion { "3.0" }; std::string machine; - struct utsname uts {}; + struct utsname uts { + }; if (uname(&uts) < 0) { err.SetError("Failed to read host arch."); @@ -85,8 +85,8 @@ auto GetDefaultSandboxImage(Errors &err) -> std::string return defaultPodSandboxImageName + "-" + machine + ":" + defaultPodSandboxImageVersion; } -auto MakeLabels(const google::protobuf::Map &mapLabels, - Errors &error) -> json_map_string_string * +auto MakeLabels(const google::protobuf::Map &mapLabels, Errors &error) +-> json_map_string_string * { json_map_string_string *labels = (json_map_string_string *)util_common_calloc_s(sizeof(json_map_string_string)); if (labels == nullptr) { @@ -112,8 +112,8 @@ cleanup: return nullptr; } -auto MakeAnnotations(const google::protobuf::Map &mapAnnotations, - Errors &error) -> json_map_string_string * +auto MakeAnnotations(const google::protobuf::Map &mapAnnotations, Errors &error) +-> json_map_string_string * { json_map_string_string *annotations = (json_map_string_string *)util_common_calloc_s(sizeof(json_map_string_string)); @@ -386,8 +386,8 @@ auto sha256(const char *val) -> std::string return outputBuffer; } -auto GetNetworkPlaneFromPodAnno(const google::protobuf::Map &annotations, - size_t *len, Errors &error) -> cri_pod_network_element ** +auto GetNetworkPlaneFromPodAnno(const google::protobuf::Map &annotations, size_t *len, + Errors &error) -> cri_pod_network_element ** { auto iter = annotations.find(CRIHelpers::Constants::POD_NETWORK_ANNOTATION_KEY); @@ -404,8 +404,8 @@ auto GetNetworkPlaneFromPodAnno(const google::protobuf::Map std::unique_ptr +auto CheckpointToSandbox(const std::string &id, const cri::PodSandboxCheckpoint &checkpoint) +-> std::unique_ptr { std::unique_ptr result(new (std::nothrow) runtime::v1alpha2::PodSandbox); if (result == nullptr) { @@ -507,8 +507,8 @@ void GenerateMountBindings(const google::protobuf::RepeatedPtrField &envs) -> std::vector +auto GenerateEnvList(const ::google::protobuf::RepeatedPtrField<::runtime::v1alpha2::KeyValue> &envs) +-> std::vector { std::vector vect; std::for_each(envs.begin(), envs.end(), [&vect](const ::runtime::v1alpha2::KeyValue & elem) { @@ -568,7 +568,8 @@ auto GetSeccompiSuladOpts(const std::string &seccompProfile, Errors &error) -> s if (seccompProfile.empty() || seccompProfile == "unconfined") { return std::vector { { "seccomp", "unconfined", "" } }; } - if (seccompProfile == "iSulad/default" || seccompProfile == "docker/default" || seccompProfile == "runtime/default") { + if (seccompProfile == "iSulad/default" || seccompProfile == "docker/default" || + seccompProfile == "runtime/default") { // return nil so docker will load the default seccomp profile return std::vector {}; } @@ -578,7 +579,7 @@ auto GetSeccompiSuladOpts(const std::string &seccompProfile, Errors &error) -> s } std::string fname = seccompProfile.substr(std::string("localhost/").length(), seccompProfile.length()); char dstpath[PATH_MAX] { 0 }; - if (cleanpath(fname.c_str(), dstpath, sizeof(dstpath)) == nullptr) { + if (util_clean_path(fname.c_str(), dstpath, sizeof(dstpath)) == nullptr) { error.Errorf("failed to get clean path"); return std::vector {}; } @@ -609,8 +610,8 @@ auto GetSeccompiSuladOpts(const std::string &seccompProfile, Errors &error) -> s return ret; } -auto GetSeccompSecurityOpts(const std::string &seccompProfile, const char &separator, - Errors &error) -> std::vector +auto GetSeccompSecurityOpts(const std::string &seccompProfile, const char &separator, Errors &error) +-> std::vector { std::vector seccompOpts = GetSeccompiSuladOpts(seccompProfile, error); if (error.NotEmpty()) { @@ -620,8 +621,8 @@ auto GetSeccompSecurityOpts(const std::string &seccompProfile, const char &separ return fmtiSuladOpts(seccompOpts, separator); } -auto GetSecurityOpts(const std::string &seccompProfile, const char &separator, - Errors &error) -> std::vector +auto GetSecurityOpts(const std::string &seccompProfile, const char &separator, Errors &error) +-> std::vector { std::vector seccompSecurityOpts = GetSeccompSecurityOpts(seccompProfile, separator, error); if (error.NotEmpty()) { diff --git a/src/daemon/entry/cri/cri_sandbox.cc b/src/daemon/entry/cri/cri_sandbox.cc index 540e8b3..6db9616 100644 --- a/src/daemon/entry/cri/cri_sandbox.cc +++ b/src/daemon/entry/cri/cri_sandbox.cc @@ -116,16 +116,14 @@ void CRIRuntimeServiceImpl::ConstructPodSandboxCheckpoint(const runtime::v1alpha } void CRIRuntimeServiceImpl::ApplySandboxResources(const runtime::v1alpha2::LinuxPodSandboxConfig * /*lc*/, - host_config *hc, - Errors & /*error*/) + host_config *hc, Errors & /*error*/) { hc->memory_swap = CRIRuntimeService::Constants::DefaultMemorySwap; hc->cpu_shares = CRIRuntimeService::Constants::DefaultSandboxCPUshares; } void CRIRuntimeServiceImpl::ApplySandboxLinuxOptions(const runtime::v1alpha2::LinuxPodSandboxConfig &lc, - host_config *hc, container_config *custom_config, - Errors &error) + host_config *hc, container_config *custom_config, Errors &error) { CRISecurity::ApplySandboxSecurityContext(lc, custom_config, hc, error); if (error.NotEmpty()) { @@ -184,7 +182,7 @@ void CRIRuntimeServiceImpl::MergeSecurityContextToHostConfig(const runtime::v1al } size_t newSize = (hc->security_opt_len + securityOpts.size()) * sizeof(char *); size_t oldSize = hc->security_opt_len * sizeof(char *); - int ret = mem_realloc((void **)(&tmp_security_opt), newSize, (void *)hc->security_opt, oldSize); + int ret = util_mem_realloc((void **)(&tmp_security_opt), newSize, (void *)hc->security_opt, oldSize); if (ret != 0) { error.Errorf("Out of memory"); return; @@ -258,7 +256,7 @@ void CRIRuntimeServiceImpl::MakeSandboxIsuladConfig(const runtime::v1alpha2::Pod } size_t newSize = (hc->security_opt_len + securityOpts.size()) * sizeof(char *); size_t oldSize = hc->security_opt_len * sizeof(char *); - int ret = mem_realloc((void **)(&tmp_security_opt), newSize, (void *)hc->security_opt, oldSize); + int ret = util_mem_realloc((void **)(&tmp_security_opt), newSize, (void *)hc->security_opt, oldSize); if (ret != 0) { error.Errorf("Out of memory"); return; @@ -292,9 +290,9 @@ void CRIRuntimeServiceImpl::SetupSandboxFiles(const std::string &resolvPath, resolvContentStrs.push_back("nameserver " + CXXUtils::StringsJoin(servers, "\nnameserver ")); } - std::vector searchs(config.dns_config().searches().begin(), config.dns_config().searches().end()); - if (!searchs.empty()) { - resolvContentStrs.push_back("search " + CXXUtils::StringsJoin(searchs, " ")); + std::vector searches(config.dns_config().searches().begin(), config.dns_config().searches().end()); + if (!searches.empty()) { + resolvContentStrs.push_back("search " + CXXUtils::StringsJoin(searches, " ")); } std::vector options(config.dns_config().options().begin(), config.dns_config().options().end()); @@ -304,17 +302,16 @@ void CRIRuntimeServiceImpl::SetupSandboxFiles(const std::string &resolvPath, if (!resolvContentStrs.empty()) { std::string resolvContent = CXXUtils::StringsJoin(resolvContentStrs, "\n") + "\n"; - if (util_write_file(resolvPath.c_str(), resolvContent.c_str(), resolvContent.size(), DEFAULT_SECURE_FILE_MODE) != 0) { + if (util_write_file(resolvPath.c_str(), resolvContent.c_str(), resolvContent.size(), + DEFAULT_SECURE_FILE_MODE) != 0) { error.SetError("Failed to write resolv content"); } } } -auto CRIRuntimeServiceImpl::PackCreateContainerRequest( - const runtime::v1alpha2::PodSandboxConfig &config, - const std::string &image, host_config *hostconfig, - container_config *custom_config, - const std::string &runtimeHandler, Errors &error) -> container_create_request * +container_create_request *CRIRuntimeServiceImpl::PackCreateContainerRequest( + const runtime::v1alpha2::PodSandboxConfig &config, const std::string &image, host_config *hostconfig, + container_config *custom_config, const std::string &runtimeHandler, Errors &error) { struct parser_context ctx = { OPT_GEN_SIMPLIFY, 0 }; parser_error perror = nullptr; @@ -353,11 +350,10 @@ error_out: return nullptr; } -auto CRIRuntimeServiceImpl::GenerateSandboxCreateContainerRequest( - const runtime::v1alpha2::PodSandboxConfig &config, - const std::string &image, std::string &jsonCheckpoint, - const std::string &runtimeHandler, - Errors &error) -> container_create_request * +container_create_request * +CRIRuntimeServiceImpl::GenerateSandboxCreateContainerRequest(const runtime::v1alpha2::PodSandboxConfig &config, + const std::string &image, std::string &jsonCheckpoint, + const std::string &runtimeHandler, Errors &error) { container_create_request *create_request = nullptr; host_config *hostconfig = nullptr; @@ -415,8 +411,7 @@ cleanup: auto CRIRuntimeServiceImpl::CreateSandboxContainer(const runtime::v1alpha2::PodSandboxConfig &config, const std::string &image, std::string &jsonCheckpoint, - const std::string &runtimeHandler, - Errors &error) -> std::string + const std::string &runtimeHandler, Errors &error) -> std::string { std::string response_id; container_create_request *create_request = @@ -483,8 +478,8 @@ void CRIRuntimeServiceImpl::SetupUserDefinedNetworkPlane(const runtime::v1alpha2 if ((networks[i] != nullptr) && (networks[i]->name != nullptr) && (networks[i]->interface != nullptr) && strcmp(networks[i]->name, Network::DEFAULT_NETWORK_PLANE_NAME.c_str()) != 0) { INFO("SetupPod net: %s", networks[i]->name); - m_pluginManager->SetUpPod(config.metadata().namespace_(), config.metadata().name(), networks[i]->interface, response_id, - stdAnnos, options, error); + m_pluginManager->SetUpPod(config.metadata().namespace_(), config.metadata().name(), networks[i]->interface, + response_id, stdAnnos, options, error); if (error.Empty()) { continue; } @@ -545,8 +540,7 @@ cleanup: } auto CRIRuntimeServiceImpl::RunPodSandbox(const runtime::v1alpha2::PodSandboxConfig &config, - const std::string &runtimeHandler, - Errors &error) -> std::string + const std::string &runtimeHandler, Errors &error) -> std::string { std::string response_id; std::string jsonCheckpoint; @@ -597,8 +591,7 @@ cleanup: } auto CRIRuntimeServiceImpl::GetRealSandboxIDToStop(const std::string &podSandboxID, bool &hostNetwork, - std::string &name, - std::string &ns, std::string &realSandboxID, + std::string &name, std::string &ns, std::string &realSandboxID, std::map &stdAnnos, Errors &error) -> int { Errors statusErr; @@ -733,14 +726,16 @@ cleanup: auto CRIRuntimeServiceImpl::ClearCniNetwork(const std::string &realSandboxID, bool hostNetwork, const std::string &ns, const std::string &name, std::vector &errlist, - std::map &stdAnnos, Errors & /*error*/) -> int + std::map &stdAnnos, Errors & + /*error*/) -> int { Errors networkErr; bool ready = GetNetworkReady(realSandboxID, networkErr); if (!hostNetwork && (ready || networkErr.NotEmpty())) { Errors pluginErr; - m_pluginManager->TearDownPod(ns, name, Network::DEFAULT_NETWORK_INTERFACE_NAME, realSandboxID, stdAnnos, pluginErr); + m_pluginManager->TearDownPod(ns, name, Network::DEFAULT_NETWORK_INTERFACE_NAME, realSandboxID, stdAnnos, + pluginErr); if (pluginErr.NotEmpty()) { WARN("TearDownPod cni network failed: %s", pluginErr.GetCMessage()); errlist.push_back(pluginErr.GetMessage()); @@ -828,8 +823,7 @@ cleanup: free_container_stop_response(response); } -auto CRIRuntimeServiceImpl::DoRemovePodSandbox(const std::string &realSandboxID, - std::vector &errors) -> int +int CRIRuntimeServiceImpl::DoRemovePodSandbox(const std::string &realSandboxID, std::vector &errors) { int ret = 0; container_delete_request *remove_request { nullptr }; @@ -1087,8 +1081,8 @@ auto CRIRuntimeServiceImpl::GetIP(const std::string &podSandboxID, container_ins return ""; } -auto CRIRuntimeServiceImpl::PodSandboxStatus( - const std::string &podSandboxID, Errors &error) -> std::unique_ptr +std::unique_ptr +CRIRuntimeServiceImpl::PodSandboxStatus(const std::string &podSandboxID, Errors &error) { container_inspect *inspect { nullptr }; std::unique_ptr podStatus(new runtime::v1alpha2::PodSandboxStatus); diff --git a/src/daemon/entry/cri/cri_security_context.cc b/src/daemon/entry/cri/cri_security_context.cc index 3b05e2c..634e53a 100644 --- a/src/daemon/entry/cri/cri_security_context.cc +++ b/src/daemon/entry/cri/cri_security_context.cc @@ -19,8 +19,7 @@ #include namespace CRISecurity { -static void ModifyContainerConfig(const runtime::v1alpha2::LinuxContainerSecurityContext &sc, - container_config *config) +static void ModifyContainerConfig(const runtime::v1alpha2::LinuxContainerSecurityContext &sc, container_config *config) { if (sc.has_run_as_user()) { free(config->user); @@ -89,7 +88,7 @@ static void ModifyHostConfigNoNewPrivs(const runtime::v1alpha2::LinuxContainerSe size_t oldSize = hostConfig->security_opt_len * sizeof(char *); size_t newSize = oldSize + sizeof(char *); - int ret = mem_realloc((void **)(&tmp_security_opt), newSize, (void *)hostConfig->security_opt, oldSize); + int ret = util_mem_realloc((void **)(&tmp_security_opt), newSize, (void *)hostConfig->security_opt, oldSize); if (ret != 0) { error.Errorf("Out of memory"); return; diff --git a/src/daemon/executor/container_cb/execution.c b/src/daemon/executor/container_cb/execution.c index 44ae32e..a41bd83 100644 --- a/src/daemon/executor/container_cb/execution.c +++ b/src/daemon/executor/container_cb/execution.c @@ -403,7 +403,7 @@ static int restart_container(container_t *cont) goto out; } - (void)get_now_time_buffer(timebuffer, sizeof(timebuffer)); + (void)util_get_now_time_buffer(timebuffer, sizeof(timebuffer)); params.rootpath = rootpath; @@ -706,7 +706,7 @@ static int container_kill_cb(const container_kill_request *request, container_ki goto pack_response; } - if (!util_check_signal_valid((int)signal)) { + if (!util_valid_signal((int)signal)) { isulad_set_error_message("Not supported signal %d", signal); ERROR("Not supported signal %d", signal); cc = ISULAD_ERR_EXEC; diff --git a/src/daemon/executor/container_cb/execution_create.c b/src/daemon/executor/container_cb/execution_create.c index 91c9692..761f0af 100644 --- a/src/daemon/executor/container_cb/execution_create.c +++ b/src/daemon/executor/container_cb/execution_create.c @@ -33,6 +33,7 @@ #include #include #include +#include #include "isula_libutils/log.h" #include "isulad_config.h" @@ -57,6 +58,9 @@ #include "utils_verify.h" #include "selinux_label.h" +static int do_init_cpurt_cgroups_path(const char *path, int recursive_depth, const char *mnt_root, + int64_t cpu_rt_period, int64_t cpu_rt_runtime); + static int runtime_check(const char *name, bool *runtime_res) { int ret = 0; @@ -479,7 +483,7 @@ static int register_new_container(const char *id, const char *runtime, host_conf container_config_v2_common_config **v2_spec) { int ret = -1; - bool registed = false; + bool registered = false; char *runtime_root = NULL; char *runtime_stat = NULL; char *image_id = NULL; @@ -511,8 +515,8 @@ static int register_new_container(const char *id, const char *runtime, host_conf goto out; } - registed = containers_store_add(id, cont); - if (!registed) { + registered = containers_store_add(id, cont); + if (!registered) { ERROR("Failed to register container '%s'", id); goto out; } @@ -576,7 +580,7 @@ out: static char *get_runtime_from_request(const container_create_request *request) { - return strings_to_lower(request->runtime); + return util_strings_to_lower(request->runtime); } static void pack_create_response(container_create_response *response, const char *id, uint32_t cc) @@ -916,12 +920,13 @@ static int pack_security_config_to_v2_spec(const host_config *host_spec, contain v2_spec->seccomp_profile = seccomp_profile; seccomp_profile = NULL; v2_spec->no_new_privileges = no_new_privileges; - +#ifdef ENABLE_SELINUX if (init_label((const char **)label_opts, label_opts_len, &process_label, &mount_label) != 0) { ERROR("Failed to append label"); ret = -1; goto out; } +#endif v2_spec->mount_label = mount_label; mount_label = NULL; @@ -944,7 +949,7 @@ static void v2_spec_fill_basic_info(const char *id, const char *name, const char v2_spec->name = name ? util_strdup_s(name) : NULL; v2_spec->image = image_name ? util_strdup_s(image_name) : util_strdup_s("none"); v2_spec->image_type = image_type ? util_strdup_s(image_type) : NULL; - (void)get_now_time_buffer(timebuffer, sizeof(timebuffer)); + (void)util_get_now_time_buffer(timebuffer, sizeof(timebuffer)); free(v2_spec->created); v2_spec->created = util_strdup_s(timebuffer); v2_spec->config = container_spec; @@ -1022,6 +1027,204 @@ static int save_container_config_before_create(const char *id, const char *runti return 0; } +/* maybe create cpu realtime file */ +static int maybe_create_cpu_realtime_file(int64_t value, const char *file, const char *path) +{ + int ret; + int fd = 0; + ssize_t nwrite; + char fpath[PATH_MAX] = { 0 }; + char buf[ISULAD_NUMSTRLEN64] = { 0 }; + + if (value == 0) { + return 0; + } + + ret = util_mkdir_p(path, CONFIG_DIRECTORY_MODE); + if (ret != 0) { + ERROR("Failed to mkdir: %s", path); + return -1; + } + + int nret = snprintf(fpath, sizeof(fpath), "%s/%s", path, file); + if (nret < 0 || nret >= sizeof(fpath)) { + ERROR("Failed to print string"); + return -1; + } + nret = snprintf(buf, sizeof(buf), "%lld", (long long int)value); + if (nret < 0 || (size_t)nret >= sizeof(buf)) { + ERROR("Failed to print string"); + return -1; + } + + fd = util_open(fpath, O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, 0700); + if (fd < 0) { + ERROR("Failed to open file: %s: %s", fpath, strerror(errno)); + isulad_set_error_message("Failed to open file: %s: %s", fpath, strerror(errno)); + return -1; + } + nwrite = util_write_nointr(fd, buf, strlen(buf)); + if (nwrite < 0) { + ERROR("Failed to write %s to %s: %s", buf, fpath, strerror(errno)); + isulad_set_error_message("Failed to write '%s' to '%s': %s", buf, fpath, strerror(errno)); + close(fd); + return -1; + } + close(fd); + + return 0; +} + +static int recursively_create_cgroup(const char *path, const char *mnt_root, int recursive_depth, int64_t cpu_rt_period, + int64_t cpu_rt_runtime) +{ + int ret = 0; + char *dup = NULL; + char *dirpath = NULL; + char fpath[PATH_MAX] = { 0 }; + + dup = util_strdup_s(path); + dirpath = dirname(dup); + ret = do_init_cpurt_cgroups_path(dirpath, (recursive_depth + 1), mnt_root, cpu_rt_period, cpu_rt_runtime); + free(dup); + if (ret != 0) { + return ret; + } + + int nret = snprintf(fpath, sizeof(fpath), "%s/%s", mnt_root, path); + if (nret < 0 || (size_t)nret >= sizeof(fpath)) { + ERROR("Failed to print string"); + ret = -1; + goto out; + } + + ret = maybe_create_cpu_realtime_file(cpu_rt_period, "cpu.rt_period_us", fpath); + if (ret != 0) { + goto out; + } + + ret = maybe_create_cpu_realtime_file(cpu_rt_runtime, "cpu.rt_runtime_us", fpath); + if (ret != 0) { + goto out; + } + +out: + return ret; +} + +/* init cgroups path */ +static int do_init_cpurt_cgroups_path(const char *path, int recursive_depth, const char *mnt_root, + int64_t cpu_rt_period, int64_t cpu_rt_runtime) +{ + if ((recursive_depth + 1) > MAX_PATH_DEPTH) { + ERROR("Reach the max cgroup depth:%s", path); + return -1; + } + + if (path == NULL || strcmp(path, "/") == 0 || strcmp(path, ".") == 0) { + return 0; + } + + // Recursively create cgroup to ensure that the system and all parent cgroups have values set + // for the period and runtime as this limits what the children can be set to. + if (recursively_create_cgroup(path, mnt_root, recursive_depth, cpu_rt_period, cpu_rt_runtime)) { + return -1; + } + + return 0; +} + +static char *get_cpurt_controller_mnt_path() +{ + char *res = NULL; + int nret = 0; + char *mnt = NULL; + char *root = NULL; + char fpath[PATH_MAX] = { 0 }; + + nret = find_cgroup_mountpoint_and_root("cpu", &mnt, &root); + if (nret != 0 || mnt == NULL || root == NULL) { + ERROR("Can not find cgroup mnt and root path for subsystem 'cpu'"); + isulad_set_error_message("Can not find cgroup mnt and root path for subsystem 'cpu'"); + goto out; + } + + // When iSulad is run inside docker, the root is based of the host cgroup. + // Replace root to "/" + if (strncmp(root, "/docker/", strlen("/docker/")) == 0) { + root[1] = '\0'; + } + + nret = snprintf(fpath, sizeof(fpath), "%s/%s", mnt, root); + if (nret < 0 || (size_t)nret >= sizeof(fpath)) { + ERROR("Failed to print string"); + goto out; + } + + res = util_strdup_s(fpath); + +out: + free(mnt); + free(root); + return res; +} + +static int cpurt_controller_init(const char *cgroups_path) +{ + int ret = 0; + char *dup = NULL; + char *dirpath = NULL; + int64_t cpu_rt_period = 0; + int64_t cpu_rt_runtime = 0; + sysinfo_t *sysinfo = NULL; + char *mnt_root = NULL; + + if (cgroups_path == NULL || strcmp(cgroups_path, "/") == 0 || strcmp(cgroups_path, ".") == 0) { + return 0; + } + + if (conf_get_cgroup_cpu_rt(&cpu_rt_period, &cpu_rt_runtime)) { + return -1; + } + + if (cpu_rt_period == 0 && cpu_rt_runtime == 0) { + return 0; + } + + sysinfo = get_sys_info(true); + if (sysinfo == NULL) { + ERROR("Can not get system info"); + ret = -1; + goto out; + } + + if (!(sysinfo->cgcpuinfo.cpu_rt_period)) { + ERROR("Daemon-scoped cpu-rt-period and cpu-rt-runtime are not supported by kernel"); + isulad_set_error_message("Daemon-scoped cpu-rt-period and cpu-rt-runtime are not supported by kernel"); + ret = -1; + goto out; + } + + mnt_root = get_cpurt_controller_mnt_path(); + if (mnt_root == NULL) { + ERROR("Failed to get cpu rt controller mnt root path"); + isulad_set_error_message("Failed to get cpu rt controller mnt root path"); + ret = -1; + goto out; + } + + dup = util_strdup_s(cgroups_path); + dirpath = dirname(dup); + + ret = do_init_cpurt_cgroups_path(dirpath, 0, mnt_root, cpu_rt_period, cpu_rt_runtime); + +out: + free_sysinfo(sysinfo); + free(mnt_root); + free(dup); + return ret; +} + /* * request -> host_spec + container_spec * container_spec + image config @@ -1127,11 +1330,6 @@ int container_create_cb(const container_create_request *request, container_creat goto umount_shm; } - ret = merge_oci_cgroups_path(id, oci_spec, host_spec); - if (ret < 0) { - goto umount_shm; - } - if (merge_config_for_syscontainer(request, host_spec, v2_spec->config, oci_spec) != 0) { ERROR("Failed to merge config for syscontainer"); cc = ISULAD_ERR_EXEC; @@ -1165,6 +1363,13 @@ int container_create_cb(const container_create_request *request, container_creat goto umount_channel; } + // init cgroup path for cpu_rt_runtime and cpu_rt_period + if (cpurt_controller_init(oci_spec->linux->cgroups_path) != 0) { + ERROR("Unable to init CPU RT controller %s", oci_spec->linux->cgroups_path); + cc = ISULAD_ERR_EXEC; + goto umount_channel; + } + if (container_v2_spec_merge_contaner_spec(v2_spec) != 0) { ERROR("Failed to merge container settings"); cc = ISULAD_ERR_EXEC; diff --git a/src/daemon/executor/container_cb/execution_extend.c b/src/daemon/executor/container_cb/execution_extend.c index df4655d..e63ec54 100644 --- a/src/daemon/executor/container_cb/execution_extend.c +++ b/src/daemon/executor/container_cb/execution_extend.c @@ -834,8 +834,41 @@ static void host_config_restore_unlocking(container_t *cont, host_config *backup } } -static void update_container_cpu(const host_config *hostconfig, host_config *chostconfig) +static int update_container_cpu(const host_config *hostconfig, host_config *chostconfig) { + int ret = 0; + + if (hostconfig->nano_cpus > 0 && chostconfig->cpu_period > 0) { + ERROR("Conflicting options: Nano CPUs cannot be updated as CPU Period has already been set"); + isulad_set_error_message("Conflicting options: Nano CPUs cannot be updated as CPU Period has already been set"); + ret = -1; + goto out; + } + + if (hostconfig->nano_cpus > 0 && chostconfig->cpu_quota > 0) { + ERROR("Conflicting options: Nano CPUs cannot be updated as CPU Quota has already been set"); + isulad_set_error_message("Conflicting options: Nano CPUs cannot be updated as CPU Quota has already been set"); + ret = -1; + goto out; + } + + if (hostconfig->cpu_period > 0 && chostconfig->nano_cpus > 0) { + ERROR("Conflicting options: CPU Period cannot be updated as NanoCPUs has already been set"); + isulad_set_error_message("Conflicting options: CPU Period cannot be updated as NanoCPUs has already been set"); + ret = -1; + goto out; + } + + if (hostconfig->cpu_quota > 0 && chostconfig->nano_cpus > 0) { + ERROR("Conflicting options: CPU Quota cannot be updated as NanoCPUs has already been set"); + isulad_set_error_message("Conflicting options: CPU Quota cannot be updated as NanoCPUs has already been set"); + ret = -1; + goto out; + } + + if (hostconfig->nano_cpus != 0) { + chostconfig->nano_cpus = hostconfig->nano_cpus; + } if (hostconfig->cpu_shares != 0) { chostconfig->cpu_shares = hostconfig->cpu_shares; } @@ -853,6 +886,15 @@ static void update_container_cpu(const host_config *hostconfig, host_config *cho free(chostconfig->cpuset_mems); chostconfig->cpuset_mems = util_strdup_s(hostconfig->cpuset_mems); } + if (hostconfig->cpu_realtime_period != 0) { + chostconfig->cpu_realtime_period = hostconfig->cpu_realtime_period; + } + if (hostconfig->cpu_realtime_runtime != 0) { + chostconfig->cpu_realtime_runtime = hostconfig->cpu_realtime_runtime; + } + +out: + return ret; } static int update_container_memory(const char *id, const host_config *hostconfig, host_config *chostconfig) @@ -926,7 +968,11 @@ static int update_container(const container_t *cont, const host_config *hostconf chostconfig->blkio_weight = hostconfig->blkio_weight; } - update_container_cpu(hostconfig, chostconfig); + ret = update_container_cpu(hostconfig, chostconfig); + if (ret != 0) { + ret = -1; + goto out; + } ret = update_container_memory(id, hostconfig, chostconfig); if (ret != 0) { diff --git a/src/daemon/executor/container_cb/execution_information.c b/src/daemon/executor/container_cb/execution_information.c index 4dd8166..720cd52 100644 --- a/src/daemon/executor/container_cb/execution_information.c +++ b/src/daemon/executor/container_cb/execution_information.c @@ -183,7 +183,7 @@ static int get_proxy_env(char **proxy, const char *type) *proxy = getenv(type); if (*proxy == NULL) { - tmp = strings_to_upper(type); + tmp = util_strings_to_upper(type); if (tmp == NULL) { ERROR("Failed to upper string!"); ret = -1; @@ -1007,13 +1007,13 @@ static int dup_container_config_cmd_and_entrypoint(const container_config *src, return 0; } - ret = dup_array_of_strings((const char **)(src->cmd), src->cmd_len, &(dest->cmd), &(dest->cmd_len)); + ret = util_dup_array_of_strings((const char **)(src->cmd), src->cmd_len, &(dest->cmd), &(dest->cmd_len)); if (ret != 0) { goto out; } - ret = dup_array_of_strings((const char **)(src->entrypoint), src->entrypoint_len, &(dest->entrypoint), - &(dest->entrypoint_len)); + ret = util_dup_array_of_strings((const char **)(src->entrypoint), src->entrypoint_len, &(dest->entrypoint), + &(dest->entrypoint_len)); out: return ret; } diff --git a/src/daemon/executor/container_cb/execution_network.c b/src/daemon/executor/container_cb/execution_network.c index 7bb0c36..f15707e 100644 --- a/src/daemon/executor/container_cb/execution_network.c +++ b/src/daemon/executor/container_cb/execution_network.c @@ -46,7 +46,7 @@ static int write_hostname_to_file(const char *rootfs, const char *hostname) goto out; } - if (realpath_in_scope(rootfs, "/etc/hostname", &file_path) < 0) { + if (util_realpath_in_scope(rootfs, "/etc/hostname", &file_path) < 0) { SYSERROR("Failed to get real path '/etc/hostname' under rootfs '%s'", rootfs); isulad_set_error_message("Failed to get real path '/etc/hostname' under rootfs '%s'", rootfs); goto out; @@ -76,7 +76,7 @@ out: static int fopen_network(FILE **fp, char **file_path, const char *rootfs, const char *filename) { - if (realpath_in_scope(rootfs, filename, file_path) < 0) { + if (util_realpath_in_scope(rootfs, filename, file_path) < 0) { SYSERROR("Failed to get real path '%s' under rootfs '%s'", filename, rootfs); isulad_set_error_message("Failed to get real path '%s' under rootfs '%s'", filename, rootfs); return -1; @@ -674,7 +674,7 @@ static int chown_network(const char *user_remap, const char *rootfs, const char ret = -1; goto out; } - if (realpath_in_scope(rootfs, filename, &file_path) < 0) { + if (util_realpath_in_scope(rootfs, filename, &file_path) < 0) { SYSERROR("Failed to get real path '%s' under rootfs '%s'", filename, rootfs); isulad_set_error_message("Failed to get real path '%s' under rootfs '%s'", filename, rootfs); ret = -1; @@ -1004,10 +1004,10 @@ int init_container_network_confs(const char *id, const char *rootpath, const hos container_config_v2_common_config *v2_spec) { int ret = 0; - bool share_host = is_host(hc->network_mode); + bool share_host = namespace_is_host(hc->network_mode); // is container mode - if (is_container(hc->network_mode)) { + if (namespace_is_container(hc->network_mode)) { return init_container_network_confs_container(id, hc, v2_spec); } diff --git a/src/daemon/executor/container_cb/execution_stream.c b/src/daemon/executor/container_cb/execution_stream.c index c897624..7e2ac38 100644 --- a/src/daemon/executor/container_cb/execution_stream.c +++ b/src/daemon/executor/container_cb/execution_stream.c @@ -381,18 +381,18 @@ static int archive_and_send_copy_data(const stream_func_wrapper *stream, return -1; } - if (cleanpath(resolvedpath, cleaned, sizeof(cleaned)) == NULL) { + if (util_clean_path(resolvedpath, cleaned, sizeof(cleaned)) == NULL) { ERROR("Can not clean path: %s", resolvedpath); goto cleanup; } - nret = split_dir_and_base_name(cleaned, &srcdir, &srcbase); + nret = util_split_dir_and_base_name(cleaned, &srcdir, &srcbase); if (nret != 0) { ERROR("split %s failed", cleaned); goto cleanup; } - nret = split_dir_and_base_name(abspath, NULL, &absbase); + nret = util_split_dir_and_base_name(abspath, NULL, &absbase); if (nret != 0) { ERROR("split %s failed", abspath); goto cleanup; @@ -453,7 +453,7 @@ static container_path_stat *do_container_stat_path(const char *rootpath, const c if (S_ISLNK(st.st_mode)) { char *p = NULL; - hostpath = get_resource_path(rootpath, abspath); + hostpath = util_get_resource_path(rootpath, abspath); if (hostpath == NULL) { ERROR("Failed to get resource path"); goto cleanup; @@ -481,7 +481,7 @@ static container_path_stat *do_container_stat_path(const char *rootpath, const c ERROR("Out of memory"); goto cleanup; } - nret = split_dir_and_base_name(abspath, NULL, &stat->name); + nret = util_split_dir_and_base_name(abspath, NULL, &stat->name); if (nret != 0) { ERROR("split %s failed", abspath); goto cleanup; @@ -538,7 +538,7 @@ static container_path_stat *resolve_and_stat_path(const char *rootpath, const ch char *abs = NULL; container_path_stat *stat = NULL; - nret = resolve_path(rootpath, srcpath, &resolved, &abs); + nret = util_resolve_path(rootpath, srcpath, &resolved, &abs); if (nret < 0) { ERROR("Can not resolve path: %s", srcpath); return NULL; @@ -844,17 +844,17 @@ static int copy_to_container_resolve_path(const container_t *cont, const char *d ERROR("Can not join path"); return -1; } - if (cleanpath(joined, cleaned, sizeof(cleaned)) == NULL) { + if (util_clean_path(joined, cleaned, sizeof(cleaned)) == NULL) { ERROR("Can not clean path: %s", dstdir); goto cleanup; } - *abspath = preserve_trailing_dot_or_separator(cleaned, dstdir); + *abspath = util_preserve_trailing_dot_or_separator(cleaned, dstdir); if (*abspath == NULL) { ERROR("Can not preserve path"); goto cleanup; } - *resolvedpath = get_resource_path(cont->common_config->base_fs, *abspath); + *resolvedpath = util_get_resource_path(cont->common_config->base_fs, *abspath); if (*resolvedpath == NULL) { ERROR("Can not get resource path"); goto cleanup; @@ -1062,7 +1062,7 @@ static int64_t do_read_log_file(const char *path, int64_t require_line, long pos break; } /* fopen is too fast, need wait rename operator finish */ - usleep_nointerupt(1000); + util_usleep_nointerupt(1000); } if (fp == NULL) { ERROR("open file: %s failed: %s", path, strerror(errno)); @@ -1079,7 +1079,7 @@ static int64_t do_read_log_file(const char *path, int64_t require_line, long pos (*last_pos) += (long)strlen(buffer); if (do_decode_write_log_entry(buffer, stream) != 0) { - /* read a incomplete json object, try agin */ + /* read a incomplete json object, try again */ decode_retries++; if (decode_retries < MAX_JSON_DECODE_RETRY) { continue; @@ -1341,7 +1341,7 @@ static int handle_rotate(int fd, int wd, const char *path) if (watch_fd >= 0) { break; } - usleep_nointerupt(1000); + util_usleep_nointerupt(1000); } if (watch_fd < 0) { SYSERROR("Add watch %s failed", path); @@ -1509,7 +1509,7 @@ static int do_follow_log_file(const char *cid, stream_func_wrapper *stream, stru ret = -1; break; } - usleep_nointerupt(10000); + util_usleep_nointerupt(10000); } out: diff --git a/src/daemon/executor/container_cb/list.c b/src/daemon/executor/container_cb/list.c index feccebe..9010337 100644 --- a/src/daemon/executor/container_cb/list.c +++ b/src/daemon/executor/container_cb/list.c @@ -341,7 +341,7 @@ static int convert_common_config_info(const map_t *map_labels, const container_c dup_id_name(common_config, isuladinfo); args_err = (common_config->created != NULL && - to_unix_nanos_from_str(common_config->created, &isuladinfo->created) != 0); + util_to_unix_nanos_from_str(common_config->created, &isuladinfo->created) != 0); if (args_err) { ret = -1; goto out; @@ -439,7 +439,7 @@ static int fill_isuladinfo(container_container *isuladinfo, const container_conf isuladinfo->health_state = container_get_health_state(cont_state); if (cont->common_config->created != NULL) { - ret = to_unix_nanos_from_str(cont->common_config->created, &created_nanos); + ret = util_to_unix_nanos_from_str(cont->common_config->created, &created_nanos); if (ret != 0) { goto out; } diff --git a/src/daemon/executor/image_cb/image_cb.c b/src/daemon/executor/image_cb/image_cb.c index 63a780b..57b1a6a 100644 --- a/src/daemon/executor/image_cb/image_cb.c +++ b/src/daemon/executor/image_cb/image_cb.c @@ -596,7 +596,7 @@ static int trans_one_image(image_list_images_response *response, size_t image_in int64_t created_nanos = 0; types_timestamp_t timestamp; - if (to_unix_nanos_from_str(im_image->created, &created_nanos) != 0) { + if (util_to_unix_nanos_from_str(im_image->created, &created_nanos) != 0) { ERROR("Failed to translate created time to nanos"); ret = -1; goto out; @@ -930,7 +930,7 @@ out: return ret; } -/* When inspect none image, we respone following string according hasen's request. */ +/* When inspect none image, we respond following string according hasen's request. */ #define INSPECT_NONE_IMAGE_RESP \ "{ \ \"ContainerConfig\": { \ diff --git a/src/daemon/modules/container/container_events_handler.c b/src/daemon/modules/container/container_events_handler.c index b227541..447097b 100644 --- a/src/daemon/modules/container/container_events_handler.c +++ b/src/daemon/modules/container/container_events_handler.c @@ -141,7 +141,7 @@ static int container_state_changed(container_t *cont, const struct isulad_events should_restart = restart_manager_should_restart(id, events->exit_status, cont->common_config->has_been_manually_stopped, - time_seconds_since(started_at), &timeout); + util_time_seconds_since(started_at), &timeout); free(started_at); started_at = NULL; diff --git a/src/daemon/modules/container/container_gc/containers_gc.c b/src/daemon/modules/container/container_gc/containers_gc.c index dbf2077..89c4e31 100644 --- a/src/daemon/modules/container/container_gc/containers_gc.c +++ b/src/daemon/modules/container/container_gc/containers_gc.c @@ -130,7 +130,7 @@ out: return ret; } -/* notes: this funciton must be called with gc_containers_lock */ +/* notes: this function must be called with gc_containers_lock */ static int gc_containers_to_disk() { int ret = 0; @@ -356,7 +356,7 @@ static void apply_restart_policy_after_gc(const char *id) exit_code = container_state_get_exitcode(cont->state); should_restart = restart_manager_should_restart(id, exit_code, cont->common_config->has_been_manually_stopped, - time_seconds_since(started_at), &timeout); + util_time_seconds_since(started_at), &timeout); free(started_at); if (should_restart) { @@ -535,7 +535,7 @@ static void *gchandler(void *arg) do_gc_container(it); wait_continue: - usleep_nointerupt(100 * 1000); /* wait 100 millisecond to check next gc container */ + util_usleep_nointerupt(100 * 1000); /* wait 100 millisecond to check next gc container */ } error: return NULL; diff --git a/src/daemon/modules/container/container_state.c b/src/daemon/modules/container/container_state.c index 47f12ac..d4a448a 100644 --- a/src/daemon/modules/container/container_state.c +++ b/src/daemon/modules/container/container_state.c @@ -167,7 +167,7 @@ void container_state_set_running(container_state_t *s, const pid_ppid_info_t *pi state->p_start_time = 0; } - (void)get_now_time_buffer(timebuffer, sizeof(timebuffer)); + (void)util_get_now_time_buffer(timebuffer, sizeof(timebuffer)); free(state->started_at); state->started_at = util_strdup_s(timebuffer); @@ -198,7 +198,7 @@ void container_state_set_stopped(container_state_t *s, int exit_code) state->p_pid = 0; state->p_start_time = 0; - (void)get_now_time_buffer(timebuffer, sizeof(timebuffer)); + (void)util_get_now_time_buffer(timebuffer, sizeof(timebuffer)); free(state->finished_at); state->finished_at = util_strdup_s(timebuffer); @@ -259,7 +259,7 @@ void container_restart_update_start_and_finish_time(container_state_t *s, const state->paused = false; state->exit_code = 0; - (void)get_now_time_buffer(timebuffer, sizeof(timebuffer)); + (void)util_get_now_time_buffer(timebuffer, sizeof(timebuffer)); free(state->finished_at); state->finished_at = util_strdup_s(finish_at); free(state->started_at); @@ -294,7 +294,7 @@ void container_state_set_restarting(container_state_t *s, int exit_code) state->p_start_time = 0; state->exit_code = exit_code; - (void)get_now_time_buffer(timebuffer, sizeof(timebuffer)); + (void)util_get_now_time_buffer(timebuffer, sizeof(timebuffer)); free(state->finished_at); state->finished_at = util_strdup_s(timebuffer); diff --git a/src/daemon/modules/container/health_check/health_check.c b/src/daemon/modules/container/health_check/health_check.c index 8905f90..75c3f3d 100644 --- a/src/daemon/modules/container/health_check/health_check.c +++ b/src/daemon/modules/container/health_check/health_check.c @@ -297,8 +297,8 @@ static int append_last_log_result(defs_health *health, const defs_health_log_ele return -1; } - ret = mem_realloc((void **)(&tmp_log), (health->log_len + 1) * sizeof(defs_health_log_element *), health->log, - health->log_len * sizeof(defs_health_log_element *)); + ret = util_mem_realloc((void **)(&tmp_log), (health->log_len + 1) * sizeof(defs_health_log_element *), health->log, + health->log_len * sizeof(defs_health_log_element *)); if (ret != 0) { ERROR("failed to realloc memory"); return -1; @@ -356,12 +356,12 @@ static int handle_unhealthy_case(container_t *cont, const defs_health_log_elemen DEFAULT_START_PERIOD : cont->common_config->config->healthcheck->start_period; int64_t first, last; - if (to_unix_nanos_from_str(cont->state->state->started_at, &first)) { + if (util_to_unix_nanos_from_str(cont->state->state->started_at, &first)) { ERROR("Parse container started time failed: %s", cont->state->state->started_at); ret = -1; goto out; } - if (to_unix_nanos_from_str(result->start, &last)) { + if (util_to_unix_nanos_from_str(result->start, &last)) { ERROR("Parse last health check start time failed: %s", result->start); ret = -1; goto out; @@ -560,7 +560,7 @@ void *health_check_run(void *arg) cmd_slice = NULL; EVENT("EVENT: {Object: %s, Type: Health checking}", cont->common_config->id); - (void)get_now_time_buffer(timebuffer, sizeof(timebuffer)); + (void)util_get_now_time_buffer(timebuffer, sizeof(timebuffer)); result = util_common_calloc_s(sizeof(defs_health_log_element)); if (result == NULL) { ERROR("Out of memory"); @@ -581,7 +581,7 @@ void *health_check_run(void *arg) health_check_exec_success_handle(container_res, result, output); } - (void)get_now_time_buffer(timebuffer, sizeof(timebuffer)); + (void)util_get_now_time_buffer(timebuffer, sizeof(timebuffer)); result->end = util_strdup_s(timebuffer); if (handle_probe_result(cont->common_config->id, result) != 0) { @@ -644,7 +644,7 @@ static int do_monitor_interval(const char *container_id, health_check_manager_t goto out; } set_monitor_idle_status(health_check); - if (get_now_time_stamp(start_timestamp) == false) { + if (util_get_now_time_stamp(start_timestamp) == false) { ERROR("Failed to get time stamp"); ret = -1; goto out; @@ -658,12 +658,12 @@ static int do_monitor_default(int64_t probe_interval, health_check_manager_t *he { int64_t time_interval = 0; - if (get_now_time_stamp(last_timestamp) == false) { + if (util_get_now_time_stamp(last_timestamp) == false) { ERROR("Failed to get time stamp"); return -1; } - if (get_time_interval(*start_timestamp, *last_timestamp, &time_interval)) { + if (util_get_time_interval(*start_timestamp, *last_timestamp, &time_interval)) { ERROR("Failed to get time interval"); return -1; } @@ -671,7 +671,7 @@ static int do_monitor_default(int64_t probe_interval, health_check_manager_t *he if (time_interval >= probe_interval) { set_monitor_interval_timeout_status(health_check); } - usleep_nointerupt(500); + util_usleep_nointerupt(500); return 0; } @@ -697,7 +697,7 @@ static void *health_check_monitor(void *arg) goto out; } - if (get_now_time_stamp(&start_timestamp) == false) { + if (util_get_now_time_stamp(&start_timestamp) == false) { ERROR("Failed to monitor start time stamp"); goto out; } diff --git a/src/daemon/modules/container/restore/restore.c b/src/daemon/modules/container/restore/restore.c index 372d4bd..02f4127 100644 --- a/src/daemon/modules/container/restore/restore.c +++ b/src/daemon/modules/container/restore/restore.c @@ -348,7 +348,7 @@ static void restored_restart_container(container_t *cont) started_at = container_state_get_started_at(cont->state); if (restart_manager_should_restart(id, container_state_get_exitcode(cont->state), - cont->common_config->has_been_manually_stopped, time_seconds_since(started_at), + cont->common_config->has_been_manually_stopped, util_time_seconds_since(started_at), &timeout)) { cont->common_config->restart_count++; INFO("Restart container %s after 5 second", id); diff --git a/src/daemon/modules/container/supervisor/supervisor.c b/src/daemon/modules/container/supervisor/supervisor.c index ac49f6a..6267a25 100644 --- a/src/daemon/modules/container/supervisor/supervisor.c +++ b/src/daemon/modules/container/supervisor/supervisor.c @@ -189,7 +189,7 @@ retry: } if (retry_count < max_retry) { - usleep_nointerupt(100 * 1000); /* 100 millisecond */ + util_usleep_nointerupt(100 * 1000); /* 100 millisecond */ retry_count++; goto retry; } diff --git a/src/daemon/modules/events/collector.c b/src/daemon/modules/events/collector.c index 1165972..3e587ae 100644 --- a/src/daemon/modules/events/collector.c +++ b/src/daemon/modules/events/collector.c @@ -598,7 +598,7 @@ out: static int check_since_time(const types_timestamp_t *since, const struct isulad_events_format *event) { if (since != NULL && (since->has_seconds || since->has_nanos)) { - if (types_timestamp_cmp(&event->timestamp, since) < 0) { + if (util_types_timestamp_cmp(&event->timestamp, since) < 0) { return -1; } } @@ -608,7 +608,7 @@ static int check_since_time(const types_timestamp_t *since, const struct isulad_ static int check_util_time(const types_timestamp_t *until, const struct isulad_events_format *event) { if (until != NULL && (until->has_seconds || until->has_nanos)) { - if (types_timestamp_cmp(&event->timestamp, until) > 0) { + if (util_types_timestamp_cmp(&event->timestamp, until) > 0) { return -1; } } @@ -684,7 +684,7 @@ int events_subscribe(const char *name, const types_timestamp_t *since, const typ if (since != NULL && (since->has_seconds || since->has_nanos) && until != NULL && (until->has_seconds || until->has_nanos)) { - if (types_timestamp_cmp(since, until) > 0) { + if (util_types_timestamp_cmp(since, until) > 0) { ERROR("'since' time cannot be after 'until' time"); return -1; } @@ -717,7 +717,7 @@ static void events_forward(struct isulad_events_format *r) name = context_info->name; if (context_info->since != NULL) { - if (types_timestamp_cmp(&r->timestamp, context_info->since) < 0) { + if (util_types_timestamp_cmp(&r->timestamp, context_info->since) < 0) { continue; } } @@ -806,7 +806,7 @@ static void *event_should_exit(void *arg) t_now.has_nanos = true; t_now.nanos = (int32_t)ts_now.tv_nsec; - if (types_timestamp_cmp(&t_now, context_info->until) > 0) { + if (util_types_timestamp_cmp(&t_now, context_info->until) > 0) { INFO("Finish response for RPC, client should exit"); linked_list_del(it); sem_post(&context_info->context_sem); @@ -988,15 +988,15 @@ out: return ret; } -static int start_monitord() +static int start_monitored() { int ret = 0; - int monitord_exitcode = 0; + int monitored_exitcode = 0; sem_t monitord_sem; struct monitord_sync_data msync = { 0 }; msync.monitord_sem = &monitord_sem; - msync.exit_code = &monitord_exitcode; + msync.exit_code = &monitored_exitcode; if (sem_init(msync.monitord_sem, 0, 0)) { isulad_set_error_message("Failed to init monitor sem"); ret = -1; @@ -1004,7 +1004,7 @@ static int start_monitord() } if (new_monitord(&msync)) { - isulad_set_error_message("Create monitord thread failed"); + isulad_set_error_message("Create monitored thread failed"); ret = -1; sem_destroy(msync.monitord_sem); goto out; @@ -1012,8 +1012,8 @@ static int start_monitord() sem_wait(msync.monitord_sem); sem_destroy(msync.monitord_sem); - if (monitord_exitcode) { - isulad_set_error_message("Monitord start failed"); + if (monitored_exitcode) { + isulad_set_error_message("Monitored start failed"); ret = -1; goto out; } @@ -1032,7 +1032,7 @@ int events_module_init(char **msg) goto out; } - if (start_monitord()) { + if (start_monitored()) { *msg = g_isulad_errmsg ? g_isulad_errmsg : "Failed to init cgroups path"; ret = -1; goto out; diff --git a/src/daemon/modules/events/monitord.c b/src/daemon/modules/events/monitord.c index 70ab4eb..3cf0744 100644 --- a/src/daemon/modules/events/monitord.c +++ b/src/daemon/modules/events/monitord.c @@ -10,7 +10,7 @@ * See the Mulan PSL v2 for more details. * Author: tanyifeng * Create: 2017-11-22 - * Description: provide container monitord functions + * Description: provide container monitored functions ******************************************************************************/ #define _GNU_SOURCE @@ -33,7 +33,7 @@ #include "event_type.h" #include "utils_file.h" -struct monitord_handler { +struct monitored_handler { struct epoll_descr *pdescr; int fifo_fd; char *fifo_path; @@ -61,8 +61,8 @@ out: return 0; } -/* free monitord */ -static void free_monitord(struct monitord_handler *mhandler) +/* free monitored */ +static void free_monitored(struct monitored_handler *mhandler) { if (mhandler->fifo_fd != -1) { epoll_loop_del_handler(mhandler->pdescr, mhandler->fifo_fd); @@ -76,16 +76,16 @@ static void free_monitord(struct monitord_handler *mhandler) mhandler->fifo_path = NULL; } - DEBUG("Clean monitord data..."); + DEBUG("Clean monitored data..."); } #define EVENTS_FIFO_SIZE (1024 * 1024) -/* monitord */ -static void *monitord(void *arg) +/* monitored */ +static void *monitored(void *arg) { int ret = 0; char *fifo_file_path = NULL; - struct monitord_handler mhandler = { 0 }; + struct monitored_handler mhandler = { 0 }; struct flock mlock; struct monitord_sync_data *msync = arg; struct epoll_descr descr; @@ -97,7 +97,7 @@ static void *monitord(void *arg) goto pexit; } - prctl(PR_SET_NAME, "Monitord"); + prctl(PR_SET_NAME, "Monitored"); ret = epoll_loop_open(&descr); if (ret != 0) { @@ -114,13 +114,13 @@ static void *monitord(void *arg) mhandler.fifo_path = fifo_file_path; if (mknod(fifo_file_path, S_IFIFO | S_IRUSR | S_IWUSR, (dev_t)0) && errno != EEXIST) { - ERROR("Create monitord fifo file failed: %s", strerror(errno)); + ERROR("Create monitored fifo file failed: %s", strerror(errno)); goto err; } mhandler.fifo_fd = util_open(fifo_file_path, O_RDWR | O_NONBLOCK | O_CLOEXEC, 0); if (mhandler.fifo_fd == -1) { - ERROR("Open monitord fifo file failed: %s", strerror(errno)); + ERROR("Open monitored fifo file failed: %s", strerror(errno)); goto err; } @@ -134,7 +134,7 @@ static void *monitord(void *arg) mlock.l_start = 0; mlock.l_len = 0; if (fcntl(mhandler.fifo_fd, F_SETLK, &mlock)) { - INFO("Monitord already running on path: %s", fifo_file_path); + INFO("Monitored already running on path: %s", fifo_file_path); goto err; } @@ -146,7 +146,7 @@ static void *monitord(void *arg) sem_post(msync->monitord_sem); - /* loop forever except error occured */ + /* loop forever except error occurred */ do { ret = epoll_loop(&descr, -1); } while (ret == 0); @@ -158,22 +158,22 @@ err: *(msync->exit_code) = -1; sem_post(msync->monitord_sem); err2: - free_monitord(&mhandler); + free_monitored(&mhandler); epoll_loop_close(&descr); pexit: return NULL; } -/* new monitord */ +/* new monitored */ int new_monitord(struct monitord_sync_data *msync) { int ret = 0; char *statedir = NULL; - pthread_t monitord_thread; + pthread_t monitored_thread; if (msync == NULL || msync->monitord_sem == NULL) { - ERROR("Monitord sem is NULL"); + ERROR("Monitored sem is NULL"); ret = -1; goto out; } @@ -185,15 +185,15 @@ int new_monitord(struct monitord_sync_data *msync) goto out; } - if (setenv("ISULAD_MONITORD_PATH", statedir, 1)) { - ERROR("Setenv monitord path failed"); + if (setenv("ISULAD_MONITORED_PATH", statedir, 1)) { + ERROR("Setenv monitored path failed"); ret = -1; goto out; } - INFO("Starting monitord..."); - if (pthread_create(&monitord_thread, NULL, monitord, msync) != 0) { - ERROR("Create monitord thread failed"); + INFO("Starting monitored..."); + if (pthread_create(&monitored_thread, NULL, monitored, msync) != 0) { + ERROR("Create monitored thread failed"); ret = -1; } diff --git a/src/daemon/modules/events/monitord.h b/src/daemon/modules/events/monitord.h index 00a09ca..beace80 100644 --- a/src/daemon/modules/events/monitord.h +++ b/src/daemon/modules/events/monitord.h @@ -10,10 +10,10 @@ * See the Mulan PSL v2 for more details. * Author: maoweiyong * Create: 2017-11-22 - * Description: provide monitord definition + * Description: provide monitored definition ******************************************************************************/ -#ifndef DAEMON_MODULES_EVENTS_MONITORD_H -#define DAEMON_MODULES_EVENTS_MONITORD_H +#ifndef DAEMON_MODULES_EVENTS_MONITORED_H +#define DAEMON_MODULES_EVENTS_MONITORED_H #include #include #include diff --git a/src/daemon/modules/events_sender/event_sender.c b/src/daemon/modules/events_sender/event_sender.c index 63c8c26..03dcbbf 100644 --- a/src/daemon/modules/events_sender/event_sender.c +++ b/src/daemon/modules/events_sender/event_sender.c @@ -59,7 +59,7 @@ static void isulad_monitor_fifo_send(const struct monitord_msg *msg) do { ret = util_write_nointr(fd, msg, sizeof(struct monitord_msg)); if (ret != sizeof(struct monitord_msg)) { - usleep_nointerupt(1000); + util_usleep_nointerupt(1000); } } while (ret != sizeof(struct monitord_msg)); diff --git a/src/daemon/modules/image/CMakeLists.txt b/src/daemon/modules/image/CMakeLists.txt index a4d569e..a92799a 100644 --- a/src/daemon/modules/image/CMakeLists.txt +++ b/src/daemon/modules/image/CMakeLists.txt @@ -100,5 +100,7 @@ target_link_libraries(${LIB_ISULAD_IMG} ${SELINUX_LIBRARY} -lpthread -lcrypto -larchive -lz libhttpclient) +target_compile_definitions(${LIB_ISULAD_IMG} PRIVATE LIB_ISULAD_IMG_SO) + install(TARGETS ${LIB_ISULAD_IMG} LIBRARY DESTINATION ${LIB_INSTALL_DIR_DEFAULT} PERMISSIONS OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE) diff --git a/src/daemon/modules/image/embedded/db/db_all.c b/src/daemon/modules/image/embedded/db/db_all.c index 185eb75..6d6670d 100644 --- a/src/daemon/modules/image/embedded/db/db_all.c +++ b/src/daemon/modules/image/embedded/db/db_all.c @@ -299,7 +299,7 @@ static int db_save_image_info_sql(struct db_image *image) sqlite3_bind_text(stmt, 12, image->config_digest, -1, SQLITE_STATIC); sqlite3_bind_text(stmt, 13, image->config_path, -1, SQLITE_STATIC); if (sqlite3_step(stmt) != SQLITE_DONE) { - ERROR("Insert image info into the image infomation table failed!"); + ERROR("Insert image info into the image information table failed!"); ret = DB_FAIL; } @@ -373,7 +373,7 @@ int db_save_image(struct db_image *image) ret = db_add_image_name_sql(image->image_name, image->config_digest, image->config_path); if (ret) { - /* Should not error when add image name. If error occured, + /* Should not error when add image name. If error occurred, * database is abnormal, so do not rollback. */ goto out; } @@ -699,8 +699,8 @@ static int read_all_images_info(sqlite3_stmt *stmt, void **data) } oldsize = (*imagesinfo)->imagesnum * sizeof(struct db_image *); newsize = ((*imagesinfo)->imagesnum + 1) * sizeof(struct db_image *); - ret = mem_realloc((void **)(&(*imagesinfo)->images_info), newsize, - (*imagesinfo)->images_info, oldsize); + ret = util_mem_realloc((void **)(&(*imagesinfo)->images_info), newsize, + (*imagesinfo)->images_info, oldsize); if (ret < 0) { ERROR("Out of memory!"); goto cleanup; diff --git a/src/daemon/modules/image/embedded/db/sqlite_common.c b/src/daemon/modules/image/embedded/db/sqlite_common.c index f8c7c2a..42fdf6d 100644 --- a/src/daemon/modules/image/embedded/db/sqlite_common.c +++ b/src/daemon/modules/image/embedded/db/sqlite_common.c @@ -25,10 +25,10 @@ // Waiting at most (10 * 1000ms) when database is busy // to avoid concurrent write or read. -#define SQLITE_BUSY_TIMEOUT 120000 +#define ISULA_SQLITE_BUSY_TIMEOUT 120000 -#define SQLITE_PAGECACHE_SIZE 4096 -#define SQLITE_PAGECACHE_NUM 8 +#define ISULA_SQLITE_PAGECACHE_SIZE 4096 +#define ISULA_SQLITE_PAGECACHE_NUM 8 sqlite3 *g_db = NULL; @@ -74,7 +74,7 @@ int db_sqlite_request(const char *stmt) char *errmsg = NULL; int ret; - ret = sqlite3_busy_timeout(g_db, SQLITE_BUSY_TIMEOUT); + ret = sqlite3_busy_timeout(g_db, ISULA_SQLITE_BUSY_TIMEOUT); if (ret != SQLITE_OK) { ERROR("Falied to set sqlite busy timeout"); return ret; @@ -94,7 +94,7 @@ int db_sqlite_request_callback(const char *stmt, char *errmsg = NULL; int ret; - ret = sqlite3_busy_timeout(g_db, SQLITE_BUSY_TIMEOUT); + ret = sqlite3_busy_timeout(g_db, ISULA_SQLITE_BUSY_TIMEOUT); if (ret != SQLITE_OK) { ERROR("Falied to set sqlite busy timeout"); return ret; @@ -163,8 +163,8 @@ int db_common_init(const char *rootpath) ERROR("Failed to print string"); return -1; } - ret = sqlite3_config(SQLITE_CONFIG_PAGECACHE, NULL, SQLITE_PAGECACHE_SIZE, - SQLITE_PAGECACHE_NUM); + ret = sqlite3_config(SQLITE_CONFIG_PAGECACHE, NULL, ISULA_SQLITE_PAGECACHE_SIZE, + ISULA_SQLITE_PAGECACHE_NUM); if (ret != SQLITE_OK) { goto open_new_db; } diff --git a/src/daemon/modules/image/embedded/embedded_config_merge.c b/src/daemon/modules/image/embedded/embedded_config_merge.c index c60bbcc..29878a4 100644 --- a/src/daemon/modules/image/embedded/embedded_config_merge.c +++ b/src/daemon/modules/image/embedded/embedded_config_merge.c @@ -13,6 +13,7 @@ * Description: provide embedded image merge config ******************************************************************************/ #define _GNU_SOURCE /* See feature_test_macros(7) */ +#include "embedded_config_merge.h" #include /* Obtain O_* constant definitions */ #include #include @@ -28,13 +29,13 @@ #include "specs_mount.h" #include "lim.h" #include "mediatype.h" -#include "embedded_config_merge.h" +#include "image_spec_merge.h" static int embedded_merge_entrypoint(embedded_config *config, container_config *container_spec) { if (config->entrypoint && container_spec->entrypoint_len == 0) { - int ret = dup_array_of_strings((const char **)config->entrypoint, config->entrypoint_len, - &(container_spec->entrypoint), &(container_spec->entrypoint_len)); + int ret = util_dup_array_of_strings((const char **)config->entrypoint, config->entrypoint_len, + &(container_spec->entrypoint), &(container_spec->entrypoint_len)); if (ret != 0) { ERROR("Failed to duplicate entrypoint from manifest"); return -1; @@ -47,64 +48,16 @@ static int embedded_merge_entrypoint(embedded_config *config, container_config * static int embedded_merge_env(const embedded_config *config, container_config *container_spec) { int ret = 0; - size_t new_size = 0; - size_t old_size = 0; - size_t i = 0; - size_t j = 0; - char **temp = NULL; - char **im_kv = NULL; - char **custom_kv = NULL; if (config->env == NULL || config->env_len == 0) { return 0; } - if (config->env_len > LIST_ENV_SIZE_MAX - container_spec->env_len) { - ERROR("The length of envionment variables is too long, the limit is %lld", LIST_ENV_SIZE_MAX); - isulad_set_error_message("The length of envionment variables is too long, the limit is %lld", - LIST_ENV_SIZE_MAX); + if (image_spec_merge_env((const char **)config->env, config->env_len, container_spec) != 0) { ret = -1; goto out; } - new_size = (container_spec->env_len + config->env_len) * sizeof(char *); - old_size = container_spec->env_len * sizeof(char *); - ret = mem_realloc((void **)&temp, new_size, container_spec->env, old_size); - if (ret != 0) { - ERROR("Failed to realloc memory for envionment variables"); - ret = -1; - goto out; - } - - container_spec->env = temp; - for (i = 0; i < config->env_len; i++) { - bool found = false; - im_kv = util_string_split(config->env[i], '='); - if (im_kv == NULL) { - continue; - } - for (j = 0; j < container_spec->env_len; j++) { - custom_kv = util_string_split(container_spec->env[j], '='); - if (custom_kv == NULL) { - continue; - } - if (strcmp(im_kv[0], custom_kv[0]) == 0) { - found = true; - } - util_free_array(custom_kv); - custom_kv = NULL; - if (found) { - break; - } - } - - if (!found) { - container_spec->env[container_spec->env_len] = util_strdup_s(config->env[i]); - container_spec->env_len++; - } - util_free_array(im_kv); - im_kv = NULL; - } out: return ret; } diff --git a/src/daemon/modules/image/embedded/embedded_config_merge.h b/src/daemon/modules/image/embedded/embedded_config_merge.h index db0a15e..d2fd734 100644 --- a/src/daemon/modules/image/embedded/embedded_config_merge.h +++ b/src/daemon/modules/image/embedded/embedded_config_merge.h @@ -15,7 +15,7 @@ #ifndef __EMBEDDED_IMAGE_MERGE_CONFIG_H_ #define __EMBEDDED_IMAGE_MERGE_CONFIG_H_ -#include "isula_libutils/oci_image_spec.h" +#include "isula_libutils/container_config.h" #ifdef __cplusplus extern "C" { @@ -28,4 +28,3 @@ int embedded_image_merge_config(const char *image_config, container_config *cont #endif #endif - diff --git a/src/daemon/modules/image/embedded/lim.c b/src/daemon/modules/image/embedded/lim.c index 8de60d9..f986b6c 100644 --- a/src/daemon/modules/image/embedded/lim.c +++ b/src/daemon/modules/image/embedded/lim.c @@ -249,7 +249,7 @@ static bool validate_layer_path_in_host(size_t layer_index, const char *location UTIL_FREE_AND_SET_NULL(tmp_path); return false; } - tmp_path = follow_symlink_in_scope(abs_path, parent_location); + tmp_path = util_follow_symlink_in_scope(abs_path, parent_location); if (tmp_path == NULL || !strncmp(tmp_path, "..", 2)) { ERROR("invalid layer path %s", path_in_host); isulad_try_set_error_message("Invalid content in manifest: layer not exists"); @@ -312,7 +312,7 @@ static bool validate_layer_digest(size_t layer_index, char *path, uint32_t fmod, /* If layer is a directory, digest must be empty */ if ((int)fmod == S_IFDIR) { ERROR("Invalid digest %s, digest must be empty if media type is %s", digest, MediaTypeEmbeddedLayerDir); - isulad_try_set_error_message("Invalid content in mainfest: layer digest must be empty if mediaType is %s", + isulad_try_set_error_message("Invalid content in manifest: layer digest must be empty if mediaType is %s", MediaTypeEmbeddedLayerDir); return false; } @@ -320,13 +320,13 @@ static bool validate_layer_digest(size_t layer_index, char *path, uint32_t fmod, /* check if digest format is valid */ if (!util_valid_digest(digest)) { ERROR("invalid digest %s for layer", digest); - isulad_try_set_error_message("Invalid content in mainfest: layer(except first layer) has invalid digest"); + isulad_try_set_error_message("Invalid content in manifest: layer(except first layer) has invalid digest"); return false; } /* calc and check digest */ if (!sha256_valid_digest_file(path, digest)) { - isulad_try_set_error_message("Invalid content in mainfest: layer(except first layer) has invalid digest"); + isulad_try_set_error_message("Invalid content in manifest: layer(except first layer) has invalid digest"); return false; } @@ -386,7 +386,7 @@ static bool validate_image_name(char *image_name) { if (image_name == NULL) { ERROR("image name not exist"); - isulad_try_set_error_message("Invalid content in manfiest: image name not exist"); + isulad_try_set_error_message("Invalid content in manifest: image name not exist"); return false; } @@ -399,7 +399,7 @@ static bool validate_image_name(char *image_name) if (!util_valid_embedded_image_name(image_name)) { ERROR("invalid image name %s", image_name); - isulad_try_set_error_message("Invalid content in manfiest: invalid image name"); + isulad_try_set_error_message("Invalid content in manifest: invalid image name"); return false; } return true; @@ -410,7 +410,7 @@ static bool validate_image_layers_number(size_t layers_len) { if (layers_len > LAYER_NUM_MAX || layers_len < 1) { ERROR("invalid layers number %ld maxium is %d", layers_len, LAYER_NUM_MAX); - isulad_try_set_error_message("Invalid content in mainfest: layer empty or max depth exceeded"); + isulad_try_set_error_message("Invalid content in manifest: layer empty or max depth exceeded"); return false; } return true; diff --git a/src/daemon/modules/image/embedded/lim.h b/src/daemon/modules/image/embedded/lim.h index 7a0f7b8..cb21884 100644 --- a/src/daemon/modules/image/embedded/lim.h +++ b/src/daemon/modules/image/embedded/lim.h @@ -33,7 +33,7 @@ struct image_creator { struct image_info { char *image_name; /* image name */ char *image_type; /* image type. docker or embedded */ - int64_t size; /* image sieze */ + int64_t size; /* image size */ char *chain_id; /* chain id of image's top layer */ char *config_digest; /* sha256 digest of image's config */ }; diff --git a/src/daemon/modules/image/image.c b/src/daemon/modules/image/image.c index 87025ad..551c630 100644 --- a/src/daemon/modules/image/image.c +++ b/src/daemon/modules/image/image.c @@ -245,7 +245,7 @@ static const struct bim_type *bim_query(const char *image_name) } temp = g_bims[i].ops->resolve_image_name(image_name); if (temp == NULL) { - isulad_append_error_message("Failed to resovle image name%s", image_name); + isulad_append_error_message("Failed to resolve image name%s", image_name); return NULL; } int r = g_bims[i].ops->detect(temp); @@ -325,7 +325,7 @@ static struct bim *bim_get(const char *image_type, const char *image_name, const if (image_name != NULL) { bim->image_name = bim->ops->resolve_image_name(image_name); if (bim->image_name == NULL) { - isulad_append_error_message("Failed to resovle image name%s", image_name); + isulad_append_error_message("Failed to resolve image name%s", image_name); bim_put(bim); return NULL; } @@ -808,7 +808,7 @@ static int append_images_to_response(im_list_response *response, imagetool_image new_size = (old_num + images_num) * sizeof(imagetool_image *); old_size = old_num * sizeof(imagetool_image *); - ret = mem_realloc((void **)(&tmp), new_size, response->images->images, old_size); + ret = util_mem_realloc((void **)(&tmp), new_size, response->images->images, old_size); if (ret != 0) { ERROR("Failed to realloc memory for append images"); ret = -1; @@ -962,17 +962,17 @@ void free_im_pull_request(im_pull_request *req) req->type = NULL; free(req->image); req->image = NULL; - free_sensitive_string(req->username); + util_free_sensitive_string(req->username); req->username = NULL; - free_sensitive_string(req->password); + util_free_sensitive_string(req->password); req->password = NULL; - free_sensitive_string(req->auth); + util_free_sensitive_string(req->auth); req->auth = NULL; - free_sensitive_string(req->server_address); + util_free_sensitive_string(req->server_address); req->server_address = NULL; - free_sensitive_string(req->registry_token); + util_free_sensitive_string(req->registry_token); req->registry_token = NULL; - free_sensitive_string(req->identity_token); + util_free_sensitive_string(req->identity_token); req->identity_token = NULL; free(req); } @@ -1235,16 +1235,16 @@ void free_im_login_request(im_login_request *ptr) return; } - free_sensitive_string(ptr->username); + util_free_sensitive_string(ptr->username); ptr->username = NULL; - free_sensitive_string(ptr->password); + util_free_sensitive_string(ptr->password); ptr->password = NULL; free(ptr->type); ptr->type = NULL; - free_sensitive_string(ptr->server); + util_free_sensitive_string(ptr->server); ptr->server = NULL; free(ptr); diff --git a/src/daemon/modules/image/image_rootfs_handler.c b/src/daemon/modules/image/image_rootfs_handler.c index dd30535..19735f6 100644 --- a/src/daemon/modules/image/image_rootfs_handler.c +++ b/src/daemon/modules/image/image_rootfs_handler.c @@ -41,43 +41,6 @@ #define UnixPasswdPath "/etc/passwd" #define UnixGroupPath "/etc/group" -static void parse_user_group(const char *username, char **user, char **group, char **tmp_dup) -{ - char *tmp = NULL; - char *pdot = NULL; - - if (user == NULL || group == NULL || tmp_dup == NULL) { - return; - } - - if (username != NULL) { - tmp = util_strdup_s(username); - - // for free tmp in caller - *tmp_dup = tmp; - - pdot = strstr(tmp, ":"); - if (pdot != NULL) { - *pdot = '\0'; - if (pdot != tmp) { - // User found - *user = tmp; - } - if (*(pdot + 1) != '\0') { - // group found - *group = pdot + 1; - } - } else { - // No : found - if (*tmp != '\0') { - *user = tmp; - } - } - } - - return; -} - static void uids_gids_range_err_log() { ERROR("uids and gids must be in range 0-%lld", MAXUID); @@ -189,7 +152,7 @@ static int append_additional_gids(gid_t gid, gid_t **additional_gids, size_t *le } } - ret = mem_realloc((void **)&new_gids, new_len * sizeof(gid_t), *additional_gids, (*len) * sizeof(gid_t)); + ret = util_mem_realloc((void **)&new_gids, new_len * sizeof(gid_t), *additional_gids, (*len) * sizeof(gid_t)); if (ret != 0) { ERROR("Out of memory"); return -1; @@ -310,7 +273,7 @@ static int append_additional_groups(const struct group *grp, struct group **grou struct group *new_groups = NULL; size_t new_len = *len + 1; - ret = mem_realloc((void **)&new_groups, new_len * sizeof(struct group), *groups, (*len) * sizeof(struct group)); + ret = util_mem_realloc((void **)&new_groups, new_len * sizeof(struct group), *groups, (*len) * sizeof(struct group)); if (ret != 0) { ERROR("Out of memory"); return -1; @@ -432,7 +395,7 @@ static int read_user_file(const char *basefs, const char *user_path, FILE **stre int64_t filesize = 0; char *real_path = NULL; - if (realpath_in_scope(basefs, user_path, &real_path) < 0) { + if (util_realpath_in_scope(basefs, user_path, &real_path) < 0) { ERROR("user target file '%s' real path must be under '%s'", user_path, basefs); isulad_set_error_message("user target file '%s' real path must be under '%s'", user_path, basefs); ret = -1; @@ -492,7 +455,7 @@ static int get_exec_user(const char *username, FILE *f_passwd, FILE *f_group, de char *matched_username = NULL; // parse user and group by username - parse_user_group(username, &user, &group, &tmp); + util_parse_user_group(username, &user, &group, &tmp); // proc by f_passwd ret = proc_by_fpasswd(f_passwd, user, puser, &matched_username); diff --git a/src/daemon/modules/image/image_spec_merge.c b/src/daemon/modules/image/image_spec_merge.c new file mode 100644 index 0000000..a5d7501 --- /dev/null +++ b/src/daemon/modules/image/image_spec_merge.c @@ -0,0 +1,84 @@ +/****************************************************************************** +* Copyright (c) Huawei Technologies Co., Ltd. 2020. All rights reserved. + * iSulad licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * 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 v2 for more details. +* Author: lifeng +* Create: 2020-10-10 +* Description: provide oci image operator definition +*******************************************************************************/ +#include "image_spec_merge.h" + +#include "utils.h" +#include "isula_libutils/log.h" +#include "err_msg.h" + +int image_spec_merge_env(const char **env, size_t env_len, container_config *container_spec) +{ + int ret = 0; + size_t new_size = 0; + size_t old_size = 0; + size_t i = 0; + size_t j = 0; + char **temp = NULL; + char **im_kv = NULL; + char **custom_kv = NULL; + + if (env == NULL || env_len == 0) { + return 0; + } + + if (env_len > LIST_ENV_SIZE_MAX - container_spec->env_len) { + ERROR("The length of envionment variables is too long, the limit is %lld", LIST_ENV_SIZE_MAX); + isulad_set_error_message("The length of envionment variables is too long, the limit is %lld", + LIST_ENV_SIZE_MAX); + ret = -1; + goto out; + } + new_size = (container_spec->env_len + env_len) * sizeof(char *); + old_size = container_spec->env_len * sizeof(char *); + ret = util_mem_realloc((void **)&temp, new_size, container_spec->env, old_size); + if (ret != 0) { + ERROR("Failed to realloc memory for envionment variables"); + ret = -1; + goto out; + } + + container_spec->env = temp; + for (i = 0; i < env_len; i++) { + bool found = false; + im_kv = util_string_split(env[i], '='); + if (im_kv == NULL) { + continue; + } + + for (j = 0; j < container_spec->env_len; j++) { + custom_kv = util_string_split(container_spec->env[j], '='); + if (custom_kv == NULL) { + continue; + } + if (strcmp(im_kv[0], custom_kv[0]) == 0) { + found = true; + } + util_free_array(custom_kv); + custom_kv = NULL; + if (found) { + break; + } + } + + if (!found) { + container_spec->env[container_spec->env_len] = util_strdup_s(env[i]); + container_spec->env_len++; + } + util_free_array(im_kv); + im_kv = NULL; + } +out: + return ret; +} \ No newline at end of file diff --git a/src/daemon/modules/image/image_spec_merge.h b/src/daemon/modules/image/image_spec_merge.h new file mode 100644 index 0000000..3cc91b0 --- /dev/null +++ b/src/daemon/modules/image/image_spec_merge.h @@ -0,0 +1,30 @@ +/****************************************************************************** +* Copyright (c) Huawei Technologies Co., Ltd. 2020. All rights reserved. + * iSulad licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * 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 v2 for more details. +* Author: lifeng +* Create: 2020-10-10 +* Description: provide isula image rootfs handler definition +*******************************************************************************/ +#ifndef DAEMON_MODULES_IMAGE_SPEC_MERGE_H +#define DAEMON_MODULES_IMAGE_SPEC_MERGE_H + +#include "isula_libutils/container_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int image_spec_merge_env(const char **env, size_t env_len, container_config *container_spec); + +#ifdef __cplusplus +} +#endif + +#endif // DAEMON_MODULES_IMAGE_SPEC_MERGE_H diff --git a/src/daemon/modules/image/oci/oci_common_operators.c b/src/daemon/modules/image/oci/oci_common_operators.c index 6b95e86..967894b 100644 --- a/src/daemon/modules/image/oci/oci_common_operators.c +++ b/src/daemon/modules/image/oci/oci_common_operators.c @@ -125,7 +125,7 @@ static int do_image_time_filter(map_itor *itor, bool is_before_filter, int64_t * goto out; } - if (to_unix_nanos_from_str(image_info->created, &tmp_nanos) != 0) { + if (util_to_unix_nanos_from_str(image_info->created, &tmp_nanos) != 0) { ERROR("Failed to get unix nano from string"); ret = -1; goto out; @@ -176,7 +176,7 @@ static bool image_time_filter(const imagetool_image *src, const struct filters_a } } - if (to_unix_nanos_from_str(src->created, &tmp_nanos) != 0) { + if (util_to_unix_nanos_from_str(src->created, &tmp_nanos) != 0) { ERROR("Failed to get unix nano from string"); goto out; } @@ -316,7 +316,7 @@ static int dup_oci_image_info_by_filters(const imagetool_image *src, const struc new_size = (images_list->images_len + 1) * sizeof(imagetool_image *); old_size = images_list->images_len * sizeof(imagetool_image *); - ret = mem_realloc((void **)(&tmp_images), new_size, images_list->images, old_size); + ret = util_mem_realloc((void **)(&tmp_images), new_size, images_list->images, old_size); if (ret != 0) { ERROR("Failed to realloc memory for append images"); ret = -1; @@ -434,8 +434,8 @@ int oci_status_image(im_status_request *request, im_status_response **response) resolved_name = oci_resolve_image_name(image_ref); if (resolved_name == NULL) { - ERROR("Failed to reslove image name %s", image_ref); - isulad_set_error_message("Failed to reslove image name %s", image_ref); + ERROR("Failed to resolve image name %s", image_ref); + isulad_set_error_message("Failed to resolve image name %s", image_ref); ret = -1; goto pack_response; } diff --git a/src/daemon/modules/image/oci/oci_config_merge.c b/src/daemon/modules/image/oci/oci_config_merge.c index 9b5050f..5fdacd3 100644 --- a/src/daemon/modules/image/oci/oci_config_merge.c +++ b/src/daemon/modules/image/oci/oci_config_merge.c @@ -31,6 +31,7 @@ #include "err_msg.h" #include "utils_array.h" #include "utils_string.h" +#include "image_spec_merge.h" static void oci_image_merge_working_dir(const char *working_dir, container_config *container_spec) { @@ -44,63 +45,16 @@ static void oci_image_merge_working_dir(const char *working_dir, container_confi static int oci_image_merge_env(const oci_image_spec_config *config, container_config *container_spec) { int ret = 0; - size_t new_size = 0; - size_t old_size = 0; - size_t i = 0; - size_t j = 0; - char **temp = NULL; - char **im_kv = NULL; - char **custom_kv = NULL; if (config->env == NULL || config->env_len == 0) { return 0; } - if (config->env_len > LIST_ENV_SIZE_MAX - container_spec->env_len) { - ERROR("The length of envionment variables is too long, the limit is %lld", LIST_ENV_SIZE_MAX); - isulad_set_error_message("The length of envionment variables is too long, the limit is %d", LIST_ENV_SIZE_MAX); + if (image_spec_merge_env((const char **)config->env, config->env_len, container_spec) != 0) { ret = -1; goto out; } - new_size = (container_spec->env_len + config->env_len) * sizeof(char *); - old_size = container_spec->env_len * sizeof(char *); - ret = mem_realloc((void **)&temp, new_size, container_spec->env, old_size); - if (ret != 0) { - ERROR("Failed to realloc memory for envionment variables"); - ret = -1; - goto out; - } - - container_spec->env = temp; - for (i = 0; i < config->env_len; i++) { - bool found = false; - im_kv = util_string_split(config->env[i], '='); - if (im_kv == NULL) { - continue; - } - for (j = 0; j < container_spec->env_len; j++) { - custom_kv = util_string_split(container_spec->env[j], '='); - if (custom_kv == NULL) { - continue; - } - if (strcmp(im_kv[0], custom_kv[0]) == 0) { - found = true; - } - util_free_array(custom_kv); - custom_kv = NULL; - if (found) { - break; - } - } - - if (!found) { - container_spec->env[container_spec->env_len] = util_strdup_s(config->env[i]); - container_spec->env_len++; - } - util_free_array(im_kv); - im_kv = NULL; - } out: return ret; } diff --git a/src/daemon/modules/image/oci/oci_image.c b/src/daemon/modules/image/oci/oci_image.c index b9331c3..f544019 100644 --- a/src/daemon/modules/image/oci/oci_image.c +++ b/src/daemon/modules/image/oci/oci_image.c @@ -53,6 +53,7 @@ static char *format_driver_name(const char *driver) } } +#ifndef LIB_ISULAD_IMG_SO static int do_integration_of_images_check(bool image_layer_check, struct storage_module_init_options *opts) { char *check_file = NULL; @@ -89,6 +90,7 @@ out: free(check_file); return ret; } +#endif // LIB_ISULAD_IMG_SO static int storage_module_init_helper(const isulad_daemon_configs *args) { @@ -123,17 +125,19 @@ static int storage_module_init_helper(const isulad_daemon_configs *args) goto out; } - if (dup_array_of_strings((const char **)args->storage_opts, args->storage_opts_len, &storage_opts->driver_opts, - &storage_opts->driver_opts_len) != 0) { + if (util_dup_array_of_strings((const char **)args->storage_opts, args->storage_opts_len, &storage_opts->driver_opts, + &storage_opts->driver_opts_len) != 0) { ERROR("Failed to get storage storage opts"); ret = -1; goto out; } +#ifndef LIB_ISULAD_IMG_SO if (do_integration_of_images_check(args->image_layer_check, storage_opts) != 0) { ret = -1; goto out; } +#endif // LIB_ISULAD_IMG_SO if (storage_module_init(storage_opts) != 0) { ERROR("Failed to init storage module"); diff --git a/src/daemon/modules/image/oci/oci_import.c b/src/daemon/modules/image/oci/oci_import.c index 0386372..99181cd 100644 --- a/src/daemon/modules/image/oci/oci_import.c +++ b/src/daemon/modules/image/oci/oci_import.c @@ -54,7 +54,7 @@ typedef struct { types_timestamp_t now_time; char *tag; char *layer_file; - char *layer_of_hold_flag; + char *layer_of_hold_refs; } import_desc; static void free_import_desc(import_desc *desc) @@ -81,8 +81,8 @@ static void free_import_desc(import_desc *desc) desc->uncompressed_digest = NULL; free(desc->layer_file); desc->layer_file = NULL; - free(desc->layer_of_hold_flag); - desc->layer_of_hold_flag = NULL; + free(desc->layer_of_hold_refs); + desc->layer_of_hold_refs = NULL; free(desc); @@ -98,7 +98,7 @@ static int register_layer(import_desc *desc) return -1; } - id = without_sha256_prefix(desc->uncompressed_digest); + id = util_without_sha256_prefix(desc->uncompressed_digest); if (id == NULL) { ERROR("Invalid NULL param"); return -1; @@ -114,7 +114,7 @@ static int register_layer(import_desc *desc) if (storage_layer_create(id, &copts) != 0) { return -1; } - desc->layer_of_hold_flag = util_strdup_s(id); + desc->layer_of_hold_refs = util_strdup_s(id); return 0; } @@ -140,7 +140,7 @@ static int create_config(import_desc *desc) return -1; } - ret = normalized_host_os_arch(&host_os, &host_arch, &host_variant); + ret = util_normalized_host_os_arch(&host_os, &host_arch, &host_variant); if (ret != 0) { ERROR("get host os and arch for import failed"); isulad_try_set_error_message("get host os and arch for import failed"); @@ -178,7 +178,7 @@ static int create_config(import_desc *desc) goto out; } - if (!get_time_buffer(&desc->now_time, time_str, TIME_BUF_MAX_LEN)) { + if (!util_get_time_buffer(&desc->now_time, time_str, TIME_BUF_MAX_LEN)) { ERROR("get time string from timestamp failed"); isulad_try_set_error_message("get time string from timestamp failed"); ret = -1; @@ -319,8 +319,8 @@ static int register_image(import_desc *desc) opts.create_time = &desc->now_time; opts.digest = desc->manifest_digest; - image_id = without_sha256_prefix(desc->config_digest); - top_layer_id = without_sha256_prefix(desc->uncompressed_digest); + image_id = util_without_sha256_prefix(desc->config_digest); + top_layer_id = util_without_sha256_prefix(desc->uncompressed_digest); ret = storage_img_create(image_id, top_layer_id, NULL, &opts); if (ret != 0) { pre_top_layer = storage_get_img_top_layer(image_id); @@ -374,12 +374,11 @@ static int register_image(import_desc *desc) } out: - if (desc->layer_of_hold_flag != NULL && - storage_set_hold_flag(desc->layer_of_hold_flag, false) != 0) { - ERROR("clear hold flag failed for layer %s", desc->layer_of_hold_flag); + if (desc->layer_of_hold_refs != NULL && storage_dec_hold_refs(desc->layer_of_hold_refs) != 0) { + ERROR("decrease hold refs failed for layer %s", desc->layer_of_hold_refs); } else { - free(desc->layer_of_hold_flag); - desc->layer_of_hold_flag = NULL; + free(desc->layer_of_hold_refs); + desc->layer_of_hold_refs = NULL; } if (ret != 0 && image_created) { @@ -420,7 +419,7 @@ static import_desc *prepre_import(char *file, char *tag) goto out; } - if (!get_now_time_stamp(&desc->now_time)) { + if (!util_get_now_time_stamp(&desc->now_time)) { ERROR("get time stamp for import failed"); isulad_try_set_error_message("get time stamp for import failed"); ret = -1; @@ -494,9 +493,8 @@ static int do_import(char *file, char *tag) } out: - if (desc->layer_of_hold_flag != NULL && - storage_set_hold_flag(desc->layer_of_hold_flag, false) != 0) { - ERROR("clear hold flag failed for layer %s", desc->layer_of_hold_flag); + if (desc->layer_of_hold_refs != NULL && storage_dec_hold_refs(desc->layer_of_hold_refs) != 0) { + ERROR("decrease hold refs failed for layer %s", desc->layer_of_hold_refs); } free_import_desc(desc); diff --git a/src/daemon/modules/image/oci/oci_load.c b/src/daemon/modules/image/oci/oci_load.c index f7908b6..5511c04 100644 --- a/src/daemon/modules/image/oci/oci_load.c +++ b/src/daemon/modules/image/oci/oci_load.c @@ -200,12 +200,25 @@ static void oci_load_free_image(load_image_t *im) free_oci_image_manifest(im->manifest); - free(im->layer_of_hold_flag); - im->layer_of_hold_flag = NULL; + free(im->layer_of_hold_refs); + im->layer_of_hold_refs = NULL; free(im); } +inline static void do_free_load_image(load_image_t *im) +{ + if (im == NULL) { + return; + } + + if (im->layer_of_hold_refs != NULL && storage_dec_hold_refs(im->layer_of_hold_refs) != 0) { + ERROR("decrease hold refs failed for layer %s", im->layer_of_hold_refs); + } + + oci_load_free_image(im); +} + static char **str_array_copy(char **arr, size_t len) { char **str_arr = NULL; @@ -224,25 +237,6 @@ static char **str_array_copy(char **arr, size_t len) return str_arr; } -static types_timestamp_t oci_load_get_timestamp(char *created) -{ - int64_t nanos = 0; - types_timestamp_t timestamp = { 0 }; - - if (to_unix_nanos_from_str(created, &nanos) != 0) { - ERROR("Failed to get created time from image config"); - goto out; - } - - timestamp.has_seconds = true; - timestamp.seconds = nanos / Time_Second; - timestamp.has_nanos = true; - timestamp.nanos = nanos % Time_Second; - -out: - return timestamp; -} - static char *oci_load_calc_chain_id(char *parent_chain_id, char *diff_id) { int sret = 0; @@ -299,21 +293,31 @@ static char *oci_load_without_sha256_prefix(char *digest) return digest + strlen(SHA256_PREFIX); } -static int oci_load_set_chain_id(load_image_t *image) +static int registry_layer_from_tarball(const load_layer_blob_t *layer, const char *id, const char *parent) { - char *parent_chain_id = ""; - size_t i = 0; + int ret = 0; - for (; i < image->layers_len; i++) { - image->layers[i]->chain_id = oci_load_calc_chain_id(parent_chain_id, image->layers[i]->diff_id); - if (image->layers[i]->chain_id == NULL) { - ERROR("calc chain id failed, diff id %s, parent chain id %s", image->layers[i]->diff_id, parent_chain_id); - return -1; - } - parent_chain_id = image->layers[i]->chain_id; + if (layer == NULL || id == NULL) { + ERROR("Invalid input params"); + return -1; } - return 0; + storage_layer_create_opts_t copts = { + .parent = parent, + .uncompress_digest = layer->diff_id, + .compressed_digest = layer->compressed_digest, + .writable = false, + .layer_data_path = layer->fpath, + }; + + if (storage_layer_create(id, &copts) != 0) { + ERROR("create layer %s failed, parent %s, file %s", id, parent, layer->fpath); + ret = -1; + goto out; + } + +out: + return ret; } static int oci_load_register_layers(load_image_t *desc) @@ -341,22 +345,22 @@ static int oci_load_register_layers(load_image_t *desc) goto out; } - storage_layer_create_opts_t copts = { - .parent = parent, - .uncompress_digest = desc->layers[i]->diff_id, - .compressed_digest = desc->layers[i]->compressed_digest, - .writable = false, - .layer_data_path = desc->layers[i]->fpath, - }; - ret = storage_layer_create(id, &copts); - if (ret != 0) { - ERROR("create layer %s failed, parent %s, file %s", id, parent, desc->layers[i]->fpath); + if (desc->layers[i]->alread_exist) { + DEBUG("Layer:%s is already exist in storage, no need to registry", desc->layers[i]->fpath); + parent = id; + continue; + } + + if (registry_layer_from_tarball(desc->layers[i], id, parent) != 0) { + ERROR("Registry layer:%s from local tarball failed", desc->layers[i]->fpath); + ret = -1; goto out; } - free(desc->layer_of_hold_flag); - desc->layer_of_hold_flag = util_strdup_s(id); - if (parent != NULL && storage_set_hold_flag(parent, false) != 0) { - ERROR("clear hold flag failed for layer %s", parent); + + free(desc->layer_of_hold_refs); + desc->layer_of_hold_refs = util_strdup_s(id); + if (parent != NULL && storage_dec_hold_refs(parent) != 0) { + ERROR("decrease hold refs failed for layer %s", parent); ret = -1; goto out; } @@ -442,7 +446,7 @@ static int oci_load_create_image(load_image_t *desc, const char *dst_tag) goto out; } - timestamp = oci_load_get_timestamp(conf->created); + timestamp = util_to_timestamp_from_str(conf->created); top_layer_index = desc->layers_len - 1; opts.create_time = ×tamp; opts.digest = desc->manifest_digest; @@ -553,7 +557,7 @@ static int oci_load_set_loaded_time(char *image_id) int ret = 0; types_timestamp_t now = { 0 }; - if (!get_now_time_stamp(&now)) { + if (!util_get_now_time_stamp(&now)) { ret = -1; ERROR("get now time stamp failed"); goto out; @@ -623,12 +627,62 @@ out: return ret; } +static int check_and_set_digest_from_tarball(load_layer_blob_t *layer, const char *conf_diff_id) +{ + int ret = 0; + bool gzip = false; + + if (layer == NULL || conf_diff_id == NULL) { + ERROR("Invalid input param"); + return -1; + } + + if (!util_file_exists(layer->fpath)) { + ERROR("Layer data file:%s is not exist", layer->fpath); + isulad_try_set_error_message("%s no such file", layer->fpath); + ret = -1; + goto out; + } + + layer->alread_exist = false; + layer->diff_id = oci_calc_diffid(layer->fpath); + if (layer->diff_id == NULL) { + ERROR("Calc layer:%s diff id failed", layer->fpath); + ret = -1; + goto out; + } + + if (util_gzip_compressed(layer->fpath, &gzip) != 0) { + ERROR("Judge layer file gzip attr err"); + ret = -1; + goto out; + } + + layer->compressed_digest = gzip ? sha256_full_file_digest(layer->fpath) : util_strdup_s(layer->diff_id); + if (layer->compressed_digest == NULL) { + ERROR("Calc layer %s compressed digest failed", layer->fpath); + ret = -1; + goto out; + } + + if (strcmp(layer->diff_id, conf_diff_id) != 0) { + ERROR("invalid diff id for layer:%s: expected %s, got %s", layer->chain_id, conf_diff_id, layer->diff_id); + ret = -1; + goto out; + } + +out: + return ret; +} + static int oci_load_set_layers_info(load_image_t *im, const image_manifest_items_element *manifest, const char *dstdir) { int ret = 0; size_t i = 0; - bool gzip = false; - char *layer_fpath = NULL; + oci_image_spec *conf = NULL; + char *parent_chain_id_sha256 = ""; + char *id = NULL; + char *parent_chain_id = NULL; if (im == NULL || manifest == NULL || dstdir == NULL) { ERROR("Invalid input params image or manifest is null"); @@ -638,12 +692,25 @@ static int oci_load_set_layers_info(load_image_t *im, const image_manifest_items im->layers_len = manifest->layers_len; im->layers = util_common_calloc_s(sizeof(load_layer_blob_t *) * manifest->layers_len); if (im->layers == NULL) { - ret = -1; ERROR("Calloc memory failed"); + ret = -1; goto out; } - for (; i < im->layers_len; i++) { + conf = load_image_config(im->config_fpath); + if (conf == NULL || conf->rootfs == NULL) { + ERROR("Load image config file %s failed", im->config_fpath); + ret = -1; + goto out; + } + + if (conf->rootfs->diff_ids_len != im->layers_len) { + ERROR("Invalid manifest, layers length mismatch: expected %zu, got %zu", im->layers_len, conf->rootfs->diff_ids_len); + ret = -1; + goto out; + } + + for (; i < conf->rootfs->diff_ids_len; i++) { im->layers[i] = util_common_calloc_s(sizeof(load_layer_blob_t)); if (im->layers[i] == NULL) { ERROR("Out of memory"); @@ -651,47 +718,57 @@ static int oci_load_set_layers_info(load_image_t *im, const image_manifest_items goto out; } - layer_fpath = util_path_join(dstdir, manifest->layers[i]); - if (layer_fpath == NULL) { + im->layers[i]->fpath = util_path_join(dstdir, manifest->layers[i]); + if (im->layers[i]->fpath == NULL) { ERROR("Path join failed"); ret = -1; goto out; } - - if (util_gzip_compressed(layer_fpath, &gzip) != 0) { - ERROR("Judge layer file gzip attribute err"); + // The format is sha256:xxx + im->layers[i]->chain_id = oci_load_calc_chain_id(parent_chain_id_sha256, conf->rootfs->diff_ids[i]); + if (im->layers[i]->chain_id == NULL) { + ERROR("calc chain id failed, diff id %s, parent chain id %s", conf->rootfs->diff_ids[i], parent_chain_id_sha256); ret = -1; goto out; } + parent_chain_id_sha256 = im->layers[i]->chain_id; - im->layers[i]->diff_id = oci_calc_diffid(layer_fpath); - if (im->layers[i]->diff_id == NULL) { + id = oci_load_without_sha256_prefix(im->layers[i]->chain_id); + if (id == NULL) { + ERROR("Wipe out sha256 prefix failed from layer with chain id : %s", im->layers[i]->chain_id); ret = -1; - ERROR("Calc layer %s uncompressed digest failed", manifest->layers[i]); goto out; } - im->layers[i]->compressed_digest = gzip ? sha256_full_file_digest(layer_fpath) : - util_strdup_s(im->layers[i]->diff_id); - if (im->layers[i]->compressed_digest == NULL) { - ret = -1; - ERROR("Calc layer %s compressed digest failed", manifest->layers[i]); - goto out; + if (storage_inc_hold_refs(id) == 0) { + free(im->layer_of_hold_refs); + im->layer_of_hold_refs = util_strdup_s(id); + if (parent_chain_id != NULL && storage_dec_hold_refs(parent_chain_id) != 0) { + ERROR("Decrease hold refs failed for layer with chain id:%s", parent_chain_id); + ret = -1; + goto out; + } + + im->layers[i]->diff_id = util_strdup_s(conf->rootfs->diff_ids[i]); + if (im->layers[i]->diff_id == NULL) { + ERROR("Dup layer diff id:%s from conf failed", conf->rootfs->diff_ids[i]); + ret = -1; + goto out; + } + im->layers[i]->alread_exist = true; + parent_chain_id = id; + continue; } - im->layers[i]->fpath = util_strdup_s(layer_fpath); - if (im->layers[i]->fpath == NULL) { + if (check_and_set_digest_from_tarball(im->layers[i], conf->rootfs->diff_ids[i]) != 0) { + ERROR("Check layer digest failed"); ret = -1; - ERROR("Image layer data file path is NULL"); goto out; } - UTIL_FREE_AND_SET_NULL(layer_fpath); } out: - if (layer_fpath != NULL) { - free(layer_fpath); - } + free_oci_image_spec(conf); return ret; } @@ -743,11 +820,6 @@ static load_image_t *oci_load_process_manifest(const image_manifest_items_elemen goto out; } - if (oci_load_set_chain_id(im) != 0) { - ret = -1; - ERROR("Calc image chain id failed"); - } - out: free(config_fpath); free(image_digest); @@ -758,6 +830,38 @@ out: return im; } +static int64_t get_layer_size_from_storage(char *chain_id_pre) +{ + char *id = NULL; + struct layer *l = NULL; + int64_t size = 0; + + if (chain_id_pre == NULL) { + ERROR("Invalid input param"); + return -1; + } + + id = oci_load_without_sha256_prefix(chain_id_pre); + if (id == NULL) { + ERROR("Get chain id failed from value:%s", chain_id_pre); + size = -1; + goto out; + } + + l = storage_layer_get(id); + if (l == NULL) { + ERROR("Layer with chain id:%s is not exist in store", id); + size = -1; + goto out; + } + + size = l->compress_size; + +out: + free_layer(l); + return size; +} + static int oci_load_set_manifest_info(load_image_t *im) { int ret = 0; @@ -811,14 +915,24 @@ static int oci_load_set_manifest_info(load_image_t *im) ERROR("Out of memory"); goto out; } + im->manifest->layers[i]->media_type = util_strdup_s(MediaTypeDockerSchema2LayerGzip); im->manifest->layers[i]->digest = util_strdup_s(im->layers[i]->diff_id); - size = util_file_size(im->layers[i]->fpath); - if (size < 0) { - ERROR("Calc image layer %s size error", im->layers[i]->fpath); - ret = -1; - goto out; + if (im->layers[i]->alread_exist) { + size = get_layer_size_from_storage(im->layers[i]->chain_id); + if (size < 0) { + ERROR("Get image layer:%s size error from local store", im->layers[i]->chain_id); + ret = -1; + goto out; + } + } else { + size = util_file_size(im->layers[i]->fpath); + if (size < 0) { + ERROR("Calc image layer %s size error", im->layers[i]->fpath); + ret = -1; + goto out; + } } im->manifest->layers[i]->size = size; } @@ -831,38 +945,6 @@ out: return ret; } -static int oci_load_check_image_layers(load_image_t *im) -{ - int ret = 0; - size_t i = 0; - oci_image_spec *conf = NULL; - - conf = load_image_config(im->config_fpath); - if (conf == NULL || conf->rootfs == NULL) { - ERROR("Load image config file %s failed", im->config_fpath); - ret = -1; - goto out; - } - - if (conf->rootfs->diff_ids_len != im->layers_len) { - ret = -1; - ERROR("Config file layer numbers are not equal to with image layer numbers"); - goto out; - } - - for (; i < im->layers_len; i++) { - if (strcmp(im->layers[i]->diff_id, conf->rootfs->diff_ids[i]) != 0) { - ERROR("Layer diff id %s check err", im->layers[i]->diff_id); - ret = -1; - goto out; - } - } - -out: - free_oci_image_spec(conf); - return ret; -} - static size_t oci_tag_count(image_manifest_items_element **manifest, size_t manifest_len) { size_t cnt_tags = 0; @@ -1014,14 +1096,6 @@ int oci_do_load(const im_load_request *request) if (oci_load_set_manifest_info(im) != 0) { ERROR("Image %s set manifest info err", im->im_id); - isulad_try_set_error_message("Image %s set manifest info err", im->im_id); - ret = -1; - goto out; - } - - if (oci_load_check_image_layers(im) != 0) { - ERROR("Image %s check err", im->im_id); - isulad_try_set_error_message("Image %s check err", im->im_id); ret = -1; goto out; } @@ -1033,7 +1107,8 @@ int oci_do_load(const im_load_request *request) ret = -1; goto out; } - oci_load_free_image(im); + + do_free_load_image(im); im = NULL; } @@ -1048,13 +1123,7 @@ out: } free(manifest); - if (im != NULL) { - if (im->layer_of_hold_flag != NULL && storage_set_hold_flag(im->layer_of_hold_flag, false) != 0) { - ERROR("clear hold flag failed for layer %s", im->layer_of_hold_flag); - } - - oci_load_free_image(im); - } + do_free_load_image(im); if (reader.close != NULL) { reader.close(reader.context, NULL); diff --git a/src/daemon/modules/image/oci/oci_load.h b/src/daemon/modules/image/oci/oci_load.h index 5fdeb4c..e1e0906 100644 --- a/src/daemon/modules/image/oci/oci_load.h +++ b/src/daemon/modules/image/oci/oci_load.h @@ -33,8 +33,11 @@ typedef struct { char *diff_id; // compressed digest char *compressed_digest; + // with "sha256:" prefix char *chain_id; char *fpath; + // layer already exist in storage + bool alread_exist; } load_layer_blob_t; typedef struct { @@ -49,7 +52,7 @@ typedef struct { char *manifest_digest; types_timestamp_t create_time; oci_image_manifest *manifest; - char *layer_of_hold_flag; + char *layer_of_hold_refs; } load_image_t; int oci_do_load(const im_load_request *request); diff --git a/src/daemon/modules/image/oci/oci_pull.c b/src/daemon/modules/image/oci/oci_pull.c index 21efd34..9d94b66 100644 --- a/src/daemon/modules/image/oci/oci_pull.c +++ b/src/daemon/modules/image/oci/oci_pull.c @@ -63,7 +63,7 @@ static int decode_auth(const char *auth, char **username, char **password) (void)memset(auth_parts[1], 0, strlen(auth_parts[1])); out: - free_sensitive_string((char *)decoded); + util_free_sensitive_string((char *)decoded); decoded = NULL; util_free_array(auth_parts); auth_parts = NULL; @@ -194,8 +194,7 @@ int oci_do_pull_image(const im_pull_request *request, im_pull_response *response image2 = storage_img_get(request->image); if (image == NULL || image2 == NULL) { ERROR("get image %s failed after pulling", request->image); - isulad_set_error_message("Failed to pull image %s with error: image not found after pulling", - request->image); + isulad_set_error_message("Failed to pull image %s with error: image not found after pulling", request->image); ret = -1; goto out; } diff --git a/src/daemon/modules/image/oci/registry/auths.c b/src/daemon/modules/image/oci/registry/auths.c index a6c549c..a7da0c6 100644 --- a/src/daemon/modules/image/oci/registry/auths.c +++ b/src/daemon/modules/image/oci/registry/auths.c @@ -35,12 +35,12 @@ #include "utils_file.h" #include "utils_string.h" -static char *g_auth_path = DEFAULT_AUTH_DIR"/"AUTH_FILE_NAME ; +static char *g_auth_path = DEFAULT_AUTH_DIR "/" AUTH_FILE_NAME; void auths_set_dir(char *auth_dir) { int sret = 0; - char path[PATH_MAX] = {0}; + char path[PATH_MAX] = { 0 }; if (auth_dir == NULL) { return; @@ -109,9 +109,9 @@ static int decode_auth_aes(char *encoded, char **username, char **password) (void)memset(auth_parts[1], 0, strlen(auth_parts[1])); out: - free_sensitive_string((char *)auth); + util_free_sensitive_string((char *)auth); auth = NULL; - free_sensitive_string((char *)decoded); + util_free_sensitive_string((char *)decoded); decoded = NULL; util_free_array(auth_parts); auth_parts = NULL; @@ -164,12 +164,12 @@ static char *encode_auth_aes(char *username, char *password) out: (void)memset(plain_text, 0, strlen(plain_text)); - free_sensitive_string((char*)aes); + util_free_sensitive_string((char *)aes); aes = NULL; - free_sensitive_string(plain_text_base64); + util_free_sensitive_string(plain_text_base64); plain_text_base64 = NULL; if (ret != 0) { - free_sensitive_string(aes_base64); + util_free_sensitive_string(aes_base64); aes_base64 = NULL; } return aes_base64; @@ -307,7 +307,7 @@ out: return ret; } -static int write_auth_file(char *content) +static int ensure_auth_dir_exist() { int ret = 0; char *auths_dir = NULL; @@ -319,17 +319,10 @@ static int write_auth_file(char *content) goto out; } - ret = util_mkdir_p(auths_dir, 0700); + ret = util_mkdir_p(auths_dir, DEFAULT_AUTH_DIR_MODE); if (ret != 0) { - ERROR("mkdir for aeskey failed"); - isulad_try_set_error_message("create direcotry for auths failed"); - goto out; - } - - ret = util_atomic_write_file(g_auth_path, content, strlen(content), AUTH_FILE_MODE); - if (ret != 0) { - ERROR("failed to write auths json to file"); - isulad_try_set_error_message("failed to write auths json to file"); + ERROR("mkdir for auths failed"); + isulad_try_set_error_message("create directory for auths failed"); goto out; } @@ -354,6 +347,11 @@ int auths_save(char *host, char *username, char *password) return -1; } + ret = ensure_auth_dir_exist(); + if (ret != 0) { + goto out; + } + auths = registry_auths_parse_file(g_auth_path, NULL, &err); if (auths == NULL) { auths = util_common_calloc_s(sizeof(registry_auths)); @@ -392,7 +390,7 @@ int auths_save(char *host, char *username, char *password) goto out; } - ret = write_auth_file(json); + ret = util_atomic_write_file(g_auth_path, json, strlen(json), AUTH_FILE_MODE); if (ret != 0) { ERROR("failed to write auths json to file"); goto out; diff --git a/src/daemon/modules/image/oci/registry/auths.h b/src/daemon/modules/image/oci/registry/auths.h index 263b80f..63969ed 100644 --- a/src/daemon/modules/image/oci/registry/auths.h +++ b/src/daemon/modules/image/oci/registry/auths.h @@ -20,6 +20,7 @@ extern "C" { #endif #define DEFAULT_AUTH_DIR "/root/.isulad" +#define DEFAULT_AUTH_DIR_MODE 0700 #define AUTH_FILE_NAME "auths.json" #define AUTH_FILE_MODE 0600 #define MAX_AUTHS_LEN 65536 @@ -37,4 +38,3 @@ int auths_delete(char *host); #endif #endif - diff --git a/src/daemon/modules/image/oci/registry/certs.c b/src/daemon/modules/image/oci/registry/certs.c index 68ad549..9deb8f1 100644 --- a/src/daemon/modules/image/oci/registry/certs.c +++ b/src/daemon/modules/image/oci/registry/certs.c @@ -79,7 +79,7 @@ static int load_certs(const char *path, const char *name, bool use_decrypted_key return -1; } - if (ca_file != NULL && util_has_suffix(name, CA_SUFFIX)) { + if (*ca_file == NULL && util_has_suffix(name, CA_SUFFIX)) { *ca_file = util_path_join(path, name); if (*ca_file == NULL) { ret = -1; @@ -87,7 +87,7 @@ static int load_certs(const char *path, const char *name, bool use_decrypted_key goto out; } goto out; - } else if (cert_file != NULL && *cert_file == NULL && util_has_suffix(name, CLIENT_CERT_SUFFIX)) { + } else if (*cert_file == NULL && *key_file == NULL && util_has_suffix(name, CLIENT_CERT_SUFFIX)) { key_name = corresponding_key_name(name); if (key_name == NULL) { ERROR("find corresponding key name for cert failed"); diff --git a/src/daemon/modules/image/oci/registry/http_request.c b/src/daemon/modules/image/oci/registry/http_request.c index 3fcb9de..b5fcf74 100644 --- a/src/daemon/modules/image/oci/registry/http_request.c +++ b/src/daemon/modules/image/oci/registry/http_request.c @@ -431,7 +431,7 @@ static int setup_common_options(pull_descriptor *desc, struct http_get_options * } if (custom_headers != NULL) { - options->custom_headers = str_array_dup(custom_headers, util_array_len(custom_headers)); + options->custom_headers = util_str_array_dup(custom_headers, util_array_len(custom_headers)); if (options->custom_headers == NULL) { ERROR("dup headers failed"); ret = -1; diff --git a/src/daemon/modules/image/oci/registry/registry.c b/src/daemon/modules/image/oci/registry/registry.c index 77b4d02..2d38ea5 100644 --- a/src/daemon/modules/image/oci/registry/registry.c +++ b/src/daemon/modules/image/oci/registry/registry.c @@ -73,13 +73,15 @@ typedef struct { size_t file_list_len; } cached_layer; -// Share infomation of downloading layers to avoid downloading the same layer. +// Share information of downloading layers to avoid downloading the same layer. typedef struct { pthread_mutex_t mutex; bool mutex_inited; pthread_cond_t cond; bool cond_inited; map_t *cached_layers; + pthread_mutex_t image_mutex; + bool image_mutex_inited; } registry_global; static registry_global *g_shared; @@ -133,7 +135,7 @@ static int parse_manifest_schema1(pull_descriptor *desc) desc->layers[index].empty_layer = v1config->throwaway; free_image_manifest_v1_compatibility(v1config); v1config = NULL; - // Cann't download an empty layer, skip related infomation. + // Cann't download an empty layer, skip related information. if (desc->layers[index].empty_layer) { continue; } @@ -564,7 +566,7 @@ static int register_layers(pull_descriptor *desc) continue; } - id = without_sha256_prefix(desc->layers[i].chain_id); + id = util_without_sha256_prefix(desc->layers[i].chain_id); if (id == NULL) { ERROR("layer %zu have NULL digest for image %s", i, desc->image_name); ret = -1; @@ -609,9 +611,9 @@ static int register_layers(pull_descriptor *desc) ERROR("create layer %s failed, parent %s, file %s", id, parent, desc->layers[i].file); goto out; } - free(desc->layer_of_hold_flag); - desc->layer_of_hold_flag = util_strdup_s(id); - if (parent != NULL && storage_set_hold_flag(parent, false) != 0) { + free(desc->layer_of_hold_refs); + desc->layer_of_hold_refs = util_strdup_s(id); + if (parent != NULL && storage_dec_hold_refs(parent) != 0) { ERROR("clear hold flag failed for layer %s", parent); ret = -1; goto out; @@ -632,7 +634,7 @@ out: static int get_top_layer_index(pull_descriptor *desc, size_t *top_layer_index) { - size_t i = 0; + int i = 0; if (desc == NULL || top_layer_index == NULL) { ERROR("Invalid NULL pointer"); @@ -672,7 +674,7 @@ static int create_image(pull_descriptor *desc, char *image_id, bool *reuse) opts.create_time = &desc->config.create_time; opts.digest = desc->manifest.digest; - top_layer_id = without_sha256_prefix(desc->layers[top_layer_index].chain_id); + top_layer_id = util_without_sha256_prefix(desc->layers[top_layer_index].chain_id); if (top_layer_id == NULL) { ERROR("NULL top layer id found for image %s", desc->image_name); ret = -1; @@ -785,7 +787,7 @@ static int set_loaded_time(pull_descriptor *desc, char *image_id) int ret = 0; types_timestamp_t now = { 0 }; - if (!get_now_time_stamp(&now)) { + if (!util_get_now_time_stamp(&now)) { ret = -1; ERROR("get now time stamp failed"); goto out; @@ -863,7 +865,9 @@ static int register_image(pull_descriptor *desc) goto out; } - image_id = without_sha256_prefix(desc->config.digest); + // lock when create image to make sure image content all exist + mutex_lock(&g_shared->image_mutex); + image_id = util_without_sha256_prefix(desc->config.digest); ret = create_image(desc, image_id, &reuse); if (ret != 0) { ERROR("create image %s failed", desc->image_name); @@ -907,6 +911,7 @@ static int register_image(pull_descriptor *desc) } out: + mutex_unlock(&g_shared->image_mutex); if (ret != 0 && image_created) { if (storage_img_delete(image_id, true)) { @@ -956,7 +961,7 @@ static int parse_docker_config(pull_descriptor *desc) parent_chain_id = desc->layers[i].chain_id; } - desc->config.create_time = created_to_timestamp(config->created); + desc->config.create_time = util_to_timestamp_from_str(config->created); out: @@ -1007,7 +1012,7 @@ static int parse_oci_config(pull_descriptor *desc) parent_chain_id = desc->layers[i].chain_id; } - desc->config.create_time = created_to_timestamp(config->created); + desc->config.create_time = util_to_timestamp_from_str(config->created); out: free_oci_image_spec(config); @@ -1212,6 +1217,8 @@ static int add_fetch_task(thread_fetch_info *info) goto out; } } + // retry get cached layer after some time of unlock + cache = get_cached_layer(info->blob_digest); } ret = add_cached_layer(info->blob_digest, info->file); @@ -1395,15 +1402,15 @@ static int fetch_all(pull_descriptor *desc) for (j = 0; j < list->layers_len; j++) { if ((list->layers[j]->parent == NULL && i == 0) || (parent_chain_id != NULL && list->layers[j]->parent != NULL && - !strcmp(list->layers[j]->parent, without_sha256_prefix(parent_chain_id)) && + !strcmp(list->layers[j]->parent, util_without_sha256_prefix(parent_chain_id)) && strcmp(list->layers[j]->uncompressed_digest, list->layers[j]->compressed_digest))) { - // If can't set hold flag, it means it not exist anymore. - if (storage_set_hold_flag(list->layers[j]->id, true) != 0) { + // If can't set hold refs, it means it not exist anymore. + if (storage_inc_hold_refs(list->layers[j]->id) != 0) { continue; } - free(desc->layer_of_hold_flag); - desc->layer_of_hold_flag = util_strdup_s(list->layers[j]->id); - if (parent_chain_id != NULL && storage_set_hold_flag(parent_chain_id, false) != 0) { + free(desc->layer_of_hold_refs); + desc->layer_of_hold_refs = util_strdup_s(list->layers[j]->id); + if (parent_chain_id != NULL && storage_dec_hold_refs(parent_chain_id) != 0) { continue; } desc->layers[i].already_exist = true; @@ -1541,7 +1548,7 @@ static int create_config_from_v1config(pull_descriptor *desc) goto out; } - desc->config.create_time = created_to_timestamp(config->created); + desc->config.create_time = util_to_timestamp_from_str(config->created); free(err); err = NULL; @@ -1592,7 +1599,7 @@ static bool reuse_image(pull_descriptor *desc) goto out; } - id = without_sha256_prefix(desc->config.digest); + id = util_without_sha256_prefix(desc->config.digest); if (id == NULL) { goto out; } @@ -1795,9 +1802,8 @@ int registry_pull(registry_pull_options *options) INFO("Pull images %s success", options->image_name); out: - if (desc->layer_of_hold_flag != NULL && - storage_set_hold_flag(desc->layer_of_hold_flag, false) != 0) { - ERROR("clear hold flag failed for layer %s", desc->layer_of_hold_flag); + if (desc->layer_of_hold_refs != NULL && storage_dec_hold_refs(desc->layer_of_hold_refs) != 0) { + ERROR("decrease hold refs failed for layer %s", desc->layer_of_hold_refs); } if (desc->blobpath != NULL) { @@ -1859,6 +1865,13 @@ int registry_init(char *auths_dir, char *certs_dir) } g_shared->mutex_inited = true; + ret = pthread_mutex_init(&g_shared->image_mutex, NULL); + if (ret != 0) { + ERROR("Failed to init image mutex for create image"); + goto out; + } + g_shared->image_mutex_inited = true; + ret = pthread_cond_init(&g_shared->cond, NULL); if (ret != 0) { ERROR("Failed to init cond for download info"); @@ -1882,6 +1895,9 @@ out: if (g_shared->mutex_inited) { pthread_mutex_destroy(&g_shared->mutex); } + if (g_shared->image_mutex_inited) { + pthread_mutex_destroy(&g_shared->image_mutex); + } map_free(g_shared->cached_layers); g_shared->cached_layers = NULL; free(g_shared); @@ -1941,9 +1957,9 @@ static void free_registry_auth(registry_auth *auth) if (auth == NULL) { return; } - free_sensitive_string(auth->username); + util_free_sensitive_string(auth->username); auth->username = NULL; - free_sensitive_string(auth->password); + util_free_sensitive_string(auth->password); auth->password = NULL; return; } diff --git a/src/daemon/modules/image/oci/registry/registry_apiv2.c b/src/daemon/modules/image/oci/registry/registry_apiv2.c index 7abca9f..6bc3cd4 100644 --- a/src/daemon/modules/image/oci/registry/registry_apiv2.c +++ b/src/daemon/modules/image/oci/registry/registry_apiv2.c @@ -285,7 +285,7 @@ static int parse_ping_header(pull_descriptor *desc, char *http_head) } } - if (!strings_contains_word(version, "registry/2.0")) { + if (!util_strings_contains_word(version, "registry/2.0")) { ERROR("Docker-Distribution-Api-Version does not contain registry/2.0, it's value is %s." "Registry can not support registry API V2", version); @@ -339,7 +339,7 @@ int registry_pingv2(pull_descriptor *desc, char *protocol) // Sending url // https://registry.isula.org/v2/ INFO("sending ping url: %s", url); - ret = http_request_buf(desc, url, (const char **)headers, &output, HEAD_ONLY); + ret = http_request_buf(desc, url, (const char **)headers, &output, HEAD_BODY); if (ret != 0) { ERROR("http request failed"); goto out; @@ -425,7 +425,7 @@ static int registry_request(pull_descriptor *desc, char *path, char **custom_hea goto out; } - headers = str_array_dup((const char **)custom_headers, util_array_len((const char **)custom_headers)); + headers = util_str_array_dup((const char **)custom_headers, util_array_len((const char **)custom_headers)); if (ret != 0) { ERROR("duplicate custom headers failed"); ret = -1; @@ -717,6 +717,7 @@ static void try_log_resp_body(char *path, char *file) if (size < LXC_LOG_BUFFER_SIZE) { // Max length not exactly, just avoid too long. ERROR("Get %s response message body: %s", path, body); } + free(body); return; } @@ -797,7 +798,7 @@ out: static bool is_variant_same(char *variant1, char *variant2) { - // Compatiable with manifests which didn't have variant + // Compatible with manifests which didn't have variant if (variant1 == NULL || variant2 == NULL) { return true; } @@ -819,7 +820,7 @@ static int select_oci_manifest(oci_image_index *index, char **content_type, char return -1; } - ret = normalized_host_os_arch(&host_os, &host_arch, &host_variant); + ret = util_normalized_host_os_arch(&host_os, &host_arch, &host_variant); if (ret != 0) { ret = -1; goto out; @@ -876,7 +877,7 @@ static int select_docker_manifest(registry_manifest_list *manifests, char **cont return -1; } - ret = normalized_host_os_arch(&host_os, &host_arch, &host_variant); + ret = util_normalized_host_os_arch(&host_os, &host_arch, &host_variant); if (ret != 0) { ret = -1; goto out; @@ -1201,7 +1202,7 @@ int login_to_registry(pull_descriptor *desc) goto out; } - ret = registry_request(desc, path, NULL, NULL, &resp_buffer, HEAD_ONLY, &errcode); + ret = registry_request(desc, path, NULL, NULL, &resp_buffer, HEAD_BODY, &errcode); if (ret != 0) { ERROR("registry: Get %s failed, resp: %s", path, resp_buffer); isulad_try_set_error_message("login to registry for %s failed", desc->host); diff --git a/src/daemon/modules/image/oci/registry_type.c b/src/daemon/modules/image/oci/registry_type.c index cf7360b..c2b6bba 100644 --- a/src/daemon/modules/image/oci/registry_type.c +++ b/src/daemon/modules/image/oci/registry_type.c @@ -78,9 +78,9 @@ void free_pull_desc(pull_descriptor *desc) free(desc->tag); desc->tag = NULL; - free_sensitive_string(desc->username); + util_free_sensitive_string(desc->username); desc->username = NULL; - free_sensitive_string(desc->password); + util_free_sensitive_string(desc->password); desc->password = NULL; free(desc->auths_dir); desc->auths_dir = NULL; @@ -140,8 +140,8 @@ void free_pull_desc(pull_descriptor *desc) desc->layers = NULL; desc->layers_len = 0; - free(desc->layer_of_hold_flag); - desc->layer_of_hold_flag = NULL; + free(desc->layer_of_hold_refs); + desc->layer_of_hold_refs = NULL; free(desc); diff --git a/src/daemon/modules/image/oci/registry_type.h b/src/daemon/modules/image/oci/registry_type.h index 349ddfc..9592587 100644 --- a/src/daemon/modules/image/oci/registry_type.h +++ b/src/daemon/modules/image/oci/registry_type.h @@ -105,7 +105,7 @@ typedef struct { // This is temporary field. Once http request is performed, it is cleared char **headers; - char *layer_of_hold_flag; + char *layer_of_hold_refs; // Image blobs downloaded manifest_blob manifest; diff --git a/src/daemon/modules/image/oci/storage/image_store/image_store.c b/src/daemon/modules/image/oci/storage/image_store/image_store.c index 1d4add9..8b9eea0 100644 --- a/src/daemon/modules/image/oci/storage/image_store/image_store.c +++ b/src/daemon/modules/image/oci/storage/image_store/image_store.c @@ -765,7 +765,7 @@ static int get_layers_from_manifest(const registry_manifest_schema1 *manifest, l layers[index].empty_layer = v1config->throwaway; free_image_manifest_v1_compatibility(v1config); v1config = NULL; - // Cann't download an empty layer, skip related infomation. + // Cann't download an empty layer, skip related information. if (layers[index].empty_layer) { continue; } @@ -777,7 +777,7 @@ static int get_layers_from_manifest(const registry_manifest_schema1 *manifest, l for (j = 0; j < list->layers_len; j++) { if ((list->layers[j]->parent == NULL && index == 0) || (parent_chain_id != NULL && list->layers[j]->parent != NULL && - !strcmp(list->layers[j]->parent, without_sha256_prefix(parent_chain_id)))) { + !strcmp(list->layers[j]->parent, util_without_sha256_prefix(parent_chain_id)))) { layers[index].diff_id = util_strdup_s(list->layers[j]->uncompressed_digest); layers[i].chain_id = util_string_append(list->layers[j]->id, SHA256_PREFIX); parent_chain_id = layers[i].chain_id; @@ -830,11 +830,11 @@ static int update_image_info(types_timestamp_t *created, const char *config_dige free(img->id); img->id = util_strdup_s(config_digest); - (void)get_now_time_buffer(timebuffer, sizeof(timebuffer)); + (void)util_get_now_time_buffer(timebuffer, sizeof(timebuffer)); img->loaded = util_strdup_s(timebuffer); if (created != NULL && (created->has_seconds || created->has_nanos) && - !get_time_buffer(created, timebuffer, sizeof(timebuffer))) { + !util_get_time_buffer(created, timebuffer, sizeof(timebuffer))) { ERROR("Failed to get time buffer"); return -1; } @@ -988,7 +988,7 @@ static int convert_to_v2_image_and_load(const char *path) goto out; } - created = created_to_timestamp(config->created); + created = util_to_timestamp_from_str(config->created); if (update_image_info(&created, config_digest, img) != 0) { ERROR("Failed to update image info"); ret = -1; @@ -1320,10 +1320,10 @@ static storage_image *new_storage_image(const char *id, const char *searchable_d im->layer = util_strdup_s(layer); im->metadata = util_strdup_s(metadata); - (void)get_now_time_buffer(timebuffer, sizeof(timebuffer)); + (void)util_get_now_time_buffer(timebuffer, sizeof(timebuffer)); im->loaded = util_strdup_s(timebuffer); if (time != NULL && (time->has_seconds || time->has_nanos) && - !get_time_buffer(time, timebuffer, sizeof(timebuffer))) { + !util_get_time_buffer(time, timebuffer, sizeof(timebuffer))) { ERROR("Failed to get time buffer"); ret = -1; goto out; @@ -1338,91 +1338,6 @@ out: return im; } -char *image_store_create(const char *id, const char **names, size_t names_len, const char *layer, const char *metadata, - const types_timestamp_t *time, const char *searchable_digest) -{ - int ret = 0; - char *dst_id = NULL; - char **unique_names = NULL; - size_t unique_names_len = 0; - image_t *img = NULL; - storage_image *im = NULL; - - if (g_image_store == NULL) { - ERROR("Image store is not ready"); - return NULL; - } - - if (!image_store_lock(EXCLUSIVE)) { - ERROR("Failed to lock image store with exclusive lock, not allowed to create new images"); - return NULL; - } - - if (id == NULL) { - dst_id = generate_random_image_id(); - } else { - dst_id = util_strdup_s(id); - } - - if (dst_id == NULL) { - ERROR("Out of memory or generate random image id failed"); - ret = -1; - goto out; - } - - if (map_search(g_image_store->byid, (void *)dst_id) != NULL) { - ERROR("ID is already in use: %s", dst_id); - ret = -1; - goto out; - } - - if (util_string_array_unique(names, names_len, &unique_names, &unique_names_len) != 0) { - ERROR("Failed to unique names"); - ret = -1; - goto out; - } - - im = new_storage_image(dst_id, searchable_digest, &unique_names, &unique_names_len, time, layer, metadata); - if (im == NULL) { - ERROR("Failed to generate new storage image"); - ret = -1; - goto out; - } - - img = new_image(im); - if (img == NULL) { - ERROR("Out of memory"); - ret = -1; - goto out; - } - im = NULL; - - if (image_store_append_image(dst_id, searchable_digest, img) != 0) { - ERROR("Failed to append image to image store"); - ret = -1; - goto out; - } - - if (save_image(img->simage) != 0) { - ERROR("Failed to save image"); - ret = -1; - goto out; - } - -out: - if (ret != 0) { - free(dst_id); - dst_id = NULL; - free_storage_image(im); - im = NULL; - free_image_t(img); - img = NULL; - } - util_free_array_by_len(unique_names, unique_names_len); - image_store_unlock(); - return dst_id; -} - static image_t *get_image_for_store_by_prefix(const char *id) { bool ret = true; @@ -1494,40 +1409,6 @@ found: return value; } -char *image_store_lookup(const char *id) -{ - char *image_id = NULL; - image_t *img = NULL; - - if (id == NULL) { - ERROR("Invalid input parameter, id is NULL"); - return NULL; - } - - if (g_image_store == NULL) { - ERROR("Image store is not ready"); - return NULL; - } - - if (!image_store_lock(SHARED)) { - ERROR("Failed to lock image store with shared lock, not allowed to get image id assignments"); - return NULL; - } - - img = lookup(id); - if (img == NULL) { - ERROR("Image not known"); - goto out; - } - - image_id = util_strdup_s(img->simage->id); - -out: - image_ref_dec(img); - image_store_unlock(); - return image_id; -} - static char *get_value_from_json_map_string_string(json_map_string_string *map, const char *key) { size_t i; @@ -1701,6 +1582,130 @@ out: return ret; } +char *image_store_create(const char *id, const char **names, size_t names_len, const char *layer, const char *metadata, + const types_timestamp_t *time, const char *searchable_digest) +{ + int ret = 0; + char *dst_id = NULL; + char **unique_names = NULL; + size_t unique_names_len = 0; + image_t *img = NULL; + storage_image *im = NULL; + + if (g_image_store == NULL) { + ERROR("Image store is not ready"); + return NULL; + } + + if (!image_store_lock(EXCLUSIVE)) { + ERROR("Failed to lock image store with exclusive lock, not allowed to create new images"); + return NULL; + } + + if (id == NULL) { + dst_id = generate_random_image_id(); + } else { + dst_id = util_strdup_s(id); + } + + if (dst_id == NULL) { + ERROR("Out of memory or generate random image id failed"); + ret = -1; + goto out; + } + + if (map_search(g_image_store->byid, (void *)dst_id) != NULL) { + ERROR("ID is already in use: %s", dst_id); + ret = -1; + goto out; + } + + if (util_string_array_unique(names, names_len, &unique_names, &unique_names_len) != 0) { + ERROR("Failed to unique names"); + ret = -1; + goto out; + } + + im = new_storage_image(dst_id, searchable_digest, &unique_names, &unique_names_len, time, layer, metadata); + if (im == NULL) { + ERROR("Failed to generate new storage image"); + ret = -1; + goto out; + } + + img = new_image(im); + if (img == NULL) { + ERROR("Out of memory"); + ret = -1; + goto out; + } + im = NULL; + + if (image_store_append_image(dst_id, searchable_digest, img) != 0) { + ERROR("Failed to append image to image store"); + ret = -1; + goto out; + } + + if (save_image(img->simage) != 0) { + ERROR("Failed to save image"); + if (do_delete_image_info(dst_id) != 0) { + ERROR("Failed to delete image info"); + } + im = NULL; + img = NULL; + ret = -1; + goto out; + } + +out: + if (ret != 0) { + free(dst_id); + dst_id = NULL; + free_storage_image(im); + im = NULL; + free_image_t(img); + img = NULL; + } + util_free_array_by_len(unique_names, unique_names_len); + image_store_unlock(); + return dst_id; +} + +char *image_store_lookup(const char *id) +{ + char *image_id = NULL; + image_t *img = NULL; + + if (id == NULL) { + ERROR("Invalid input parameter, id is NULL"); + return NULL; + } + + if (g_image_store == NULL) { + ERROR("Image store is not ready"); + return NULL; + } + + if (!image_store_lock(SHARED)) { + ERROR("Failed to lock image store with shared lock, not allowed to get image id assignments"); + return NULL; + } + + img = lookup(id); + if (img == NULL) { + ERROR("Image not known"); + goto out; + } + + image_id = util_strdup_s(img->simage->id); + +out: + image_ref_dec(img); + image_store_unlock(); + return image_id; +} + int image_store_delete(const char *id) { int ret = 0; @@ -1812,7 +1817,7 @@ static int append_big_data_name(storage_image *im, const char *name) old_size = im->big_data_names_len * sizeof(char *); new_size = old_size + sizeof(char *); - if (mem_realloc((void **)&tmp_names, new_size, (void *)im->big_data_names, old_size) != 0) { + if (util_mem_realloc((void **)&tmp_names, new_size, (void *)im->big_data_names, old_size) != 0) { ERROR("Failed to realloc memory"); return -1; } @@ -2007,7 +2012,7 @@ static int append_name(char ***names, size_t *names_len, const char *name) old_size = *names_len * sizeof(char *); new_size = old_size + sizeof(char *); - if (mem_realloc((void **)&tmp_names, new_size, (void *)*names, old_size) != 0) { + if (util_mem_realloc((void **)&tmp_names, new_size, (void *)*names, old_size) != 0) { ERROR("Failed to realloc memory"); return -1; } @@ -2052,7 +2057,7 @@ int image_store_add_name(const char *id, const char *name) goto out; } - if (dup_array_of_strings((const char **)img->simage->names, img->simage->names_len, &names, &names_len) != 0) { + if (util_dup_array_of_strings((const char **)img->simage->names, img->simage->names_len, &names, &names_len) != 0) { ERROR("Out of memory"); ret = -1; goto out; @@ -2234,7 +2239,8 @@ int image_store_get_names(const char *id, char ***names, size_t *names_len) goto out; } - ret = dup_array_of_strings((const char **)img->simage->names, img->simage->names_len, &tmp_names, &tmp_names_len); + ret = util_dup_array_of_strings((const char **)img->simage->names, img->simage->names_len, &tmp_names, + &tmp_names_len); if (ret != 0) { ERROR("Out of memory"); goto out; @@ -2322,7 +2328,7 @@ int image_store_set_load_time(const char *id, const types_timestamp_t *time) goto out; } - if (!get_time_buffer(time, timebuffer, sizeof(timebuffer))) { + if (!util_get_time_buffer(time, timebuffer, sizeof(timebuffer))) { ERROR("Failed to get time buffer"); ret = -1; goto out; @@ -2414,7 +2420,7 @@ char *image_store_big_data(const char *id, const char *key) goto out; } - content = isula_utils_read_file(filename); + content = util_read_content_from_file(filename); out: image_ref_dec(img); @@ -2620,8 +2626,8 @@ int image_store_big_data_names(const char *id, char ***names, size_t *names_len) goto out; } - if (dup_array_of_strings((const char **)img->simage->big_data_names, img->simage->big_data_names_len, names, - names_len) != 0) { + if (util_dup_array_of_strings((const char **)img->simage->big_data_names, img->simage->big_data_names_len, names, + names_len) != 0) { ERROR("Failed to dup image's names"); ret = -1; goto out; @@ -3014,43 +3020,6 @@ out: return ret; } -static void parse_user_group(const char *username, char **user, char **group, char **tmp_dup) -{ - char *tmp = NULL; - char *pdot = NULL; - - if (user == NULL || group == NULL || tmp_dup == NULL) { - return; - } - - if (username != NULL) { - tmp = util_strdup_s(username); - - // for free tmp in caller - *tmp_dup = tmp; - - pdot = strstr(tmp, ":"); - if (pdot != NULL) { - *pdot = '\0'; - if (pdot != tmp) { - // User found - *user = tmp; - } - if (*(pdot + 1) != '\0') { - // group found - *group = pdot + 1; - } - } else { - // No : found - if (*tmp != '\0') { - *user = tmp; - } - } - } - - return; -} - static int pack_health_check_from_image(const docker_image_config_v2 *config_v2, imagetool_image *info) { int ret = 0; @@ -3106,7 +3075,7 @@ static int pack_user_info_from_image(const docker_image_config_v2 *config_v2, im } // parse user and group by username - parse_user_group(config_v2->config->user, &user, &group, &tmp); + util_parse_user_group(config_v2->config->user, &user, &group, &tmp); if (user == NULL) { ERROR("Failed to parse user"); @@ -3114,6 +3083,14 @@ static int pack_user_info_from_image(const docker_image_config_v2 *config_v2, im goto out; } if (util_safe_llong(user, &converted) == 0) { + if (info->uid == NULL) { + info->uid = (imagetool_image_uid *)util_common_calloc_s(sizeof(imagetool_image_uid)); + if (info->uid == NULL) { + ERROR("Out of memory"); + ret = -1; + goto out; + } + } info->uid->value = (int64_t)converted; } else { info->username = util_strdup_s(user); @@ -3366,7 +3343,7 @@ int image_store_get_fs_info(imagetool_fs_info *fs_info) goto out; } - fs_usage_tmp->timestamp = get_now_time_nanos(); + fs_usage_tmp->timestamp = util_get_now_time_nanos(); fs_usage_tmp->fs_id = util_common_calloc_s(sizeof(imagetool_fs_info_image_filesystems_fs_id)); if (fs_usage_tmp->fs_id == NULL) { diff --git a/src/daemon/modules/image/oci/storage/layer_store/graphdriver/devmapper/deviceset.c b/src/daemon/modules/image/oci/storage/layer_store/graphdriver/devmapper/deviceset.c index 11523a3..fb2f502 100644 --- a/src/daemon/modules/image/oci/storage/layer_store/graphdriver/devmapper/deviceset.c +++ b/src/daemon/modules/image/oci/storage/layer_store/graphdriver/devmapper/deviceset.c @@ -2842,10 +2842,12 @@ free_out: static char *generate_mount_options(const struct driver_mount_opts *moptions, const char *dev_options) { char *res_str = NULL; - char *tmp = NULL; append_mount_options(&res_str, dev_options); +#ifdef ENABLE_SELINX if (moptions != NULL && moptions->mount_label != NULL) { + char *tmp = NULL; + tmp = selinux_format_mountlabel(res_str, moptions->mount_label); if (tmp == NULL) { goto error_out; @@ -2854,7 +2856,6 @@ static char *generate_mount_options(const struct driver_mount_opts *moptions, co res_str = tmp; tmp = NULL; } - goto out; error_out: @@ -2862,6 +2863,7 @@ error_out: res_str = NULL; out: +#endif return res_str; } @@ -3306,4 +3308,4 @@ void free_device_set(struct device_set *devset) UTIL_FREE_AND_SET_NULL(devset->base_device_filesystem); free(devset); -} \ No newline at end of file +} diff --git a/src/daemon/modules/image/oci/storage/layer_store/graphdriver/driver.c b/src/daemon/modules/image/oci/storage/layer_store/graphdriver/driver.c index 5fb8b90..f2df4f8 100644 --- a/src/daemon/modules/image/oci/storage/layer_store/graphdriver/driver.c +++ b/src/daemon/modules/image/oci/storage/layer_store/graphdriver/driver.c @@ -8,8 +8,8 @@ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR * PURPOSE. * See the Mulan PSL v2 for more details. - * Author: tanyifeng - * Create: 2017-11-22 + * Author: lifeng + * Create: 2020-04-22 * Description: provide image functions ******************************************************************************/ diff --git a/src/daemon/modules/image/oci/storage/layer_store/graphdriver/driver.h b/src/daemon/modules/image/oci/storage/layer_store/graphdriver/driver.h index 58eae32..7faf70c 100644 --- a/src/daemon/modules/image/oci/storage/layer_store/graphdriver/driver.h +++ b/src/daemon/modules/image/oci/storage/layer_store/graphdriver/driver.h @@ -8,8 +8,8 @@ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR * PURPOSE. * See the Mulan PSL v2 for more details. - * Author: tanyifeng - * Create: 2019-04-02 + * Author: lifeng + * Create: 2020-04-22 * Description: provide graphdriver function definition ******************************************************************************/ #ifndef DAEMON_MODULES_IMAGE_OCI_STORAGE_LAYER_STORE_GRAPHDRIVER_DRIVER_H @@ -98,7 +98,8 @@ struct graphdriver { // options for device mapper struct device_set *devset; - pthread_rwlock_t rwlock; // lock to protect graphdriver between cleanup and other operations + // lock to protect graphdriver between cleanup and other operations + pthread_rwlock_t rwlock; }; int graphdriver_init(const struct storage_module_init_options *opts); diff --git a/src/daemon/modules/image/oci/storage/layer_store/graphdriver/overlay2/driver_overlay2.c b/src/daemon/modules/image/oci/storage/layer_store/graphdriver/overlay2/driver_overlay2.c index c81c4bc..95909a8 100644 --- a/src/daemon/modules/image/oci/storage/layer_store/graphdriver/overlay2/driver_overlay2.c +++ b/src/daemon/modules/image/oci/storage/layer_store/graphdriver/overlay2/driver_overlay2.c @@ -8,8 +8,8 @@ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR * PURPOSE. * See the Mulan PSL v2 for more details. - * Author: tanyifeng - * Create: 2019-04-02 + * Author: lifeng + * Create: 2020-04-02 * Description: provide overlay2 function definition ******************************************************************************/ #include "driver_overlay2.h" @@ -275,6 +275,7 @@ int overlay2_init(struct graphdriver *driver, const char *drvier_home, const cha char *root_dir = NULL; if (driver == NULL || drvier_home == NULL) { + ERROR("Invalid input arguments"); return -1; } @@ -427,7 +428,7 @@ static int do_diff_symlink(const char *id, char *link_id, const char *driver_hom goto out; } - if (cleanpath(link_path, clean_path, sizeof(clean_path)) == NULL) { + if (util_clean_path(link_path, clean_path, sizeof(clean_path)) == NULL) { ERROR("failed to get clean path %s", link_path); ret = -1; goto out; @@ -682,7 +683,7 @@ out: return ret; } -static int mk_sub_directorys(const char *id, const char *parent, const char *layer_dir, const char *driver_home) +static int mk_sub_directories(const char *id, const char *parent, const char *layer_dir, const char *driver_home) { int ret = 0; char *lowers = NULL; @@ -802,11 +803,11 @@ static int do_create(const char *id, const char *parent, const struct graphdrive if (set_layer_quota(layer_dir, create_opts->storage_opt, driver) != 0) { ERROR("Unable to set layer quota %s", layer_dir); ret = -1; - goto out; + goto err_out; } } - if (mk_sub_directorys(id, parent, layer_dir, driver->home) != 0) { + if (mk_sub_directories(id, parent, layer_dir, driver->home) != 0) { ret = -1; goto err_out; } @@ -874,6 +875,7 @@ int overlay2_create_rw(const char *id, const char *parent, const struct graphdri int ret = 0; if (id == NULL || driver == NULL || create_opts == NULL) { + ERROR("Invalid input arguments"); return -1; } @@ -899,22 +901,17 @@ out: int overlay2_create_ro(const char *id, const char *parent, const struct graphdriver *driver, const struct driver_create_opts *create_opts) { - int ret = 0; - if (id == NULL || driver == NULL || create_opts == NULL) { + ERROR("Invalid input arguments"); return -1; } if (create_opts->storage_opt != NULL && create_opts->storage_opt->len != 0) { ERROR("--storage-opt size is only supported for ReadWrite Layers"); - ret = -1; - goto out; + return -1; } - ret = do_create(id, parent, driver, create_opts); - -out: - return ret; + return do_create(id, parent, driver, create_opts); } static char *read_layer_link_file(const char *layer_dir) @@ -961,6 +958,7 @@ int overlay2_rm_layer(const char *id, const struct graphdriver *driver) char clean_path[PATH_MAX] = { 0 }; if (id == NULL || driver == NULL) { + ERROR("Invalid input arguments"); return -1; } @@ -979,7 +977,7 @@ int overlay2_rm_layer(const char *id, const struct graphdriver *driver) ret = -1; goto out; } - if (cleanpath(link_path, clean_path, sizeof(clean_path)) == NULL) { + if (util_clean_path(link_path, clean_path, sizeof(clean_path)) == NULL) { ERROR("failed to get clean path %s", link_path); ret = -1; goto out; @@ -1262,6 +1260,7 @@ static char *get_abs_mount_opt_data(const char *layer_dir, const char *abs_lower tmp = NULL; } +#ifdef ENABLE_SELINUX if (mount_opts != NULL && mount_opts->mount_label != NULL) { tmp = selinux_format_mountlabel(mount_data, mount_opts->mount_label); if (tmp == NULL) { @@ -1271,6 +1270,7 @@ static char *get_abs_mount_opt_data(const char *layer_dir, const char *abs_lower mount_data = tmp; tmp = NULL; } +#endif goto out; @@ -1344,6 +1344,7 @@ static char *get_rel_mount_opt_data(const char *id, const char *rel_lower_dir, c tmp = NULL; } +#ifdef ENABLE_SELINUX if (mount_opts != NULL && mount_opts->mount_label != NULL) { tmp = selinux_format_mountlabel(mount_data, mount_opts->mount_label); if (tmp == NULL) { @@ -1353,6 +1354,7 @@ static char *get_rel_mount_opt_data(const char *id, const char *rel_lower_dir, c mount_data = tmp; tmp = NULL; } +#endif goto out; @@ -1494,6 +1496,7 @@ char *overlay2_mount_layer(const char *id, const struct graphdriver *driver, con char *layer_dir = NULL; if (id == NULL || driver == NULL) { + ERROR("Invalid input arguments"); return NULL; } @@ -1526,6 +1529,7 @@ int overlay2_umount_layer(const char *id, const struct graphdriver *driver) char *layer_dir = NULL; if (id == NULL || driver == NULL) { + ERROR("Invalid input arguments"); return -1; } @@ -1815,6 +1819,7 @@ int overlay2_get_driver_status(const struct graphdriver *driver, struct graphdri char tmp[MAX_INFO_LENGTH] = { 0 }; if (driver == NULL || status == NULL) { + ERROR("Invalid input arguments"); return -1; } @@ -1856,6 +1861,7 @@ int overlay2_clean_up(struct graphdriver *driver) int ret = 0; if (driver == NULL) { + ERROR("Invalid input arguments"); ret = -1; goto out; } @@ -1901,6 +1907,7 @@ int overlay2_repair_lowers(const char *id, const char *parent, const struct grap size_t lowers_size = 0; if (id == NULL || driver == NULL) { + ERROR("Invalid input arguments"); return -1; } @@ -1966,7 +1973,7 @@ static int do_cal_layer_fs_info(const char *layer_diff, imagetool_fs_info *fs_in goto out; } - fs_usage_tmp->timestamp = get_now_time_nanos(); + fs_usage_tmp->timestamp = util_get_now_time_nanos(); fs_usage_tmp->fs_id = util_common_calloc_s(sizeof(imagetool_fs_info_image_filesystems_fs_id)); if (fs_usage_tmp->fs_id == NULL) { @@ -2016,6 +2023,7 @@ int overlay2_get_layer_fs_info(const char *id, const struct graphdriver *driver, char *layer_diff = NULL; if (id == NULL || fs_info == NULL) { + ERROR("Invalid input arguments"); return -1; } diff --git a/src/daemon/modules/image/oci/storage/layer_store/graphdriver/overlay2/driver_overlay2.h b/src/daemon/modules/image/oci/storage/layer_store/graphdriver/overlay2/driver_overlay2.h index 8e2c30b..5f3228f 100644 --- a/src/daemon/modules/image/oci/storage/layer_store/graphdriver/overlay2/driver_overlay2.h +++ b/src/daemon/modules/image/oci/storage/layer_store/graphdriver/overlay2/driver_overlay2.h @@ -8,7 +8,7 @@ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR * PURPOSE. * See the Mulan PSL v2 for more details. - * Author: tanyifeng + * Author: lifeng * Create: 2019-04-02 * Description: provide overlay2 function definition ******************************************************************************/ diff --git a/src/daemon/modules/image/oci/storage/layer_store/graphdriver/quota/project_quota.c b/src/daemon/modules/image/oci/storage/layer_store/graphdriver/quota/project_quota.c index 8efe709..2bcfb0e 100644 --- a/src/daemon/modules/image/oci/storage/layer_store/graphdriver/quota/project_quota.c +++ b/src/daemon/modules/image/oci/storage/layer_store/graphdriver/quota/project_quota.c @@ -321,7 +321,7 @@ void free_pquota_control(struct pquota_control *ctrl) ctrl->backing_fs_device = NULL; if (pthread_rwlock_destroy(&(ctrl->rwlock)) != 0) { - SYSERROR("destory pquota_control rwlock failed"); + SYSERROR("destroy pquota_control rwlock failed"); } free(ctrl); } @@ -334,7 +334,7 @@ static int get_quota_stat(const char *backing_fs_blockdev) ret = quotactl(QCMD(Q_XGETQSTAT, FS_PROJ_QUOTA), backing_fs_blockdev, 0, (caddr_t)&fs_quota_stat_info); if (ret != 0) { - SYSERROR("Failed to get quota stat on %s", backing_fs_blockdev); + SYSWARN("Failed to get quota stat on %s", backing_fs_blockdev); return ret; } diff --git a/src/daemon/modules/image/oci/storage/layer_store/layer.h b/src/daemon/modules/image/oci/storage/layer_store/layer.h index d86e02e..f2dad64 100644 --- a/src/daemon/modules/image/oci/storage/layer_store/layer.h +++ b/src/daemon/modules/image/oci/storage/layer_store/layer.h @@ -38,7 +38,7 @@ typedef struct _layer_t_ { char *mount_point_json_path; storage_mount_point *smount_point; - bool hold; + int hold_refs_num; uint64_t refcnt; } layer_t; diff --git a/src/daemon/modules/image/oci/storage/layer_store/layer_store.c b/src/daemon/modules/image/oci/storage/layer_store/layer_store.c index 934ec35..704dbd6 100644 --- a/src/daemon/modules/image/oci/storage/layer_store/layer_store.c +++ b/src/daemon/modules/image/oci/storage/layer_store/layer_store.c @@ -556,7 +556,7 @@ static int update_layer_datas(const char *id, const struct layer_opts *opts, lay if (opts->opts != NULL) { slayer->mountlabel = util_strdup_s(opts->opts->mount_label); } - if (!get_now_local_utc_time_buffer(timebuffer, TIME_STR_SIZE)) { + if (!util_get_now_local_utc_time_buffer(timebuffer, TIME_STR_SIZE)) { ERROR("Get create time failed"); ret = -1; goto free_out; @@ -738,7 +738,7 @@ out: static int insert_memory_stores(const char *id, const struct layer_opts *opts, layer_t *l) { int ret = 0; - size_t i = 0; + int i = 0; if (!append_layer_into_list(l)) { ret = -1; @@ -863,7 +863,9 @@ static char *caculate_playload(struct archive *ar) int nret = 0; const isula_crc_table_t *ctab = NULL; uint64_t crc = 0; + // max crc bits is 8 unsigned char sum_data[8] = { 0 }; + // add \0 at crc bits last, so need a 9 bits array unsigned char tmp_data[9] = { 0 }; bool empty = true; @@ -893,6 +895,7 @@ static char *caculate_playload(struct archive *ar) } isula_crc_sum(crc, sum_data); + // max crc bits is 8 for (r = 0; r < 8; r++) { tmp_data[r] = sum_data[r]; } @@ -1004,12 +1007,6 @@ out: static int make_tar_split_file(const char *lid, const struct io_read_wrapper *diff, int64_t *size) { - /* - * step 1: read header; - * step 2: build entry json; - * step 3: write into tar split; - * step 4: gzip tar split, and save file. - * */ int *pfd = (int *)diff->context; char *save_fname = NULL; char *save_fname_gz = NULL; @@ -1024,6 +1021,7 @@ static int make_tar_split_file(const char *lid, const struct io_read_wrapper *di if (save_fname_gz == NULL) { goto out; } + // step 1: read header; tfd = util_open(save_fname, O_WRONLY | O_CREAT, SECURE_CONFIG_FILE_MODE); if (tfd == -1) { SYSERROR("touch file failed"); @@ -1032,6 +1030,8 @@ static int make_tar_split_file(const char *lid, const struct io_read_wrapper *di close(tfd); tfd = -1; + // step 2: build entry json; + // step 3: write into tar split; ret = foreach_archive_entry(archive_entry_parse, *pfd, save_fname, size); if (ret != 0) { goto out; @@ -1042,7 +1042,7 @@ static int make_tar_split_file(const char *lid, const struct io_read_wrapper *di goto out; } - // gzip tar split file + // step 4: gzip tar split, and save file. ret = util_gzip_z(save_fname, save_fname_gz, SECURE_CONFIG_FILE_MODE); // always remove tmp tar split file, even though gzip failed. @@ -1153,28 +1153,32 @@ static int layer_store_remove_layer(const char *id) return ret; } -int layer_set_hold_flag(const char *layer_id, bool hold) +int layer_set_hold_refs(const char *layer_id, bool increase) { layer_t *l = NULL; int ret = 0; if (layer_id == NULL) { - ERROR("Invalid NULL layer id when reset hold flag"); + ERROR("Invalid NULL layer id when set hold refs"); return -1; } if (!layer_store_lock(true)) { - ERROR("Failed to lock layer store, reset hold flag for layer %s failed", layer_id); + ERROR("Failed to lock layer store, reset hold refs for layer %s failed", layer_id); return -1; } l = map_search(g_metadata.by_id, (void *)layer_id); if (l == NULL) { - ERROR("layer %s not found when reset hold flag", layer_id); + ERROR("layer %s not found when set hold refs", layer_id); ret = -1; goto out; } - l->hold = hold; + if (increase) { + l->hold_refs_num++; + } else { + l->hold_refs_num--; + } out: layer_store_unlock(); @@ -1182,28 +1186,38 @@ out: return ret; } -int layer_get_hold_flag(const char *layer_id, bool *hold) +int layer_inc_hold_refs(const char *layer_id) +{ + return layer_set_hold_refs(layer_id, true); +} + +int layer_dec_hold_refs(const char *layer_id) +{ + return layer_set_hold_refs(layer_id, false); +} + +int layer_get_hold_refs(const char *layer_id, int *refs_num) { int ret = 0; layer_t *l = NULL; - if (layer_id == NULL || hold == NULL) { - ERROR("Invalid NULL param when get hold flag"); + if (layer_id == NULL || refs_num == NULL) { + ERROR("Invalid NULL param when get hold refs"); return -1; } if (!layer_store_lock(true)) { - ERROR("Failed to lock layer store, get hold flag of layer %s failed", layer_id); + ERROR("Failed to lock layer store, get hold refs of layer %s failed", layer_id); return -1; } l = map_search(g_metadata.by_id, (void *)layer_id); if (l == NULL) { - ERROR("layer %s not found when reset hold flag", layer_id); + ERROR("layer %s not found when get hold refs", layer_id); ret = -1; goto out; } - *hold = l->hold; + *refs_num = l->hold_refs_num; out: layer_store_unlock(); @@ -1214,7 +1228,7 @@ out: int layer_store_create(const char *id, const struct layer_opts *opts, const struct io_read_wrapper *diff, char **new_id) { int ret = 0; - char *lid = util_strdup_s(id); + char *lid = NULL; layer_t *l = NULL; if (opts == NULL) { @@ -1226,10 +1240,12 @@ int layer_store_create(const char *id, const struct layer_opts *opts, const stru return -1; } - // If the layer already exist, hold the layer is enough + lid = util_strdup_s(id); + + // If the layer already exist, increase refs number to hold the layer is enough l = lookup(lid); if (l != NULL) { - l->hold = true; // mark it as hold, so others can't delete this layer + l->hold_refs_num++; // increase refs number, so others can't delete this layer goto free_out; } @@ -1246,12 +1262,12 @@ int layer_store_create(const char *id, const struct layer_opts *opts, const stru l = lookup(lid); if (l == NULL) { ret = -1; - goto driver_remove; + goto clear_memory; } l->slayer->incompelte = true; if (save_layer(l) != 0) { ret = -1; - goto driver_remove; + goto clear_memory; } ret = apply_diff(l, diff); @@ -1272,7 +1288,7 @@ int layer_store_create(const char *id, const struct layer_opts *opts, const stru *new_id = lid; lid = NULL; } - l->hold = true; // mark it as hold, so others can't delete this layer + l->hold_refs_num++; // increase refs number, so others can't delete this layer goto free_out; } ERROR("Save layer failed"); @@ -1600,8 +1616,8 @@ int layer_store_umount(const char *id, bool force) } l = lookup_with_lock(id); if (l == NULL) { - ERROR("layer not known"); - return -1; + ERROR("layer not known,skip umount"); + return 0; } layer_lock(l); ret = umount_helper(l, force); @@ -1724,7 +1740,7 @@ out: return ret; } -static bool load_layer_json_cb(const char *path_name, const struct dirent *sub_dir) +static bool load_layer_json_cb(const char *path_name, const struct dirent *sub_dir, void *context) { #define LAYER_NAME_LEN 64 bool flag = false; @@ -1814,7 +1830,7 @@ static int load_layers_from_json_files() return -1; } - ret = util_scan_subdirs(g_root_dir, load_layer_json_cb); + ret = util_scan_subdirs(g_root_dir, load_layer_json_cb, NULL); if (ret != 0) { goto unlock_out; } @@ -1968,7 +1984,7 @@ static uint64_t payload_to_crc(char *payload) return crc; } -static int file_crc(char *file, uint64_t *crc, uint64_t policy) +static int file_crc64(char *file, uint64_t *crc, uint64_t policy) { #define BLKSIZE 32768 int ret = 0; @@ -2023,7 +2039,7 @@ out: return ret; } -static int valid_crc(storage_entry *entry, char *rootfs) +static int valid_crc64(storage_entry *entry, char *rootfs) { int ret = 0; int nret = 0; @@ -2058,7 +2074,7 @@ static int valid_crc(storage_entry *entry, char *rootfs) goto out; } - ret = file_crc(file, &crc, ISO_POLY); + ret = file_crc64(file, &crc, ISO_POLY); if (ret != 0) { ERROR("calc crc of file %s failed", file); ret = -1; @@ -2204,7 +2220,7 @@ static int do_integration_check(layer_t *l, char *rootfs) } while (entry != NULL) { if (entry->type == STORAGE_ENTRY_TYPE_CRC) { - ret = valid_crc(entry, rootfs); + ret = valid_crc64(entry, rootfs); if (ret != 0) { ERROR("integration check failed, layer %s, file %s", l->slayer->id, entry->name); goto out; diff --git a/src/daemon/modules/image/oci/storage/layer_store/layer_store.h b/src/daemon/modules/image/oci/storage/layer_store/layer_store.h index f025f0f..94d4bf0 100644 --- a/src/daemon/modules/image/oci/storage/layer_store/layer_store.h +++ b/src/daemon/modules/image/oci/storage/layer_store/layer_store.h @@ -57,8 +57,9 @@ void layer_store_cleanup(); void remove_layer_list_tail(); int layer_store_create(const char *id, const struct layer_opts *opts, const struct io_read_wrapper *content, char **new_id); -int layer_set_hold_flag(const char *layer_id, bool hold); -int layer_get_hold_flag(const char *layer_id, bool *hold); +int layer_inc_hold_refs(const char *layer_id); +int layer_dec_hold_refs(const char *layer_id); +int layer_get_hold_refs(const char *layer_id, int *ref_num); int layer_store_delete(const char *id); bool layer_store_exists(const char *id); int layer_store_list(struct layer_list *resp); diff --git a/src/daemon/modules/image/oci/storage/rootfs_store/rootfs_store.c b/src/daemon/modules/image/oci/storage/rootfs_store/rootfs_store.c index 22a194c..ed4b45c 100644 --- a/src/daemon/modules/image/oci/storage/rootfs_store/rootfs_store.c +++ b/src/daemon/modules/image/oci/storage/rootfs_store/rootfs_store.c @@ -211,15 +211,15 @@ static int get_containers_from_json() ret = util_list_all_subdir(g_rootfs_store->dir, &container_dirs); if (ret != 0) { - ERROR("Failed to get container directorys"); + ERROR("Failed to get container directories"); goto out; } container_dirs_num = util_array_len((const char **)container_dirs); for (i = 0; i < container_dirs_num; i++) { if (util_reg_match(id_patten, container_dirs[i]) != 0) { - DEBUG("Container's json is placed inside container's data directory, so skip any other file or directory: %s", - container_dirs[i]); + WARN("Container's json is placed inside container's data directory, so skip any other file or directory: %s", + container_dirs[i]); continue; } @@ -227,14 +227,15 @@ static int get_containers_from_json() nret = snprintf(container_path, sizeof(container_path), "%s/%s", g_rootfs_store->dir, container_dirs[i]); if (nret < 0 || (size_t)nret >= sizeof(container_path)) { ERROR("Failed to get container path"); - ret = -1; - goto out; + continue; } if (append_container_by_directory(container_path) != 0) { - ERROR("Found container path but load json failed: %s", container_dirs[i]); - ret = -1; - goto out; + ERROR("Found container path but load json failed: %s, deleting...", container_path); + if (util_recursive_rmdir(container_path, 0) != 0) { + ERROR("Failed to delete rootfs directory : %s", container_path); + } + continue; } } @@ -367,7 +368,7 @@ static int load_container_to_store_field(cntrootfs_t *cntr) should_save = true; } if (!map_replace(g_rootfs_store->byname, (void *)cntr->srootfs->names[i], (void *)cntr)) { - ERROR("Failed to insert containes to name index"); + ERROR("Failed to insert containers to name index"); ret = -1; goto out; } @@ -662,7 +663,7 @@ static storage_rootfs *new_storage_rootfs(const char *id, const char *image, cha c->layer = util_strdup_s(layer); c->metadata = util_strdup_s(metadata); - if (!get_now_time_buffer(timebuffer, sizeof(timebuffer))) { + if (!util_get_now_time_buffer(timebuffer, sizeof(timebuffer))) { ERROR("Failed to get now time string"); ret = -1; goto out; @@ -727,90 +728,6 @@ out: return ret; } -char *rootfs_store_create(const char *id, const char **names, size_t names_len, const char *image, const char *layer, - const char *metadata, struct storage_rootfs_options *rootfs_opts) -{ - int ret = 0; - char *dst_id = NULL; - char **unique_names = NULL; - size_t unique_names_len = 0; - cntrootfs_t *cntr = NULL; - storage_rootfs *c = NULL; - - if (g_rootfs_store == NULL) { - ERROR("Container store is not ready"); - return NULL; - } - - if (!rootfs_store_lock(EXCLUSIVE)) { - ERROR("Failed to lock container store, not allowed to create new containers"); - return NULL; - } - - if (id == NULL) { - dst_id = generate_random_container_id(); - } else { - dst_id = util_strdup_s(id); - } - - if (dst_id == NULL) { - ERROR("Out of memory or generate random container id failed"); - ret = -1; - goto out; - } - - if (map_search(g_rootfs_store->byid, (void *)dst_id) != NULL) { - ERROR("ID is already in use: %s", dst_id); - ret = -1; - goto out; - } - - if (util_string_array_unique(names, names_len, &unique_names, &unique_names_len) != 0) { - ERROR("Failed to unique names"); - ret = -1; - goto out; - } - - c = new_storage_rootfs(dst_id, image, unique_names, unique_names_len, layer, metadata, rootfs_opts); - if (c == NULL) { - ERROR("Failed to generate new storage container"); - ret = -1; - goto out; - } - - cntr = new_rootfs(c); - if (cntr == NULL) { - ERROR("Out of memory"); - ret = -1; - goto out; - } - c = NULL; - - if (rootfs_store_append_container_rootfs(dst_id, layer, (const char **)unique_names, unique_names_len, cntr) != 0) { - ERROR("Failed to append container to container store"); - ret = -1; - goto out; - } - - if (save_rootfs(cntr) != 0) { - ERROR("Failed to save container"); - ret = -1; - goto out; - } - -out: - if (ret != 0) { - free(dst_id); - dst_id = NULL; - free_storage_rootfs(c); - c = NULL; - free_rootfs_t(cntr); - cntr = NULL; - } - rootfs_store_unlock(); - return dst_id; -} - static cntrootfs_t *get_rootfs_for_store_by_prefix(const char *id) { bool ret = true; @@ -882,39 +799,6 @@ found: return value; } -char *rootfs_store_lookup(const char *id) -{ - char *container_id = NULL; - cntrootfs_t *cntr = NULL; - - if (id == NULL) { - ERROR("Invalid input parameter, id is NULL"); - return NULL; - } - - if (g_rootfs_store == NULL) { - ERROR("Container store is not ready"); - return NULL; - } - - if (!rootfs_store_lock(SHARED)) { - ERROR("Failed to lock rootfs store, not allowed to lookup rootfs id assginments"); - return NULL; - } - - cntr = lookup(id); - if (cntr == NULL) { - ERROR("Container not known"); - return NULL; - } - - container_id = util_strdup_s(cntr->srootfs->id); - rootfs_ref_dec(cntr); - rootfs_store_unlock(); - - return container_id; -} - static int remove_rootfs_from_memory(const char *id) { struct linked_list *item = NULL; @@ -984,13 +868,13 @@ static int remove_rootfs_dir(const char *id) return 0; } -int rootfs_store_delete(const char *id) +static int delete_rootfs_from_store_without_lock(const char *id) { - cntrootfs_t *cntr = NULL; int ret = 0; + cntrootfs_t *cntr = NULL; if (id == NULL) { - ERROR("Invalid input parameter, id is NULL"); + ERROR("Invalid input parameter: empty id"); return -1; } @@ -999,16 +883,10 @@ int rootfs_store_delete(const char *id) return -1; } - if (!rootfs_store_lock(EXCLUSIVE)) { - ERROR("Failed to lock rootfs store"); - return -1; - } - cntr = lookup(id); if (cntr == NULL) { - WARN("rootfs %s not exists already, return success", id); - ret = 0; - goto out; + ERROR("Rootfs %s not known", id); + return -1; } if (remove_rootfs_from_memory(cntr->srootfs->id) != 0) { @@ -1025,17 +903,138 @@ int rootfs_store_delete(const char *id) out: rootfs_ref_dec(cntr); - rootfs_store_unlock(); return ret; } -static int delete_rootfs_from_store_without_lock(const char *id) +char *rootfs_store_create(const char *id, const char **names, size_t names_len, const char *image, const char *layer, + const char *metadata, struct storage_rootfs_options *rootfs_opts) { int ret = 0; + char *dst_id = NULL; + char **unique_names = NULL; + size_t unique_names_len = 0; cntrootfs_t *cntr = NULL; + storage_rootfs *c = NULL; + + if (g_rootfs_store == NULL) { + ERROR("Container store is not ready"); + return NULL; + } + + if (!rootfs_store_lock(EXCLUSIVE)) { + ERROR("Failed to lock container store, not allowed to create new containers"); + return NULL; + } if (id == NULL) { - ERROR("Invalid input parameter: empty id"); + dst_id = generate_random_container_id(); + } else { + dst_id = util_strdup_s(id); + } + + if (dst_id == NULL) { + ERROR("Out of memory or generate random container id failed"); + ret = -1; + goto out; + } + + if (map_search(g_rootfs_store->byid, (void *)dst_id) != NULL) { + ERROR("ID is already in use: %s", dst_id); + ret = -1; + goto out; + } + + if (util_string_array_unique(names, names_len, &unique_names, &unique_names_len) != 0) { + ERROR("Failed to unique names"); + ret = -1; + goto out; + } + + c = new_storage_rootfs(dst_id, image, unique_names, unique_names_len, layer, metadata, rootfs_opts); + if (c == NULL) { + ERROR("Failed to generate new storage container"); + ret = -1; + goto out; + } + + cntr = new_rootfs(c); + if (cntr == NULL) { + ERROR("Out of memory"); + ret = -1; + goto out; + } + c = NULL; + + if (rootfs_store_append_container_rootfs(dst_id, layer, (const char **)unique_names, unique_names_len, cntr) != 0) { + ERROR("Failed to append container to container store"); + ret = -1; + goto out; + } + + if (save_rootfs(cntr) != 0) { + ERROR("Failed to save container"); + if (delete_rootfs_from_store_without_lock(dst_id) != 0) { + ERROR("Failed to delete rootfs from store"); + } + c = NULL; + cntr = NULL; + ret = -1; + goto out; + } + +out: + if (ret != 0) { + free(dst_id); + dst_id = NULL; + free_storage_rootfs(c); + c = NULL; + free_rootfs_t(cntr); + cntr = NULL; + } + rootfs_store_unlock(); + return dst_id; +} + +char *rootfs_store_lookup(const char *id) +{ + char *container_id = NULL; + cntrootfs_t *cntr = NULL; + + if (id == NULL) { + ERROR("Invalid input parameter, id is NULL"); + return NULL; + } + + if (g_rootfs_store == NULL) { + ERROR("Container store is not ready"); + return NULL; + } + + if (!rootfs_store_lock(SHARED)) { + ERROR("Failed to lock rootfs store, not allowed to lookup rootfs id assginments"); + return NULL; + } + + cntr = lookup(id); + if (cntr == NULL) { + ERROR("Container not known"); + return NULL; + } + + container_id = util_strdup_s(cntr->srootfs->id); + rootfs_ref_dec(cntr); + rootfs_store_unlock(); + + return container_id; +} + +int rootfs_store_delete(const char *id) +{ + cntrootfs_t *cntr = NULL; + int ret = 0; + + if (id == NULL) { + ERROR("Invalid input parameter, id is NULL"); return -1; } @@ -1044,10 +1043,16 @@ static int delete_rootfs_from_store_without_lock(const char *id) return -1; } + if (!rootfs_store_lock(EXCLUSIVE)) { + ERROR("Failed to lock rootfs store"); + return -1; + } + cntr = lookup(id); if (cntr == NULL) { - ERROR("Rootfs %s not known", id); - return -1; + WARN("rootfs %s not exists already, return success", id); + ret = 0; + goto out; } if (remove_rootfs_from_memory(cntr->srootfs->id) != 0) { @@ -1064,6 +1069,7 @@ static int delete_rootfs_from_store_without_lock(const char *id) out: rootfs_ref_dec(cntr); + rootfs_store_unlock(); return ret; } @@ -1262,40 +1268,6 @@ out: return dup_rootfs; } -char *rootfs_store_metadata(const char *id) -{ - cntrootfs_t *img = NULL; - char *metadata = NULL; - - if (id == NULL) { - ERROR("Invalid parameter, id is NULL"); - return NULL; - } - - if (g_rootfs_store == NULL) { - ERROR("Rootfs store is not ready"); - return NULL; - } - - if (!rootfs_store_lock(SHARED)) { - ERROR("Failed to lock rootfs store with shared lock, not allowed to get rootfs metadata assignments"); - return NULL; - } - - img = lookup(id); - if (img == NULL) { - ERROR("Rootfs not known"); - goto out; - } - - metadata = util_strdup_s(img->srootfs->metadata); - -out: - rootfs_ref_dec(img); - rootfs_store_unlock(); - return metadata; -} - int rootfs_store_get_all_rootfs(struct rootfs_list *all_rootfs) { int ret = 0; diff --git a/src/daemon/modules/image/oci/storage/rootfs_store/rootfs_store.h b/src/daemon/modules/image/oci/storage/rootfs_store/rootfs_store.h index 6cab97a..e13f97b 100644 --- a/src/daemon/modules/image/oci/storage/rootfs_store/rootfs_store.h +++ b/src/daemon/modules/image/oci/storage/rootfs_store/rootfs_store.h @@ -62,9 +62,6 @@ bool rootfs_store_exists(const char *id); // Retrieve information about a container given an ID or name. storage_rootfs *rootfs_store_get_rootfs(const char *id); -// Reads metadata associated with an item with the specified ID. -char *rootfs_store_metadata(const char *id); - // Return a slice enumerating the known containers. int rootfs_store_get_all_rootfs(struct rootfs_list *all_rootfs); diff --git a/src/daemon/modules/image/oci/storage/storage.c b/src/daemon/modules/image/oci/storage/storage.c index 8ad96d6..6e83665 100644 --- a/src/daemon/modules/image/oci/storage/storage.c +++ b/src/daemon/modules/image/oci/storage/storage.c @@ -103,15 +103,14 @@ static int fill_read_wrapper(const char *layer_data_path, struct io_read_wrapper reader_tmp = util_common_calloc_s(sizeof(struct io_read_wrapper)); if (reader_tmp == NULL) { ERROR("Memory out"); - ret = -1; - goto out; + return -1; } fd_ptr = util_common_calloc_s(sizeof(int)); if (fd_ptr == NULL) { ERROR("Memory out"); ret = -1; - goto out; + goto err_out; } *fd_ptr = util_open(layer_data_path, O_RDONLY, 0); @@ -126,12 +125,13 @@ static int fill_read_wrapper(const char *layer_data_path, struct io_read_wrapper reader_tmp->close = layer_archive_io_close; *reader = reader_tmp; - goto out; + fd_ptr = NULL; + reader_tmp = NULL; err_out: free(fd_ptr); free(reader_tmp); -out: + return ret; } @@ -182,16 +182,32 @@ out: return opts; } -int storage_set_hold_flag(const char *layer_id, bool hold) +int storage_inc_hold_refs(const char *layer_id) +{ + int ret = 0; + + if (!storage_lock(&g_storage_rwlock, true)) { + ERROR("Failed to lock image store when increase hold refs number for layer %s", layer_id); + return -1; + } + + ret = layer_inc_hold_refs(layer_id); + + storage_unlock(&g_storage_rwlock); + + return ret; +} + +int storage_dec_hold_refs(const char *layer_id) { int ret = 0; if (!storage_lock(&g_storage_rwlock, true)) { - ERROR("Failed to lock image store when reset hold flag for layer %s", layer_id); + ERROR("Failed to lock image store when decrease hold refs number for layer %s", layer_id); return -1; } - ret = layer_set_hold_flag(layer_id, hold); + ret = layer_dec_hold_refs(layer_id); storage_unlock(&g_storage_rwlock); @@ -499,7 +515,7 @@ static int do_delete_related_layers(const char *img_id, const char *img_top_laye char *layer_id = NULL; char *last_deleted_layer_id = NULL; struct layer *layer_info = NULL; - bool hold = false; + int refs_num = 0; layer_id = util_strdup_s(img_top_layer_id); if (layer_id == NULL) { @@ -509,13 +525,13 @@ static int do_delete_related_layers(const char *img_id, const char *img_top_laye } while (layer_id != NULL) { - ret = layer_get_hold_flag(layer_id, &hold); + ret = layer_get_hold_refs(layer_id, &refs_num); if (ret != 0) { break; } - // if the layer is hold, it means it's pulling/importing/loading or other layer creating actions, - // so do not delete it - if (hold) { + // if the layer's hold refs number not 0, it means it's pulling/importing/loading or + // other layer creating actions, so do not delete it + if (refs_num > 0) { break; } @@ -1197,8 +1213,8 @@ int storage_rootfs_umount(const char *container_id, bool force) rootfs_info = rootfs_store_get_rootfs(container_id); if (rootfs_info == NULL) { - ERROR("Failed to get rootfs %s info", container_id); - ret = -1; + ERROR("Failed to get rootfs %s info, skip umount", container_id); + ret = 0; goto out; } @@ -1313,7 +1329,7 @@ static int parse_checked_layer_file(const char *path, map_t *checked_layers) return (errno == ENOENT ? 0 : -1); } - ret = isula_utils_read_line(fp, parse_checked_layer_cb, (void *)checked_layers); + ret = util_proc_file_line_by_line(fp, parse_checked_layer_cb, (void *)checked_layers); fclose(fp); return ret; diff --git a/src/daemon/modules/image/oci/storage/storage.h b/src/daemon/modules/image/oci/storage/storage.h index 4ba6470..d3c4420 100644 --- a/src/daemon/modules/image/oci/storage/storage.h +++ b/src/daemon/modules/image/oci/storage/storage.h @@ -151,7 +151,9 @@ char *storage_img_get_image_id(const char *img_name); /* layer operations */ int storage_layer_create(const char *layer_id, storage_layer_create_opts_t *opts); -int storage_set_hold_flag(const char *layer_id, bool hold); +int storage_inc_hold_refs(const char *layer_id); + +int storage_dec_hold_refs(const char *layer_id); struct layer_list *storage_layers_get_by_compress_digest(const char *digest); diff --git a/src/daemon/modules/image/oci/utils_images.c b/src/daemon/modules/image/oci/utils_images.c index 9204d0d..42831cc 100644 --- a/src/daemon/modules/image/oci/utils_images.c +++ b/src/daemon/modules/image/oci/utils_images.c @@ -63,7 +63,7 @@ char *oci_get_host(const char *name) } parts = util_string_split(name, '/'); - if ((parts != NULL && *parts != NULL && !strings_contains_any(*parts, ".:") && strcmp(*parts, "localhost")) || + if ((parts != NULL && *parts != NULL && !util_strings_contains_any(*parts, ".:") && strcmp(*parts, "localhost")) || (strstr(name, "/") == NULL)) { util_free_array(parts); return NULL; @@ -382,8 +382,8 @@ static char *convert_created_by(image_manifest_v1_compatibility *config) return created_by; } -int add_rootfs_and_history(const layer_blob *layers, size_t layers_len, - const registry_manifest_schema1 *manifest, docker_image_config_v2 *config) +int add_rootfs_and_history(const layer_blob *layers, size_t layers_len, const registry_manifest_schema1 *manifest, + docker_image_config_v2 *config) { int i = 0; int ret = 0; @@ -464,26 +464,6 @@ out: return ret; } -types_timestamp_t created_to_timestamp(char *created) -{ - int64_t nanos = 0; - types_timestamp_t timestamp = { 0 }; - - if (to_unix_nanos_from_str(created, &nanos) != 0) { - ERROR("Failed to get created time from image config"); - goto out; - } - - timestamp.has_seconds = true; - timestamp.seconds = nanos / Time_Second; - timestamp.has_nanos = true; - timestamp.nanos = nanos % Time_Second; - -out: - - return timestamp; -} - bool oci_valid_time(char *time) { int64_t nanos = 0; @@ -493,7 +473,7 @@ bool oci_valid_time(char *time) return false; } - if (to_unix_nanos_from_str(time, &nanos) != 0) { + if (util_to_unix_nanos_from_str(time, &nanos) != 0) { ERROR("Failed to translate created time %s to nanos", time); return false; } diff --git a/src/daemon/modules/image/oci/utils_images.h b/src/daemon/modules/image/oci/utils_images.h index 9f85d1a..4ab4afc 100644 --- a/src/daemon/modules/image/oci/utils_images.h +++ b/src/daemon/modules/image/oci/utils_images.h @@ -53,7 +53,6 @@ char *oci_calc_diffid(const char *file); void free_items_not_inherit(docker_image_config_v2 *config); int add_rootfs_and_history(const layer_blob *layers, size_t layers_len, const registry_manifest_schema1 *manifest, docker_image_config_v2 *config); -types_timestamp_t created_to_timestamp(char *created); bool oci_valid_time(char *time); #ifdef __cplusplus @@ -61,4 +60,3 @@ bool oci_valid_time(char *time); #endif #endif // DAEMON_MODULES_IMAGE_OCI_UTILS_IMAGES_H - diff --git a/src/daemon/modules/plugin/plugin.c b/src/daemon/modules/plugin/plugin.c index bead032..2532656 100644 --- a/src/daemon/modules/plugin/plugin.c +++ b/src/daemon/modules/plugin/plugin.c @@ -185,7 +185,7 @@ static char *get_uniq_enable_plugins(const oci_runtime_spec *oci) UTIL_FREE_AND_SET_NULL(full); for (i = 0; i < util_array_len((const char **)raw); i++) { - if (strings_in_slice((const char **)arr, util_array_len((const char **)arr), raw[i])) { + if (util_strings_in_slice((const char **)arr, util_array_len((const char **)arr), raw[i])) { continue; } if (util_array_append(&arr, raw[i]) != 0) { @@ -274,7 +274,7 @@ static char **get_enable_plugins(const char *plugins) arr_len = util_array_len((const char **)arr); for (i = 0; i < arr_len; i++) { - if (strings_in_slice((const char **)dst, dst_len, arr[i])) { + if (util_strings_in_slice((const char **)dst, dst_len, arr[i])) { continue; } if (util_array_append(&dst, arr[i]) != 0) { @@ -691,7 +691,7 @@ static void *plugin_manager_routine(void *arg) // initilize inotify instance inotify_fd = inotify_init(); if (inotify_fd < 0) { - ERROR("Failed to initalize inotify instance"); + ERROR("Failed to initialize inotify instance"); return NULL; } // add plugin_dir to watch @@ -1129,7 +1129,7 @@ static int pm_init_plugin(const plugin_t *plugin) } } /* - * add elem to reqs, if no containers availabe add no elem. + * add elem to reqs, if no containers available add no elem. */ for (i = 0; i < container_num; i++) { ret = pm_prepare_init_reqs(plugin, &reqs, cnames[i]); diff --git a/src/daemon/modules/runtime/engines/engine.h b/src/daemon/modules/runtime/engines/engine.h index d9482cf..ced3cf2 100644 --- a/src/daemon/modules/runtime/engines/engine.h +++ b/src/daemon/modules/runtime/engines/engine.h @@ -40,6 +40,8 @@ struct engine_cgroup_resources { uint64_t memory_swap; uint64_t memory_reservation; uint64_t kernel_memory_limit; + int64_t cpurt_runtime; + int64_t cpurt_period; }; typedef struct _engine_start_request_t { diff --git a/src/daemon/modules/runtime/engines/lcr/lcr_engine.c b/src/daemon/modules/runtime/engines/lcr/lcr_engine.c index 83a206a..691bfaa 100644 --- a/src/daemon/modules/runtime/engines/lcr/lcr_engine.c +++ b/src/daemon/modules/runtime/engines/lcr/lcr_engine.c @@ -94,6 +94,8 @@ static bool lcr_update_container(const char *name, const char *lcrpath, const st lcr_cr.memory_swap = cr->memory_swap; lcr_cr.memory_reservation = cr->memory_reservation; lcr_cr.kernel_memory_limit = cr->kernel_memory_limit; + lcr_cr.cpurt_period = cr->cpurt_period; + lcr_cr.cpurt_runtime = cr->cpurt_runtime; return g_lcr_update_op(name, lcrpath, &lcr_cr); } diff --git a/src/daemon/modules/runtime/engines/lcr/lcr_rt_ops.c b/src/daemon/modules/runtime/engines/lcr/lcr_rt_ops.c index 77ca9a1..27c6a63 100644 --- a/src/daemon/modules/runtime/engines/lcr/lcr_rt_ops.c +++ b/src/daemon/modules/runtime/engines/lcr/lcr_rt_ops.c @@ -504,6 +504,9 @@ out: static void to_engine_resources(const host_config *hostconfig, struct engine_cgroup_resources *cr) { + uint64_t period = 0; + int64_t quota = 0; + if (hostconfig == NULL || cr == NULL) { return; } @@ -518,6 +521,15 @@ static void to_engine_resources(const host_config *hostconfig, struct engine_cgr cr->memory_swap = (uint64_t)hostconfig->memory_swap; cr->memory_reservation = (uint64_t)hostconfig->memory_reservation; cr->kernel_memory_limit = (uint64_t)hostconfig->kernel_memory; + cr->cpurt_period = hostconfig->cpu_realtime_period; + cr->cpurt_runtime = hostconfig->cpu_realtime_runtime; + + if (hostconfig->nano_cpus > 0) { + period = (uint64_t)(100 * Time_Milli / Time_Micro); + quota = hostconfig->nano_cpus * (int64_t)period / 1e9; + cr->cpu_period = period; + cr->cpu_quota = (uint64_t)quota; + } } int rt_lcr_update(const char *id, const char *runtime, const rt_update_params_t *params) diff --git a/src/daemon/modules/runtime/isula/isula_rt_ops.c b/src/daemon/modules/runtime/isula/isula_rt_ops.c index d056156..6e4512f 100644 --- a/src/daemon/modules/runtime/isula/isula_rt_ops.c +++ b/src/daemon/modules/runtime/isula/isula_rt_ops.c @@ -155,7 +155,7 @@ static void get_err_message(char *buf, int buf_size, const char *workdir, const if (pline == NULL) { break; } - if (strings_contains_word(pline, "error")) { + if (util_strings_contains_word(pline, "error")) { if (lines[0] == NULL) { lines[0] = pline; pline = NULL; @@ -714,7 +714,7 @@ realexec: goto out; } - status = wait_for_pid_status(pid); + status = util_wait_for_pid_status(pid); if (status < 0) { ERROR("failed wait shim-parent %d exit %s", pid, strerror(errno)); ret = -1; @@ -763,7 +763,7 @@ static int get_container_process_pid(const char *workdir) file_read_int(fname, &pid); if (!pid) { if (shim_alive(workdir)) { - usleep_nointerupt(100000); + util_usleep_nointerupt(100000); continue; } ERROR("failed read pid from dead shim %s", workdir); diff --git a/src/daemon/modules/service/service_container.c b/src/daemon/modules/service/service_container.c index 737cfea..4e830d3 100644 --- a/src/daemon/modules/service/service_container.c +++ b/src/daemon/modules/service/service_container.c @@ -1323,7 +1323,7 @@ void umount_share_shm(container_t *cont) if (cont->hostconfig->system_container) { return; } - if (cont->hostconfig->ipc_mode == NULL || is_shareable(cont->hostconfig->ipc_mode)) { + if (cont->hostconfig->ipc_mode == NULL || namespace_is_shareable(cont->hostconfig->ipc_mode)) { if (cont->common_config == NULL || cont->common_config->shm_path == NULL) { return; } @@ -1375,7 +1375,7 @@ static int do_append_process_exec_env(const char **default_env, defs_process *sp } new_size = (spec->env_len + default_env_len) * sizeof(char *); old_size = spec->env_len * sizeof(char *); - ret = mem_realloc((void **)&temp, new_size, spec->env, old_size); + ret = util_mem_realloc((void **)&temp, new_size, spec->env, old_size); if (ret != 0) { ERROR("Failed to realloc memory for envionment variables"); ret = -1; @@ -1577,7 +1577,7 @@ static defs_process *make_exec_process_spec(const container_config *container_sp } } - ret = dup_array_of_strings((const char **)request->argv, request->argv_len, &(spec->args), &(spec->args_len)); + ret = util_dup_array_of_strings((const char **)request->argv, request->argv_len, &(spec->args), &(spec->args_len)); if (ret != 0) { ERROR("Failed to dup envs for exec process spec"); goto err_out; diff --git a/src/daemon/modules/spec/specs.c b/src/daemon/modules/spec/specs.c index 030a1ba..5c52d63 100644 --- a/src/daemon/modules/spec/specs.c +++ b/src/daemon/modules/spec/specs.c @@ -39,7 +39,9 @@ #include "specs_namespace.h" #include "path.h" #include "constants.h" +#ifdef ENABLE_SELINUX #include "selinux_label.h" +#endif #include "err_msg.h" #include "utils_array.h" #include "utils_file.h" @@ -179,7 +181,7 @@ static int make_annotations_cgroup_dir(const container_config *container_spec, c if (path == NULL) { path = "/isulad"; } - if (cleanpath(path, cleaned, sizeof(cleaned)) == NULL) { + if (util_clean_path(path, cleaned, sizeof(cleaned)) == NULL) { ERROR("Failed to clean path: %s", path); ret = -1; goto out; @@ -676,7 +678,8 @@ static int merge_hugetlbs(oci_runtime_spec *oci_spec, host_config_hugetlbs_eleme old_size = oci_spec->linux->resources->hugepage_limits_len * sizeof(defs_resources_hugepage_limits_element *); new_size = (oci_spec->linux->resources->hugepage_limits_len + hugetlbs_len) * sizeof(defs_resources_hugepage_limits_element *); - ret = mem_realloc((void **)&hugepage_limits_temp, new_size, oci_spec->linux->resources->hugepage_limits, old_size); + ret = util_mem_realloc((void **)&hugepage_limits_temp, new_size, oci_spec->linux->resources->hugepage_limits, + old_size); if (ret != 0) { ERROR("Failed to realloc memory for hugepage limits"); ret = -1; @@ -901,10 +904,39 @@ static int merge_hostname(oci_runtime_spec *oci_spec, const host_config *host_sp return 0; } +static int merge_nanocpus(oci_runtime_spec *oci_spec, int64_t nanocpus) +{ + int ret = 0; + uint64_t period = 0; + int64_t quota = 0; + + ret = make_sure_oci_spec_linux_resources_cpu(oci_spec); + if (ret < 0) { + goto out; + } + + period = (uint64_t)(100 * Time_Milli / Time_Micro); + quota = nanocpus * (int64_t)period / 1e9; + + oci_spec->linux->resources->cpu->quota = quota; + oci_spec->linux->resources->cpu->period = period; + +out: + return ret; +} + static int merge_conf_cgroup_cpu_int64(oci_runtime_spec *oci_spec, const host_config *host_spec) { int ret = 0; + if (host_spec->nano_cpus > 0) { + ret = merge_nanocpus(oci_spec, host_spec->nano_cpus); + if (ret != 0) { + ERROR("Failed to merge cgroup nano cpus"); + goto out; + } + } + /* cpu shares */ if (host_spec->cpu_shares != 0) { ret = merge_cpu_shares(oci_spec, host_spec->cpu_shares); @@ -1291,8 +1323,8 @@ static int replace_entrypoint_cmds_from_spec(const oci_runtime_spec *oci_spec, c isulad_set_error_message("No command specified"); return -1; } - return dup_array_of_strings((const char **)(oci_spec->process->args), oci_spec->process->args_len, - &(container_spec->cmd), &(container_spec->cmd_len)); + return util_dup_array_of_strings((const char **)(oci_spec->process->args), oci_spec->process->args_len, + &(container_spec->cmd), &(container_spec->cmd_len)); } static int merge_conf_args(oci_runtime_spec *oci_spec, container_config *container_spec) @@ -1381,8 +1413,8 @@ static int merge_share_namespace_helper(const oci_runtime_spec *oci_spec, const goto out; } - ret = mem_realloc((void **)&work_ns, (len + 1) * sizeof(defs_namespace_reference *), (void *)work_ns, - len * sizeof(defs_namespace_reference *)); + ret = util_mem_realloc((void **)&work_ns, (len + 1) * sizeof(defs_namespace_reference *), (void *)work_ns, + len * sizeof(defs_namespace_reference *)); if (ret != 0) { ERROR("Out of memory"); goto out; @@ -1658,7 +1690,7 @@ static int split_security_opt(const char *security_opt, char ***items, size_t *i { int ret = 0; - if (strings_contains_any(security_opt, "=")) { + if (util_strings_contains_any(security_opt, "=")) { *items = util_string_split_n(security_opt, '=', 2); if (*items == NULL) { ERROR("Out of memory"); @@ -1666,7 +1698,7 @@ static int split_security_opt(const char *security_opt, char ***items, size_t *i goto out; } *items_size = util_array_len((const char **)*items); - } else if (strings_contains_any(security_opt, ":")) { + } else if (util_strings_contains_any(security_opt, ":")) { *items = util_string_split_n(security_opt, ':', 2); if (*items == NULL) { ERROR("Out of memory"); @@ -1751,6 +1783,7 @@ out: return ret; } +#ifdef ENABLE_SELINUX static int to_host_config_selinux_labels(const char **labels, size_t len, char ***dst, size_t *dst_len) { int ret = 0; @@ -1837,8 +1870,8 @@ static int handle_connected_container_mode(host_config *hc) char **pid_label = NULL; size_t pid_label_len = 0; - char *ipc_container = connected_container(hc->ipc_mode); - char *pid_container = connected_container(hc->pid_mode); + char *ipc_container = namespace_get_connected_container(hc->ipc_mode); + char *pid_container = namespace_get_connected_container(hc->pid_mode); if (ipc_container != NULL) { char *ipc_process_label = get_container_process_label(ipc_container); if (dup_security_opt(ipc_process_label, &ipc_label, &ipc_label_len) != 0) { @@ -1908,23 +1941,26 @@ static int generate_security_opt(host_config *hc) util_free_array(items); } - if (is_host(hc->ipc_mode) || is_host(hc->pid_mode) || hc->privileged) { + if (namespace_is_host(hc->ipc_mode) || namespace_is_host(hc->pid_mode) || hc->privileged) { return handle_host_or_privileged_mode(hc); } return handle_connected_container_mode(hc); } +#endif static int merge_security_conf(oci_runtime_spec *oci_spec, host_config *host_spec, container_config_v2_common_config *v2_spec) { int ret = 0; +#ifdef ENABLE_SELINUX ret = generate_security_opt(host_spec); if (ret != 0) { ERROR("Failed to generate security opt"); goto out; } +#endif ret = merge_caps(oci_spec, (const char **)host_spec->cap_add, host_spec->cap_add_len, (const char **)host_spec->cap_drop, host_spec->cap_drop_len); @@ -1952,13 +1988,53 @@ static int merge_security_conf(oci_runtime_spec *oci_spec, host_config *host_spe goto out; } +#ifdef ENABLE_SELINUX ret = merge_selinux(oci_spec, v2_spec); if (ret != 0) { ERROR("Failed to merge selinux config"); goto out; } +#endif + +out: + return ret; +} + +int merge_oci_cgroups_path(const char *id, oci_runtime_spec *oci_spec, const host_config *host_spec) +{ + int ret = 0; + char *default_cgroup_parent = NULL; + char *path = NULL; + + if (id == NULL || oci_spec == NULL || host_spec == NULL) { + ERROR("Invalid arguments"); + ret = -1; + goto out; + } + + if (make_sure_oci_spec_linux(oci_spec) != 0) { + ERROR("Failed to make oci spec linux"); + ret = -1; + goto out; + } + + default_cgroup_parent = conf_get_isulad_cgroup_parent(); + path = default_cgroup_parent; + if (host_spec->cgroup_parent != NULL) { + path = host_spec->cgroup_parent; + } + + if (path == NULL) { + free(oci_spec->linux->cgroups_path); + oci_spec->linux->cgroups_path = util_path_join("/isulad", id); + return 0; + } + + free(oci_spec->linux->cgroups_path); + oci_spec->linux->cgroups_path = util_path_join(path, id); out: + free(default_cgroup_parent); return ret; } @@ -2029,45 +2105,13 @@ int merge_all_specs(host_config *host_spec, const char *real_rootfs, container_c goto out; } -out: - return ret; -} - -int merge_oci_cgroups_path(const char *id, oci_runtime_spec *oci_spec, const host_config *host_spec) -{ - int ret = 0; - char *default_cgroup_parent = NULL; - char *path = NULL; - - if (id == NULL || oci_spec == NULL || host_spec == NULL) { - ERROR("Invalid arguments"); - ret = -1; - goto out; - } - - if (make_sure_oci_spec_linux(oci_spec) != 0) { - ERROR("Failed to make oci spec linux"); - ret = -1; + ret = merge_oci_cgroups_path(v2_spec->id, oci_spec, host_spec); + if (ret != 0) { + ERROR("Failed to make cgroup parent"); goto out; } - default_cgroup_parent = conf_get_isulad_cgroup_parent(); - path = default_cgroup_parent; - if (host_spec->cgroup_parent != NULL) { - path = host_spec->cgroup_parent; - } - - if (path == NULL) { - free(oci_spec->linux->cgroups_path); - oci_spec->linux->cgroups_path = util_path_join("/isulad", id); - return 0; - } - - free(oci_spec->linux->cgroups_path); - oci_spec->linux->cgroups_path = util_path_join(path, id); - out: - UTIL_FREE_AND_SET_NULL(default_cgroup_parent); return ret; } diff --git a/src/daemon/modules/spec/specs_extend.c b/src/daemon/modules/spec/specs_extend.c index 13b597e..96be761 100644 --- a/src/daemon/modules/spec/specs_extend.c +++ b/src/daemon/modules/spec/specs_extend.c @@ -50,7 +50,7 @@ } \ old_size = dest->item##_len * sizeof(defs_hook *); \ new_size = (dest->item##_len + src->item##_len + 1) * sizeof(defs_hook *); \ - ret = mem_realloc((void **)&(item), new_size, dest->item, old_size); \ + ret = util_mem_realloc((void **)&(item), new_size, dest->item, old_size); \ if (ret != 0) { \ ERROR("Failed to realloc memory for hooks_" #item " variables"); \ ret = -1; \ @@ -360,7 +360,7 @@ static char *get_env_abs_file_path(const oci_runtime_spec *oci_spec, const char if (oci_spec->root == NULL || oci_spec->root->path == NULL) { return NULL; } - if (realpath_in_scope(oci_spec->root->path, env_target_file, &env_path) < 0) { + if (util_realpath_in_scope(oci_spec->root->path, env_target_file, &env_path) < 0) { ERROR("env target file '%s' real path must be under rootfs '%s'", env_target_file, oci_spec->root->path); goto out; } @@ -437,7 +437,7 @@ int merge_env(oci_runtime_spec *oci_spec, const char **env, size_t env_len) } new_size = (oci_spec->process->env_len + env_len) * sizeof(char *); old_size = oci_spec->process->env_len * sizeof(char *); - ret = mem_realloc((void **)&temp, new_size, oci_spec->process->env, old_size); + ret = util_mem_realloc((void **)&temp, new_size, oci_spec->process->env, old_size); if (ret != 0) { ERROR("Failed to realloc memory for envionment variables"); ret = -1; @@ -547,7 +547,7 @@ int merge_ulimits_pre(oci_runtime_spec *oci_spec, size_t host_ulimits_len) } old_size = oci_spec->process->rlimits_len * sizeof(defs_process_rlimits_element *); new_size = (oci_spec->process->rlimits_len + host_ulimits_len) * sizeof(defs_process_rlimits_element *); - ret = mem_realloc((void **)&rlimits_temp, new_size, oci_spec->process->rlimits, old_size); + ret = util_mem_realloc((void **)&rlimits_temp, new_size, oci_spec->process->rlimits, old_size); if (ret != 0) { ERROR("Failed to realloc memory for rlimits"); ret = -1; @@ -603,47 +603,49 @@ out: return ret; } -static int do_merge_one_ulimit(const oci_runtime_spec *oci_spec, defs_process_rlimits_element *rlimit) +static bool rlimit_already_exists(const oci_runtime_spec *oci_spec, defs_process_rlimits_element *rlimit) { size_t j; bool exists = false; for (j = 0; j < oci_spec->process->rlimits_len; j++) { if (oci_spec->process->rlimits[j]->type == NULL) { - ERROR("rlimit type is empty"); - UTIL_FREE_AND_SET_NULL(rlimit->type); - free(rlimit); - return -1; + continue; } if (strcmp(oci_spec->process->rlimits[j]->type, rlimit->type) == 0) { exists = true; break; } } - if (exists) { - /* ulimit exist, discard default ulimit */ - UTIL_FREE_AND_SET_NULL(rlimit->type); - free(rlimit); - } else { - oci_spec->process->rlimits[oci_spec->process->rlimits_len] = rlimit; - oci_spec->process->rlimits_len++; - } - return 0; + return exists; } -static int merge_one_ulimit(const oci_runtime_spec *oci_spec, const host_config_ulimits_element *ulimit) +static int append_one_ulimit(const oci_runtime_spec *oci_spec, const host_config_ulimits_element *ulimit) { + int ret = 0; defs_process_rlimits_element *rlimit = NULL; if (trans_ulimit_to_rlimit(&rlimit, ulimit) != 0) { - return -1; + ret = -1; + goto out; + } + + if (rlimit_already_exists(oci_spec, rlimit)) { + ret = 0; + goto out; } - return do_merge_one_ulimit(oci_spec, rlimit); + oci_spec->process->rlimits[oci_spec->process->rlimits_len] = rlimit; + oci_spec->process->rlimits_len++; + rlimit = NULL; + +out: + free_defs_process_rlimits_element(rlimit); + return ret; } -static int merge_ulimits(oci_runtime_spec *oci_spec, host_config_ulimits_element **ulimits, size_t ulimits_len) +static int append_global_ulimits(oci_runtime_spec *oci_spec, host_config_ulimits_element **ulimits, size_t ulimits_len) { int ret = 0; size_t i = 0; @@ -658,7 +660,7 @@ static int merge_ulimits(oci_runtime_spec *oci_spec, host_config_ulimits_element } for (i = 0; i < ulimits_len; i++) { - ret = merge_one_ulimit(oci_spec, ulimits[i]); + ret = append_one_ulimit(oci_spec, ulimits[i]); if (ret != 0) { ret = -1; goto out; @@ -682,7 +684,7 @@ int merge_global_ulimit(oci_runtime_spec *oci_spec) if (ulimits != NULL) { ulimits_len = ulimit_array_len(ulimits); - if (merge_ulimits(oci_spec, ulimits, ulimits_len)) { + if (append_global_ulimits(oci_spec, ulimits, ulimits_len)) { ret = -1; goto out; } diff --git a/src/daemon/modules/spec/specs_mount.c b/src/daemon/modules/spec/specs_mount.c index 9c4b109..37bbd37 100644 --- a/src/daemon/modules/spec/specs_mount.c +++ b/src/daemon/modules/spec/specs_mount.c @@ -40,7 +40,9 @@ #include "specs_mount.h" #include "specs_extend.h" #include "container_api.h" +#ifdef ENABLE_SELINUX #include "selinux_label.h" +#endif #include "err_msg.h" #include "utils_array.h" #include "utils_file.h" @@ -88,7 +90,7 @@ static int append_additional_mounts(oci_runtime_spec *oci_spec, const char *type new_size = (oci_spec->mounts_len + files_len) * sizeof(defs_mount *); old_size = oci_spec->mounts_len * sizeof(defs_mount *); - ret = mem_realloc((void **)&spec_mounts, new_size, oci_spec->mounts, old_size); + ret = util_mem_realloc((void **)&spec_mounts, new_size, oci_spec->mounts, old_size); if (ret != 0) { ERROR("Out of memory"); ret = -1; @@ -176,7 +178,7 @@ static bool valid_dirent_info(const char *dir, const struct dirent *info_archivo return false; } - // do not map device which name containes ":" + // do not map device which name contains ":" pdot = strstr(info_archivo->d_name, ":"); if (pdot != NULL) { INFO("Skipping device %s include \":\"", info_archivo->d_name); @@ -216,7 +218,7 @@ static int pack_devices(const char *fullpath, char ***devices, size_t *device_le tmp_length += 1; new_size = sizeof(char *) * tmp_length; - ret = mem_realloc((void **)&tmp_device, new_size, *devices, old_size); + ret = util_mem_realloc((void **)&tmp_device, new_size, *devices, old_size); if (ret != 0) { ERROR("get_devices: Failed to realloc memory"); ret = -1; @@ -561,19 +563,21 @@ defs_mount *parse_mount(const char *mount) goto out; } - if (!cleanpath(mount_element->destination, dstpath, sizeof(dstpath))) { + if (!util_clean_path(mount_element->source, dstpath, sizeof(dstpath))) { + ERROR("Failed to get clean path"); + ret = -1; + goto out; + } + free(mount_element->source); + mount_element->source = util_strdup_s(dstpath); + + if (!util_clean_path(mount_element->destination, dstpath, sizeof(dstpath))) { ERROR("failed to get clean path"); ret = EINVALIDARGS; goto out; } - free(mount_element->destination); mount_element->destination = util_strdup_s(dstpath); - if (mount_element->destination == NULL) { - ERROR("out of memory"); - ret = -1; - goto out; - } /* append default options if it's bind mount */ ret = append_default_mount_options(mount_element, has_ro, has_pro); @@ -723,16 +727,26 @@ defs_mount *parse_volume(const char *volume) } } - if (!cleanpath(mount_element->destination, dstpath, sizeof(dstpath))) { + if (!util_clean_path(mount_element->source, dstpath, sizeof(dstpath))) { + ERROR("Failed to get clean path"); + ret = -1; + goto free_out; + } + free(mount_element->source); + mount_element->source = util_strdup_s(dstpath); + + if (!util_clean_path(mount_element->destination, dstpath, sizeof(dstpath))) { ERROR("Failed to get clean path"); ret = -1; goto free_out; } free(mount_element->destination); mount_element->destination = util_strdup_s(dstpath); + if (label != NULL) { options_len++; } + mount_element->options = util_common_calloc_s(options_len * sizeof(char *)); if (mount_element->options == NULL) { ERROR("Out of memory"); @@ -899,7 +913,7 @@ out: return ret; } -static int get_weight_devices_from_path(const host_config_blkio_weight_device_element *weight_dev, +static int get_weight_devices_from_path(const defs_blkio_weight_device *weight_dev, defs_block_io_device_weight *spec_weight_dev) { int ret = 0; @@ -929,7 +943,7 @@ static int get_weight_devices_from_path(const host_config_blkio_weight_device_el } static int merge_host_config_blk_weight_device(defs_block_io_device_weight **out_spec_weight_dev, - const host_config_blkio_weight_device_element *weight_dev) + const defs_blkio_weight_device *weight_dev) { int ret = 0; defs_block_io_device_weight *spec_weight_dev = NULL; @@ -958,112 +972,56 @@ out: return ret; } -static int get_read_bps_devices_from_path(const host_config_blkio_device_read_bps_element *read_bps_dev, - defs_block_io_device_throttle *spec_read_bps_dev) -{ - int ret = 0; - struct stat st; - - if (read_bps_dev == NULL || spec_read_bps_dev == NULL) { - return -1; - } - - ret = stat(read_bps_dev->path, &st); - if (ret < 0) { - ERROR("Failed to get state of device:%s", read_bps_dev->path); - isulad_set_error_message("no such file or directory: %s", read_bps_dev->path); - return -1; - } - - /* fill spec throttle read bps dev */ - spec_read_bps_dev->rate = read_bps_dev->rate; - spec_read_bps_dev->major = (int64_t)major(st.st_rdev); - spec_read_bps_dev->minor = (int64_t)minor(st.st_rdev); - - return 0; -} - -static int merge_host_config_blk_read_bps_device(defs_block_io_device_throttle **out_spec_read_bps_dev, - const host_config_blkio_device_read_bps_element *blkio_device_read_bps) -{ - int ret = 0; - defs_block_io_device_throttle *spec_read_bps_dev = NULL; - - spec_read_bps_dev = util_common_calloc_s(sizeof(defs_block_io_device_throttle)); - if (spec_read_bps_dev == NULL) { - ERROR("Memory out"); - ret = -1; - goto erro_out; - } - - ret = get_read_bps_devices_from_path(blkio_device_read_bps, spec_read_bps_dev); - if (ret != 0) { - ERROR("Failed to get throttle read bps devices info"); - ret = -1; - goto erro_out; - } - - *out_spec_read_bps_dev = spec_read_bps_dev; - goto out; - -erro_out: - free_defs_block_io_device_throttle(spec_read_bps_dev); - -out: - return ret; -} - -static int get_write_bps_devices_from_path(const host_config_blkio_device_write_bps_element *write_bps_dev, - defs_block_io_device_throttle *spec_write_bps_dev) +static int get_blkio_device_throttle_info(const defs_blkio_device *blkio_dev_info, + defs_block_io_device_throttle *blkio_dev_throttle) { int ret = 0; struct stat st; - if (write_bps_dev == NULL || spec_write_bps_dev == NULL) { + if (blkio_dev_info == NULL || blkio_dev_throttle == NULL) { return -1; } - ret = stat(write_bps_dev->path, &st); + ret = stat(blkio_dev_info->path, &st); if (ret < 0) { - ERROR("no such file or directory :%s", write_bps_dev->path); - isulad_set_error_message("no such file or directory: %s", write_bps_dev->path); + ERROR("no such file or directory :%s", blkio_dev_info->path); + isulad_set_error_message("no such file or directory: %s", blkio_dev_info->path); return -1; } /* fill spec throttle write bps dev */ - spec_write_bps_dev->rate = write_bps_dev->rate; - spec_write_bps_dev->major = (int64_t)major(st.st_rdev); - spec_write_bps_dev->minor = (int64_t)minor(st.st_rdev); + blkio_dev_throttle->rate = blkio_dev_info->rate; + blkio_dev_throttle->major = (int64_t)major(st.st_rdev); + blkio_dev_throttle->minor = (int64_t)minor(st.st_rdev); return 0; } -static int -merge_host_config_blk_write_bps_device(defs_block_io_device_throttle **out_spec_write_bps_dev, - const host_config_blkio_device_write_bps_element *blkio_device_write_bps) +static int merge_host_config_blk_device(defs_block_io_device_throttle **blkio_dev_throttle, + const defs_blkio_device *blkio_dev) { int ret = 0; - defs_block_io_device_throttle *spec_write_bps_dev = NULL; + defs_block_io_device_throttle *tmp_throttle = NULL; - spec_write_bps_dev = util_common_calloc_s(sizeof(defs_block_io_device_throttle)); - if (spec_write_bps_dev == NULL) { + tmp_throttle = util_common_calloc_s(sizeof(defs_block_io_device_throttle)); + if (tmp_throttle == NULL) { ERROR("Memory out"); ret = -1; goto erro_out; } - ret = get_write_bps_devices_from_path(blkio_device_write_bps, spec_write_bps_dev); + ret = get_blkio_device_throttle_info(blkio_dev, tmp_throttle); if (ret != 0) { - ERROR("Failed to get throttle write bps devices info"); + ERROR("Failed to get throttle read bps devices info"); ret = -1; goto erro_out; } - *out_spec_write_bps_dev = spec_write_bps_dev; + *blkio_dev_throttle = tmp_throttle; goto out; erro_out: - free_defs_block_io_device_throttle(spec_write_bps_dev); + free_defs_block_io_device_throttle(tmp_throttle); out: return ret; @@ -1091,7 +1049,7 @@ static int merge_all_devices(oci_runtime_spec *oci_spec, host_config_devices_ele } new_size = (oci_spec->linux->devices_len + devices_len) * sizeof(defs_device *); old_size = oci_spec->linux->devices_len * sizeof(defs_device *); - ret = mem_realloc((void **)&spec_dev, new_size, oci_spec->linux->devices, old_size); + ret = util_mem_realloc((void **)&spec_dev, new_size, oci_spec->linux->devices, old_size); if (ret != 0) { ERROR("Out of memory"); ret = -1; @@ -1108,7 +1066,7 @@ static int merge_all_devices(oci_runtime_spec *oci_spec, host_config_devices_ele } new_size = (oci_spec->linux->resources->devices_len + devices_len) * sizeof(defs_device_cgroup *); old_size = oci_spec->linux->resources->devices_len * sizeof(defs_device_cgroup *); - ret = mem_realloc((void **)&spec_cgroup_dev, new_size, oci_spec->linux->resources->devices, old_size); + ret = util_mem_realloc((void **)&spec_cgroup_dev, new_size, oci_spec->linux->resources->devices, old_size); if (ret != 0) { ERROR("Out of memory"); ret = -1; @@ -1416,7 +1374,7 @@ int merge_volumes(oci_runtime_spec *oci_spec, char **volumes, size_t volumes_len } new_size = (oci_spec->mounts_len + volumes_len) * sizeof(defs_mount *); old_size = oci_spec->mounts_len * sizeof(defs_mount *); - ret = mem_realloc((void **)&mounts_temp, new_size, oci_spec->mounts, old_size); + ret = util_mem_realloc((void **)&mounts_temp, new_size, oci_spec->mounts, old_size); if (ret != 0) { ERROR("Failed to realloc memory volumes"); ret = -1; @@ -1440,14 +1398,14 @@ int merge_volumes(oci_runtime_spec *oci_spec, char **volumes, size_t volumes_len old_mp_val_size = common_config->mount_points->len * sizeof(container_config_v2_common_config_mount_points_element *); - ret = mem_realloc((void **)&mp_key, new_mp_key_size, common_config->mount_points->keys, old_mp_key_size); + ret = util_mem_realloc((void **)&mp_key, new_mp_key_size, common_config->mount_points->keys, old_mp_key_size); if (ret != 0) { ERROR("Failed to realloc memory mount point"); ret = -1; goto out; } common_config->mount_points->keys = mp_key; - ret = mem_realloc((void **)&mp_val, new_mp_val_size, common_config->mount_points->values, old_mp_val_size); + ret = util_mem_realloc((void **)&mp_val, new_mp_val_size, common_config->mount_points->values, old_mp_val_size); if (ret != 0) { ERROR("Failed to realloc memory mount point"); ret = -1; @@ -1502,7 +1460,7 @@ static int merge_custom_one_device(oci_runtime_spec *oci_spec, const host_config } new_size = (oci_spec->linux->devices_len + 1) * sizeof(defs_device *); old_size = new_size - sizeof(defs_device *); - ret = mem_realloc((void **)&spec_dev, new_size, oci_spec->linux->devices, old_size); + ret = util_mem_realloc((void **)&spec_dev, new_size, oci_spec->linux->devices, old_size); if (ret != 0) { ERROR("Failed to realloc memory for devices"); ret = -1; @@ -1520,7 +1478,7 @@ static int merge_custom_one_device(oci_runtime_spec *oci_spec, const host_config } new_size = (oci_spec->linux->resources->devices_len + 1) * sizeof(defs_device_cgroup *); old_size = new_size - sizeof(defs_device_cgroup *); - ret = mem_realloc((void **)&spec_cgroup_dev, new_size, oci_spec->linux->resources->devices, old_size); + ret = util_mem_realloc((void **)&spec_cgroup_dev, new_size, oci_spec->linux->resources->devices, old_size); if (ret != 0) { ERROR("Failed to realloc memory for cgroup devices"); ret = -1; @@ -1583,8 +1541,7 @@ out: return ret; } -static int merge_blkio_weight_device(oci_runtime_spec *oci_spec, - host_config_blkio_weight_device_element **blkio_weight_device, +static int merge_blkio_weight_device(oci_runtime_spec *oci_spec, defs_blkio_weight_device **blkio_weight_device, size_t blkio_weight_device_len) { int ret = 0; @@ -1608,7 +1565,8 @@ static int merge_blkio_weight_device(oci_runtime_spec *oci_spec, new_size = (oci_spec->linux->resources->block_io->weight_device_len + blkio_weight_device_len) * sizeof(defs_block_io_device_weight *); old_size = oci_spec->linux->resources->block_io->weight_device_len * sizeof(defs_block_io_device_weight *); - ret = mem_realloc((void **)&weight_device, new_size, oci_spec->linux->resources->block_io->weight_device, old_size); + ret = util_mem_realloc((void **)&weight_device, new_size, oci_spec->linux->resources->block_io->weight_device, + old_size); if (ret != 0) { ERROR("Failed to realloc memory for weight devices"); ret = -1; @@ -1633,8 +1591,7 @@ out: return ret; } -static int merge_blkio_read_bps_device(oci_runtime_spec *oci_spec, - host_config_blkio_device_read_bps_element **blkio_read_bps_device, +static int merge_blkio_read_bps_device(oci_runtime_spec *oci_spec, defs_blkio_device **blkio_read_bps_device, size_t throttle_read_bps_device_len) { int ret = 0; @@ -1661,8 +1618,8 @@ static int merge_blkio_read_bps_device(oci_runtime_spec *oci_spec, sizeof(defs_block_io_device_throttle *); old_size = oci_spec->linux->resources->block_io->throttle_read_bps_device_len * sizeof(defs_block_io_device_throttle *); - ret = mem_realloc((void **)&throttle_read_bps_device, new_size, - oci_spec->linux->resources->block_io->throttle_read_bps_device, old_size); + ret = util_mem_realloc((void **)&throttle_read_bps_device, new_size, + oci_spec->linux->resources->block_io->throttle_read_bps_device, old_size); if (ret != 0) { ERROR("Failed to realloc memory for blkio throttle read bps devices"); ret = -1; @@ -1671,7 +1628,7 @@ static int merge_blkio_read_bps_device(oci_runtime_spec *oci_spec, oci_spec->linux->resources->block_io->throttle_read_bps_device = throttle_read_bps_device; for (i = 0; i < throttle_read_bps_device_len; i++) { - ret = merge_host_config_blk_read_bps_device( + ret = merge_host_config_blk_device( &oci_spec->linux->resources->block_io ->throttle_read_bps_device[oci_spec->linux->resources->block_io->throttle_read_bps_device_len], blkio_read_bps_device[i]); @@ -1687,8 +1644,7 @@ out: return ret; } -static int merge_blkio_write_bps_device(oci_runtime_spec *oci_spec, - host_config_blkio_device_write_bps_element **blkio_write_bps_device, +static int merge_blkio_write_bps_device(oci_runtime_spec *oci_spec, defs_blkio_device **blkio_write_bps_device, size_t throttle_write_bps_device_len) { int ret = 0; @@ -1715,8 +1671,8 @@ static int merge_blkio_write_bps_device(oci_runtime_spec *oci_spec, sizeof(defs_block_io_device_throttle *); old_size = oci_spec->linux->resources->block_io->throttle_write_bps_device_len * sizeof(defs_block_io_device_throttle *); - ret = mem_realloc((void **)&throttle_write_bps_device, new_size, - oci_spec->linux->resources->block_io->throttle_write_bps_device, old_size); + ret = util_mem_realloc((void **)&throttle_write_bps_device, new_size, + oci_spec->linux->resources->block_io->throttle_write_bps_device, old_size); if (ret != 0) { ERROR("Failed to realloc memory for throttle write bps devices"); ret = -1; @@ -1725,7 +1681,7 @@ static int merge_blkio_write_bps_device(oci_runtime_spec *oci_spec, oci_spec->linux->resources->block_io->throttle_write_bps_device = throttle_write_bps_device; for (i = 0; i < throttle_write_bps_device_len; i++) { - ret = merge_host_config_blk_write_bps_device( + ret = merge_host_config_blk_device( &oci_spec->linux->resources->block_io ->throttle_write_bps_device[oci_spec->linux->resources->block_io->throttle_write_bps_device_len], blkio_write_bps_device[i]); @@ -1741,6 +1697,300 @@ out: return ret; } +static int merge_blkio_read_iops_device(oci_runtime_spec *oci_spec, defs_blkio_device **blkio_read_iops_device, + size_t throttle_read_iops_device_len) +{ + int ret = 0; + size_t new_size = 0; + size_t old_size = 0; + size_t i = 0; + defs_block_io_device_throttle **throttle_read_iops_device = NULL; + + ret = make_sure_oci_spec_linux_resources_blkio(oci_spec); + if (ret < 0) { + goto out; + } + + if (oci_spec->linux->resources->block_io->throttle_read_iops_device_len > + LIST_DEVICE_SIZE_MAX - throttle_read_iops_device_len) { + ERROR("Too many throttle read iops devices to merge, the limit is %lld", LIST_DEVICE_SIZE_MAX); + isulad_set_error_message("Too many throttle read iops devices devices to merge, the limit is %d", + LIST_DEVICE_SIZE_MAX); + ret = -1; + goto out; + } + + new_size = (oci_spec->linux->resources->block_io->throttle_read_iops_device_len + throttle_read_iops_device_len) * + sizeof(defs_block_io_device_throttle *); + old_size = oci_spec->linux->resources->block_io->throttle_read_iops_device_len * + sizeof(defs_block_io_device_throttle *); + ret = util_mem_realloc((void **)&throttle_read_iops_device, new_size, + oci_spec->linux->resources->block_io->throttle_read_iops_device, old_size); + if (ret != 0) { + ERROR("Failed to realloc memory for blkio throttle read iops devices"); + ret = -1; + goto out; + } + oci_spec->linux->resources->block_io->throttle_read_iops_device = throttle_read_iops_device; + + for (i = 0; i < throttle_read_iops_device_len; i++) { + ret = merge_host_config_blk_device( + &oci_spec->linux->resources->block_io + ->throttle_read_iops_device[oci_spec->linux->resources->block_io->throttle_read_iops_device_len], + blkio_read_iops_device[i]); + if (ret != 0) { + ERROR("Failed to merge blkio throttle read iops device"); + ret = -1; + goto out; + } + oci_spec->linux->resources->block_io->throttle_read_iops_device_len++; + } + +out: + return ret; +} + +static int merge_blkio_write_iops_device(oci_runtime_spec *oci_spec, defs_blkio_device **blkio_write_iops_device, + size_t throttle_write_iops_device_len) +{ + int ret = 0; + size_t new_size = 0; + size_t old_size = 0; + size_t i = 0; + defs_block_io_device_throttle **throttle_write_iops_device = NULL; + + ret = make_sure_oci_spec_linux_resources_blkio(oci_spec); + if (ret < 0) { + goto out; + } + + if (oci_spec->linux->resources->block_io->throttle_write_iops_device_len > + LIST_DEVICE_SIZE_MAX - throttle_write_iops_device_len) { + ERROR("Too many throttle write iops devices to merge, the limit is %lld", LIST_DEVICE_SIZE_MAX); + isulad_set_error_message("Too many throttle write iops devices devices to merge, the limit is %d", + LIST_DEVICE_SIZE_MAX); + ret = -1; + goto out; + } + + new_size = (oci_spec->linux->resources->block_io->throttle_write_iops_device_len + throttle_write_iops_device_len) * + sizeof(defs_block_io_device_throttle *); + old_size = oci_spec->linux->resources->block_io->throttle_write_iops_device_len * + sizeof(defs_block_io_device_throttle *); + ret = util_mem_realloc((void **)&throttle_write_iops_device, new_size, + oci_spec->linux->resources->block_io->throttle_write_iops_device, old_size); + if (ret != 0) { + ERROR("Failed to realloc memory for throttle write iops devices"); + ret = -1; + goto out; + } + oci_spec->linux->resources->block_io->throttle_write_iops_device = throttle_write_iops_device; + + for (i = 0; i < throttle_write_iops_device_len; i++) { + ret = merge_host_config_blk_device( + &oci_spec->linux->resources->block_io->throttle_write_iops_device + [oci_spec->linux->resources->block_io->throttle_write_iops_device_len], + blkio_write_iops_device[i]); + if (ret != 0) { + ERROR("Failed to merge blkio throttle write iops device"); + ret = -1; + goto out; + } + oci_spec->linux->resources->block_io->throttle_write_iops_device_len++; + } + +out: + return ret; +} + +static int merge_conf_populate_device(oci_runtime_spec *oci_spec, host_config *host_spec) +{ + int ret = 0; + + if (host_spec->privileged) { + INFO("Skipped \"--device\" due to conflict with \"--privileged\""); + return 0; + } + + if (host_spec->devices != NULL && host_spec->devices_len != 0) { + /* privileged containers will populate all devices in host */ + ret = merge_custom_devices(oci_spec, host_spec->devices, host_spec->devices_len); + if (ret != 0) { + ERROR("Failed to merge custom devices"); + goto out; + } + } +out: + return ret; +} + +/* format example: b 7:* rmw */ +static int parse_device_cgroup_rule(defs_device_cgroup *spec_dev_cgroup, const char *rule) +{ + int ret = 0; + char **parts = NULL; + size_t parts_len = 0; + char **file_mode = NULL; + size_t file_mode_len = 0; + + if (rule == NULL || spec_dev_cgroup == NULL) { + return -1; + } + + parts = util_string_split(rule, ' '); + if (parts == NULL) { + ERROR("Failed to split rule %s", rule); + ret = -1; + goto free_out; + } + + parts_len = util_array_len((const char **)parts); + if (parts_len != 3) { + ERROR("Invalid rule %s", rule); + ret = -1; + goto free_out; + } + + /* fill spec cgroup dev */ + spec_dev_cgroup->allow = true; + spec_dev_cgroup->access = util_strdup_s(parts[2]); + spec_dev_cgroup->type = util_strdup_s(parts[0]); + + file_mode = util_string_split(parts[1], ':'); + if (file_mode == NULL) { + ERROR("Invalid rule mode %s", parts[1]); + ret = -1; + goto free_out; + } + + file_mode_len = util_array_len((const char **)file_mode); + if (file_mode_len != 2) { + ERROR("Invalid rule mode %s", parts[1]); + ret = -1; + goto free_out; + } + + if (strcmp(file_mode[0], "*") == 0) { + spec_dev_cgroup->major = -1; + } else { + if (util_safe_llong(file_mode[0], (long long *)&spec_dev_cgroup->major) != 0) { + ERROR("Invalid rule mode %s", file_mode[0]); + ret = -1; + goto free_out; + } + } + + if (strcmp(file_mode[1], "*") == 0) { + spec_dev_cgroup->minor = -1; + } else { + if (util_safe_llong(file_mode[1], (long long *)&spec_dev_cgroup->minor) != 0) { + ERROR("Invalid rule mode %s", file_mode[1]); + ret = -1; + goto free_out; + } + } + +free_out: + util_free_array(parts); + util_free_array(file_mode); + + return ret; +} + +static int make_device_cgroup_rule(defs_device_cgroup **out_spec_dev_cgroup, const char *dev_cgroup_rule) +{ + int ret = 0; + defs_device_cgroup *spec_dev_cgroup = NULL; + + spec_dev_cgroup = util_common_calloc_s(sizeof(defs_device_cgroup)); + if (spec_dev_cgroup == NULL) { + ERROR("Memory out"); + ret = -1; + goto erro_out; + } + + ret = parse_device_cgroup_rule(spec_dev_cgroup, dev_cgroup_rule); + if (ret != 0) { + ERROR("Failed to parse device cgroup rule %s", dev_cgroup_rule); + ret = -1; + goto erro_out; + } + + *out_spec_dev_cgroup = spec_dev_cgroup; + goto out; + +erro_out: + free_defs_device_cgroup(spec_dev_cgroup); +out: + return ret; +} + +static int do_merge_device_cgroup_rules(oci_runtime_spec *oci_spec, const char **dev_cgroup_rules, + size_t dev_cgroup_rules_len) +{ + int ret = 0; + size_t new_size = 0, old_size = 0; + size_t i = 0; + + ret = make_sure_oci_spec_linux_resources(oci_spec); + if (ret < 0) { + goto out; + } + + /* malloc for cgroup->device */ + defs_device_cgroup **spec_cgroup_dev = NULL; + if (dev_cgroup_rules_len > SIZE_MAX / sizeof(defs_device_cgroup *) - oci_spec->linux->resources->devices_len) { + ERROR("Too many cgroup devices to merge!"); + ret = -1; + goto out; + } + new_size = (oci_spec->linux->resources->devices_len + dev_cgroup_rules_len) * sizeof(defs_device_cgroup *); + old_size = oci_spec->linux->resources->devices_len * sizeof(defs_device_cgroup *); + ret = util_mem_realloc((void **)&spec_cgroup_dev, new_size, oci_spec->linux->resources->devices, old_size); + if (ret != 0) { + ERROR("Out of memory"); + ret = -1; + goto out; + } + oci_spec->linux->resources->devices = spec_cgroup_dev; + + for (i = 0; i < dev_cgroup_rules_len; i++) { + ret = make_device_cgroup_rule(&oci_spec->linux->resources->devices[oci_spec->linux->resources->devices_len], + dev_cgroup_rules[i]); + if (ret != 0) { + ERROR("Failed to merge custom device"); + ret = -1; + goto out; + } + oci_spec->linux->resources->devices_len++; + } +out: + return ret; +} + +static int merge_conf_device_cgroup_rule(oci_runtime_spec *oci_spec, host_config *host_spec) +{ + int ret = 0; + + if (host_spec->privileged) { + INFO("Skipped \"--device-cgroup-rule\" due to conflict with \"--privileged\""); + return 0; + } + + if (host_spec->device_cgroup_rules == NULL || host_spec->device_cgroup_rules_len == 0) { + return 0; + } + + ret = do_merge_device_cgroup_rules(oci_spec, (const char **)host_spec->device_cgroup_rules, + host_spec->device_cgroup_rules_len); + if (ret != 0) { + ERROR("Failed to merge custom devices cgroup rules"); + goto out; + } +out: + return ret; +} + int merge_conf_device(oci_runtime_spec *oci_spec, host_config *host_spec) { int ret = 0; @@ -1774,20 +2024,38 @@ int merge_conf_device(oci_runtime_spec *oci_spec, host_config *host_spec) } } - /* devices which will be populated into container */ - if (host_spec->devices != NULL && host_spec->devices_len != 0) { - /* privileged containers will populate all devices in host */ - if (!host_spec->privileged) { - ret = merge_custom_devices(oci_spec, host_spec->devices, host_spec->devices_len); - if (ret != 0) { - ERROR("Failed to merge custom devices"); - goto out; - } - } else { - INFO("Skipped \"--device\" due to conflict with \"--privileged\""); + /* blkio throttle read iops devices */ + if (host_spec->blkio_device_read_iops != NULL && host_spec->blkio_device_read_iops_len != 0) { + ret = merge_blkio_read_iops_device(oci_spec, host_spec->blkio_device_read_iops, + host_spec->blkio_device_read_iops_len); + if (ret != 0) { + ERROR("Failed to merge blkio read iops devices"); + goto out; } } + /* blkio throttle write iops devices */ + if (host_spec->blkio_device_write_iops != NULL && host_spec->blkio_device_write_iops_len != 0) { + ret = merge_blkio_write_iops_device(oci_spec, host_spec->blkio_device_write_iops, + host_spec->blkio_device_write_iops_len); + if (ret != 0) { + ERROR("Failed to merge blkio write iops devices"); + goto out; + } + } + + /* devices which will be populated into container */ + if (merge_conf_populate_device(oci_spec, host_spec)) { + ret = -1; + goto out; + } + + /* device cgroup rules which will be added into container */ + if (merge_conf_device_cgroup_rule(oci_spec, host_spec)) { + ret = -1; + goto out; + } + out: return ret; } @@ -1801,8 +2069,8 @@ static bool mounts_expand(oci_runtime_spec *container, size_t add_len) ERROR("Too many mount elements!"); return false; } - ret = mem_realloc((void **)&tmp_mount, (old_len + add_len) * sizeof(defs_mount *), container->mounts, - old_len * sizeof(defs_mount *)); + ret = util_mem_realloc((void **)&tmp_mount, (old_len + add_len) * sizeof(defs_mount *), container->mounts, + old_len * sizeof(defs_mount *)); if (ret < 0) { ERROR("memory realloc failed for mount array expand"); return false; @@ -1920,7 +2188,7 @@ static int change_dev_shm_size(oci_runtime_spec *oci_spec, host_config *host_spe char size_opt[MOUNT_PROPERTIES_SIZE] = { 0 }; char *tmp = NULL; - if (is_none(host_spec->ipc_mode)) { + if (namespace_is_none(host_spec->ipc_mode)) { return 0; } @@ -1982,7 +2250,9 @@ static int append_network_files_mounts(oci_runtime_spec *oci_spec, host_config * bool has_hosts_mount = false; bool has_resolv_mount = false; bool has_hostname_mount = false; - bool share = is_container(host_spec->network_mode); +#ifdef ENABLE_SELINUX + bool share = namespace_is_container(host_spec->network_mode); +#endif for (i = 0; i < oci_spec->mounts_len; i++) { if (is_mount_destination_hosts(oci_spec->mounts[i]->destination)) { @@ -2007,11 +2277,13 @@ static int append_network_files_mounts(oci_runtime_spec *oci_spec, host_config * } else { /* add network config files */ if (!has_hosts_mount) { +#ifdef ENABLE_SELINUX if (relabel(v2_spec->hosts_path, v2_spec->mount_label, share) != 0) { ERROR("Error to relabel hosts path: %s", v2_spec->hosts_path); ret = -1; goto out; } +#endif if (!mount_file(oci_spec, v2_spec->hosts_path, ETC_HOSTS)) { ERROR("Merge hosts mount failed"); ret = -1; @@ -2023,11 +2295,13 @@ static int append_network_files_mounts(oci_runtime_spec *oci_spec, host_config * WARN("ResolvConfPath set to %s, but can't stat this filename skipping", v2_spec->resolv_conf_path); } else { if (!has_resolv_mount) { +#ifdef ENABLE_SELINUX if (relabel(v2_spec->resolv_conf_path, v2_spec->mount_label, share) != 0) { ERROR("Error to relabel resolv.conf path: %s", v2_spec->resolv_conf_path); ret = -1; goto out; } +#endif if (!mount_file(oci_spec, v2_spec->resolv_conf_path, RESOLV_CONF_PATH)) { ERROR("Merge resolv.conf mount failed"); ret = -1; @@ -2040,10 +2314,12 @@ static int append_network_files_mounts(oci_runtime_spec *oci_spec, host_config * WARN("HostnamePath set to %s, but can't stat this filename; skipping", v2_spec->resolv_conf_path); } else { if (!has_hostname_mount) { +#ifdef ENABLE_SELINUX if (relabel(v2_spec->hostname_path, v2_spec->mount_label, share) != 0) { ERROR("Error to relabel hostname path: %s", v2_spec->hostname_path); return -1; } +#endif if (!mount_file(oci_spec, v2_spec->hostname_path, ETC_HOSTNAME)) { ERROR("Merge hostname mount failed"); ret = -1; @@ -2263,12 +2539,12 @@ static int setup_ipc_dirs(oci_runtime_spec *oci_spec, host_config *host_spec, return 0; } // setup shareable dirs - if (host_spec->ipc_mode == NULL || is_shareable(host_spec->ipc_mode)) { + if (host_spec->ipc_mode == NULL || namespace_is_shareable(host_spec->ipc_mode)) { return prepare_share_shm(oci_spec, host_spec, v2_spec); } - if (is_container(host_spec->ipc_mode)) { - tmp_cid = connected_container(host_spec->ipc_mode); + if (namespace_is_container(host_spec->ipc_mode)) { + tmp_cid = namespace_get_connected_container(host_spec->ipc_mode); cont = containers_store_get(tmp_cid); if (cont == NULL) { ERROR("Invalid share path: %s", host_spec->ipc_mode); @@ -2277,7 +2553,7 @@ static int setup_ipc_dirs(oci_runtime_spec *oci_spec, host_config *host_spec, } right_path = util_strdup_s(cont->common_config->shm_path); container_unref(cont); - } else if (is_host(host_spec->ipc_mode)) { + } else if (namespace_is_host(host_spec->ipc_mode)) { if (!util_file_exists(SHM_MOUNT_POINT)) { ERROR("/dev/shm is not mounted, but must be for --ipc=host"); ret = -1; diff --git a/src/daemon/modules/spec/specs_namespace.c b/src/daemon/modules/spec/specs_namespace.c index 7364617..e291f09 100644 --- a/src/daemon/modules/spec/specs_namespace.c +++ b/src/daemon/modules/spec/specs_namespace.c @@ -37,7 +37,7 @@ static char *parse_share_namespace_with_prefix(const char *type, const char *pat char ns_path[PATH_MAX] = { 0 }; char *ns_type = NULL; - tmp_cid = connected_container(path); + tmp_cid = namespace_get_connected_container(path); if (tmp_cid == NULL) { goto out; } @@ -96,14 +96,14 @@ int get_share_namespace_path(const char *type, const char *src_path, char **dest return -1; } - if (is_none(src_path)) { + if (namespace_is_none(src_path)) { *dest_path = NULL; - } else if (is_host(src_path)) { - *dest_path = get_host_namespace_path(type); + } else if (namespace_is_host(src_path)) { + *dest_path = namespace_get_host_namespace_path(type); if (*dest_path == NULL) { ret = -1; } - } else if (is_container(src_path)) { + } else if (namespace_is_container(src_path)) { *dest_path = parse_share_namespace_with_prefix(type, src_path); if (*dest_path == NULL) { ret = -1; diff --git a/src/daemon/modules/spec/specs_security.c b/src/daemon/modules/spec/specs_security.c index 3273b31..c90d193 100644 --- a/src/daemon/modules/spec/specs_security.c +++ b/src/daemon/modules/spec/specs_security.c @@ -58,7 +58,8 @@ static int append_capability(char ***dstcaps, size_t *dstcaps_len, const char *c ret = -1; goto out; } - ret = mem_realloc((void **)&tmp, sizeof(char *) * (*dstcaps_len + 1), *dstcaps, sizeof(char *) * (*dstcaps_len)); + ret = util_mem_realloc((void **)&tmp, sizeof(char *) * (*dstcaps_len + 1), *dstcaps, + sizeof(char *) * (*dstcaps_len)); if (ret != 0) { ERROR("Out of memory"); ret = -1; @@ -108,7 +109,7 @@ static int tweak_drops_capabilities(char ***new_caps, size_t *new_caps_len, char size_t i = 0; int ret = 0; - if (strings_in_slice((const char **)drops, drops_len, "all")) { + if (util_strings_in_slice((const char **)drops, drops_len, "all")) { goto out; } @@ -119,7 +120,7 @@ static int tweak_drops_capabilities(char ***new_caps, size_t *new_caps_len, char } // if we don't drop `all`, add back all the non-dropped caps - if (!strings_in_slice((const char **)drops, drops_len, basic_caps[i] + strlen("CAP_"))) { + if (!util_strings_in_slice((const char **)drops, drops_len, basic_caps[i] + strlen("CAP_"))) { ret = append_capability(new_caps, new_caps_len, basic_caps[i]); if (ret != 0) { ERROR("Failed to append capabilities"); @@ -155,14 +156,14 @@ static int tweak_adds_capabilities(char ***new_caps, size_t *new_caps_len, const ret = -1; goto out; } - if (!strings_in_slice(g_all_caps, all_caps_len, tmpcap)) { + if (!util_strings_in_slice(g_all_caps, all_caps_len, tmpcap)) { ERROR("Unknown capability to add: '%s'", tmpcap); ret = -1; goto out; } // add cap if not already in the list - if (!strings_in_slice((const char **)*new_caps, *new_caps_len, tmpcap)) { + if (!util_strings_in_slice((const char **)*new_caps, *new_caps_len, tmpcap)) { ret = append_capability(new_caps, new_caps_len, tmpcap); if (ret != 0) { ERROR("Failed to append capabilities"); @@ -195,7 +196,7 @@ static bool valid_drops_cap(const char **drops, size_t drops_len) ERROR("Failed to print string"); return false; } - if (!strings_in_slice(g_all_caps, all_caps_len, tmpcap)) { + if (!util_strings_in_slice(g_all_caps, all_caps_len, tmpcap)) { ERROR("Unknown capability to drop: '%s'", drops[i]); return false; } @@ -222,7 +223,7 @@ static int tweak_capabilities(char ***caps, size_t *caps_len, const char **adds, return -1; } - if (strings_in_slice((const char **)adds, adds_len, "all")) { + if (util_strings_in_slice((const char **)adds, adds_len, "all")) { ret = copy_capabilities(&basic_caps, &basic_caps_len, g_all_caps, all_caps_len); } else { ret = copy_capabilities(&basic_caps, &basic_caps_len, (const char **)*caps, *caps_len); @@ -361,16 +362,16 @@ static bool is_arch_in_seccomp(const docker_seccomp *seccomp, const char *arch) return false; } -static bool is_cap_in_seccomp(const defs_process_capabilities *capabilites, const char *cap) +static bool is_cap_in_seccomp(const defs_process_capabilities *capabilities, const char *cap) { size_t i = 0; - if (capabilites == NULL) { + if (capabilities == NULL) { return false; } - for (i = 0; i < capabilites->bounding_len; i++) { - if (strcasecmp(capabilites->bounding[i], cap) == 0) { + for (i = 0; i < capabilities->bounding_len; i++) { + if (strcasecmp(capabilities->bounding[i], cap) == 0) { return true; } } @@ -378,7 +379,7 @@ static bool is_cap_in_seccomp(const defs_process_capabilities *capabilites, cons } static void meet_include(const docker_seccomp *seccomp, const docker_seccomp_syscalls_element *syscall, - const defs_process_capabilities *capabilites, bool *meet_include_arch, bool *meet_include_cap) + const defs_process_capabilities *capabilities, bool *meet_include_arch, bool *meet_include_cap) { size_t i; @@ -401,7 +402,7 @@ static void meet_include(const docker_seccomp *seccomp, const docker_seccomp_sys *meet_include_cap = true; } else { for (i = 0; i < syscall->includes->caps_len; i++) { - if (is_cap_in_seccomp(capabilites, syscall->includes->caps[i])) { + if (is_cap_in_seccomp(capabilities, syscall->includes->caps[i])) { *meet_include_cap = true; break; } @@ -410,7 +411,7 @@ static void meet_include(const docker_seccomp *seccomp, const docker_seccomp_sys } static void meet_exclude(const docker_seccomp *seccomp, const docker_seccomp_syscalls_element *syscall, - const defs_process_capabilities *capabilites, bool *meet_exclude_arch, bool *meet_exclude_cap) + const defs_process_capabilities *capabilities, bool *meet_exclude_arch, bool *meet_exclude_cap) { size_t i; @@ -434,7 +435,7 @@ static void meet_exclude(const docker_seccomp *seccomp, const docker_seccomp_sys *meet_exclude_cap = true; } else { for (i = 0; i < syscall->excludes->caps_len; i++) { - if (is_cap_in_seccomp(capabilites, syscall->excludes->caps[i])) { + if (is_cap_in_seccomp(capabilities, syscall->excludes->caps[i])) { *meet_exclude_cap = false; break; } @@ -443,15 +444,15 @@ static void meet_exclude(const docker_seccomp *seccomp, const docker_seccomp_sys } static bool meet_filtering_rules(const docker_seccomp *seccomp, const docker_seccomp_syscalls_element *syscall, - const defs_process_capabilities *capabilites) + const defs_process_capabilities *capabilities) { bool meet_include_arch = false; bool meet_include_cap = false; bool meet_exclude_arch = true; bool meet_exclude_cap = true; - meet_include(seccomp, syscall, capabilites, &meet_include_arch, &meet_include_cap); - meet_exclude(seccomp, syscall, capabilites, &meet_exclude_arch, &meet_exclude_cap); + meet_include(seccomp, syscall, capabilities, &meet_include_arch, &meet_include_cap); + meet_exclude(seccomp, syscall, capabilities, &meet_exclude_arch, &meet_exclude_cap); return meet_include_arch && meet_include_cap && meet_exclude_arch && meet_exclude_cap; } @@ -530,7 +531,7 @@ static int dup_syscall_args_to_oci_spec(const docker_seccomp_syscalls_element *d static int dup_syscall_to_oci_spec(const docker_seccomp *docker_seccomp_spec, oci_runtime_config_linux_seccomp *oci_seccomp_spec, - const defs_process_capabilities *capabilites) + const defs_process_capabilities *capabilities) { int ret = 0; size_t i, j, k; @@ -550,7 +551,7 @@ static int dup_syscall_to_oci_spec(const docker_seccomp *docker_seccomp_spec, return -1; } for (i = 0; i < docker_seccomp_spec->syscalls_len; i++) { - if (!meet_filtering_rules(docker_seccomp_spec, docker_seccomp_spec->syscalls[i], capabilites)) { + if (!meet_filtering_rules(docker_seccomp_spec, docker_seccomp_spec->syscalls[i], capabilities)) { continue; } k = oci_seccomp_spec->syscalls_len; @@ -581,7 +582,7 @@ static int dup_syscall_to_oci_spec(const docker_seccomp *docker_seccomp_spec, new_size = sizeof(defs_syscall *) * oci_seccomp_spec->syscalls_len; old_size = sizeof(defs_syscall *) * docker_seccomp_spec->syscalls_len; - ret = mem_realloc((void **)&tmp_syscalls, new_size, oci_seccomp_spec->syscalls, old_size); + ret = util_mem_realloc((void **)&tmp_syscalls, new_size, oci_seccomp_spec->syscalls, old_size); if (ret < 0) { ERROR("Out of memory"); return -1; @@ -593,7 +594,7 @@ static int dup_syscall_to_oci_spec(const docker_seccomp *docker_seccomp_spec, static oci_runtime_config_linux_seccomp * trans_docker_seccomp_to_oci_format(const docker_seccomp *docker_seccomp_spec, - const defs_process_capabilities *capabilites) + const defs_process_capabilities *capabilities) { oci_runtime_config_linux_seccomp *oci_seccomp_spec = NULL; @@ -611,7 +612,7 @@ trans_docker_seccomp_to_oci_format(const docker_seccomp *docker_seccomp_spec, } // syscalls - if (dup_syscall_to_oci_spec(docker_seccomp_spec, oci_seccomp_spec, capabilites)) { + if (dup_syscall_to_oci_spec(docker_seccomp_spec, oci_seccomp_spec, capabilities)) { goto out; } @@ -626,7 +627,7 @@ done: return oci_seccomp_spec; } -int merge_default_seccomp_spec(oci_runtime_spec *oci_spec, const defs_process_capabilities *capabilites) +int merge_default_seccomp_spec(oci_runtime_spec *oci_spec, const defs_process_capabilities *capabilities) { oci_runtime_config_linux_seccomp *oci_seccomp_spec = NULL; docker_seccomp *docker_seccomp_spec = NULL; @@ -641,7 +642,7 @@ int merge_default_seccomp_spec(oci_runtime_spec *oci_spec, const defs_process_ca isulad_set_error_message("failed to parse seccomp file: %s", SECCOMP_DEFAULT_PATH); return -1; } - oci_seccomp_spec = trans_docker_seccomp_to_oci_format(docker_seccomp_spec, capabilites); + oci_seccomp_spec = trans_docker_seccomp_to_oci_format(docker_seccomp_spec, capabilities); free_docker_seccomp(docker_seccomp_spec); if (oci_seccomp_spec == NULL) { ERROR("Failed to trans docker format seccomp profile to oci standard"); @@ -669,7 +670,7 @@ static int append_systemcall_to_seccomp(oci_runtime_config_linux_seccomp *seccom } new_size = (seccomp->syscalls_len + 1) * sizeof(defs_syscall *); old_size = new_size - sizeof(defs_syscall *); - nret = mem_realloc((void **)&tmp_syscalls, new_size, seccomp->syscalls, old_size); + nret = util_mem_realloc((void **)&tmp_syscalls, new_size, seccomp->syscalls, old_size); if (nret < 0) { CRIT("Memory allocation error."); return -1; @@ -849,6 +850,7 @@ out: return ret; } +#ifdef ENABLE_SELINUX int merge_selinux(oci_runtime_spec *oci_spec, container_config_v2_common_config *v2_spec) { if (make_sure_oci_spec_process(oci_spec) < 0) { @@ -860,6 +862,7 @@ int merge_selinux(oci_runtime_spec *oci_spec, container_config_v2_common_config return 0; } +#endif static int get_adds_cap_for_system_container(const host_config *host_spec, char ***adds, size_t *adds_len) { @@ -880,7 +883,7 @@ static int get_adds_cap_for_system_container(const host_config *host_spec, char // if cap_drop in g_system_caps, move it from g_system_caps for (i = 0; i < system_caps_len; i++) { - if (!strings_in_slice((const char **)drops, drops_len, g_system_caps[i])) { + if (!util_strings_in_slice((const char **)drops, drops_len, g_system_caps[i])) { ret = append_capability(adds, adds_len, g_system_caps[i]); if (ret != 0) { ERROR("Failed to append capabilities"); diff --git a/src/daemon/modules/spec/specs_security.h b/src/daemon/modules/spec/specs_security.h index 5131d7f..f33814d 100644 --- a/src/daemon/modules/spec/specs_security.h +++ b/src/daemon/modules/spec/specs_security.h @@ -25,13 +25,15 @@ #include "isula_libutils/container_config_v2.h" #include "isula_libutils/oci_runtime_spec.h" -int merge_default_seccomp_spec(oci_runtime_spec *oci_spec, const defs_process_capabilities *capabilites); +int merge_default_seccomp_spec(oci_runtime_spec *oci_spec, const defs_process_capabilities *capabilities); int merge_caps(oci_runtime_spec *oci_spec, const char **adds, size_t adds_len, const char **drops, size_t drops_len); int refill_oci_process_capabilities(defs_process_capabilities **caps, const char **src_caps, size_t src_caps_len); int merge_sysctls(oci_runtime_spec *oci_spec, const json_map_string_string *sysctls); int merge_no_new_privileges(oci_runtime_spec *oci_spec, bool value); int adapt_settings_for_system_container(oci_runtime_spec *oci_spec, const host_config *host_spec); int merge_seccomp(oci_runtime_spec *oci_spec, const char *seccomp_profile); +#ifdef ENABLE_SELINUX int merge_selinux(oci_runtime_spec *oci_spec, container_config_v2_common_config *v2_spec); +#endif #endif diff --git a/src/daemon/modules/spec/verify.c b/src/daemon/modules/spec/verify.c index b257def..ac7f277 100644 --- a/src/daemon/modules/spec/verify.c +++ b/src/daemon/modules/spec/verify.c @@ -765,37 +765,12 @@ out: return ret; } -static inline bool is_hostconfig_blkio_weight_invalid(uint16_t weight) -{ - return weight > 0 && (weight < 10 || weight > 1000); -} - -/* verify hostconfig blkio weight */ -static int verify_hostconfig_blkio_weight(const sysinfo_t *sysinfo, uint16_t weight) -{ - int ret = 0; - - if (weight > 0 && !(sysinfo->blkioinfo.blkio_weight)) { - ERROR("Your kernel does not support Block I/O weight. Weight in host config discarded."); - isulad_set_error_message("Your kernel does not support Block I/O weight. Weight in host config discarded."); - ret = -1; - goto out; - } - if (is_hostconfig_blkio_weight_invalid(weight)) { - ERROR("Range of blkio weight is from 10 to 1000."); - isulad_set_error_message("Range of blkio weight is from 10 to 1000."); - ret = -1; - goto out; - } - -out: - return ret; -} - /* verify blkio device */ -static int verify_blkio_device(const sysinfo_t *sysinfo, size_t weight_device_len) +static int verify_blkio_device(const sysinfo_t *sysinfo, const defs_block_io_device_weight **weight_device, + size_t weight_device_len) { int ret = 0; + size_t i = 0; if (weight_device_len > 0 && !(sysinfo->blkioinfo.blkio_weight_device)) { ERROR("Your kernel does not support Block I/O weight_device."); @@ -803,6 +778,16 @@ static int verify_blkio_device(const sysinfo_t *sysinfo, size_t weight_device_le ret = -1; } + for (i = 0; i < weight_device_len; i++) { + if (is_blkio_weight_invalid(weight_device[i]->weight)) { + ERROR("Range of blkio weight is from 10 to 1000."); + isulad_set_error_message("Range of blkio weight is from 10 to 1000."); + ret = -1; + goto out; + } + } + +out: return ret; } @@ -929,7 +914,8 @@ static int verify_resources_blkio(const sysinfo_t *sysinfo, const defs_resources goto out; } - ret = verify_blkio_device(sysinfo, blkio->weight_device_len); + ret = verify_blkio_device(sysinfo, (const defs_block_io_device_weight **)blkio->weight_device, + blkio->weight_device_len); if (ret != 0) { goto out; } @@ -1028,7 +1014,7 @@ static int verify_resources_hugetlbs(const sysinfo_t *sysinfo, defs_resources_hu } newsize = sizeof(defs_resources_hugepage_limits_element *) * (newlen + 1); oldsize = newsize - sizeof(defs_resources_hugepage_limits_element *); - ret = mem_realloc((void **)&tmphugetlb, newsize, newhugetlb, oldsize); + ret = util_mem_realloc((void **)&tmphugetlb, newsize, newhugetlb, oldsize); if (ret < 0) { free(pagesize); ERROR("Out of memory"); @@ -1147,7 +1133,7 @@ static bool verify_oci_linux_sysctl(const oci_runtime_config_linux *l) } for (i = 0; i < l->sysctl->len; i++) { if (strcmp("kernel.pid_max", l->sysctl->keys[i]) == 0) { - if (!pid_max_kernel_namespaced()) { + if (!util_check_pid_max_kernel_namespaced()) { isulad_set_error_message("Sysctl '%s' is not kernel namespaced, it cannot be changed", l->sysctl->keys[i]); return false; @@ -1155,7 +1141,7 @@ static bool verify_oci_linux_sysctl(const oci_runtime_config_linux *l) return true; } } - if (!check_sysctl_valid(l->sysctl->keys[i])) { + if (!util_valid_sysctl(l->sysctl->keys[i])) { isulad_set_error_message("Sysctl %s=%s is not whitelist", l->sysctl->keys[i], l->sysctl->values[i]); return false; } @@ -1484,7 +1470,7 @@ static int verify_process_env(const defs_process *process) char *new_env = NULL; for (i = 0; i < process->env_len; i++) { - if (util_validate_env(process->env[i], &new_env) != 0) { + if (util_valid_env(process->env[i], &new_env) != 0) { ERROR("Invalid environment %s", process->env[i]); isulad_set_error_message("Invalid environment %s", process->env[i]); ret = -1; @@ -1619,7 +1605,7 @@ static int append_hugetlb_array(host_config_hugetlbs_element ***hugetlb, size_t newsize = sizeof(host_config_hugetlbs_element *) * (len + 1); oldsize = newsize - sizeof(host_config_hugetlbs_element *); - ret = mem_realloc((void **)&tmphugetlb, newsize, *hugetlb, oldsize); + ret = util_mem_realloc((void **)&tmphugetlb, newsize, *hugetlb, oldsize); if (ret < 0) { return -1; } @@ -1738,10 +1724,58 @@ out: return ret; } +static int verify_nano_cpus(const sysinfo_t *sysinfo, const host_config *hostconfig) +{ + int ret = 0; + + if (hostconfig->nano_cpus == 0) { + return 0; + } + + if (hostconfig->nano_cpus > 0 && hostconfig->cpu_period > 0) { + ERROR("Conflicting options: Nano CPUs and CPU Period cannot both be set."); + isulad_set_error_message("Conflicting options: Nano CPUs and CPU Period cannot both be set."); + ret = -1; + goto out; + } + + if (hostconfig->nano_cpus > 0 && hostconfig->cpu_quota > 0) { + ERROR("Conflicting options: Nano CPUs and CPU Quota cannot both be set."); + isulad_set_error_message("Conflicting options: Nano CPUs and CPU Quota cannot both be set."); + ret = -1; + goto out; + } + + if (hostconfig->nano_cpus > 0 && (!(sysinfo->cgcpuinfo.cpu_cfs_quota) || !(sysinfo->cgcpuinfo.cpu_cfs_period))) { + ERROR("NanoCPUs can not be set, as your kernel does not support CPU cfs period/quota or the cgroup is not mounted."); + isulad_set_error_message( + "NanoCPUs can not be set, as your kernel does not support CPU cfs period/quota or the cgroup is not mounted."); + ret = -1; + goto out; + } + + if (hostconfig->nano_cpus < 0 || (hostconfig->nano_cpus > (sysinfo->ncpus * 1e9))) { + ERROR("Range of CPUs is from 0.01 to %d.00, as there are only %d CPUs available", sysinfo->ncpus, + sysinfo->ncpus); + isulad_set_error_message("Range of CPUs is from 0.01 to %d.00, as there are only %d CPUs available", + sysinfo->ncpus, sysinfo->ncpus); + ret = -1; + goto out; + } + +out: + return ret; +} + static int host_config_settings_cpu(const sysinfo_t *sysinfo, const host_config *hostconfig) { int ret = 0; + ret = verify_nano_cpus(sysinfo, hostconfig); + if (ret != 0) { + goto out; + } + ret = verify_cpu_realtime(sysinfo, hostconfig->cpu_realtime_period, hostconfig->cpu_realtime_runtime); if (ret != 0) { goto out; @@ -1771,12 +1805,25 @@ static int host_config_settings_blkio(const sysinfo_t *sysinfo, const host_confi { int ret = 0; - ret = verify_hostconfig_blkio_weight(sysinfo, hostconfig->blkio_weight); + ret = verify_blkio_weight(sysinfo, hostconfig->blkio_weight); if (ret != 0) { goto out; } - ret = verify_blkio_device(sysinfo, hostconfig->blkio_weight_device_len); + ret = verify_blkio_device(sysinfo, (const defs_block_io_device_weight **)hostconfig->blkio_weight_device, + hostconfig->blkio_weight_device_len); + if (ret != 0) { + goto out; + } + + ret = verify_blkio_rw_bps_device(sysinfo, hostconfig->blkio_device_read_bps_len, + hostconfig->blkio_device_write_bps_len); + if (ret != 0) { + goto out; + } + + ret = verify_blkio_rw_iops_device(sysinfo, hostconfig->blkio_device_read_iops_len, + hostconfig->blkio_device_write_iops_len); if (ret != 0) { goto out; } @@ -1904,6 +1951,25 @@ out: return ret; } +/* verify device cgroup rule */ +static int verify_host_config_device_cgroup_rules(const host_config *hostconfig) +{ + int ret = 0; + size_t i = 0; + + for (i = 0; i < hostconfig->device_cgroup_rules_len; i++) { + if (!util_valid_device_cgroup_rule(hostconfig->device_cgroup_rules[i])) { + ERROR("Invalid device cgroup rule %s", hostconfig->device_cgroup_rules[i]); + isulad_set_error_message("Invalid device cgroup rule %s", hostconfig->device_cgroup_rules[i]); + ret = -1; + goto out; + } + } + +out: + return ret; +} + /* verify host config settings */ int verify_host_config_settings(host_config *hostconfig, bool update) { @@ -1930,6 +1996,11 @@ int verify_host_config_settings(host_config *hostconfig, bool update) goto out; } + ret = verify_host_config_device_cgroup_rules(hostconfig); + if (ret != 0) { + goto out; + } + #ifdef ENABLE_OCI_IMAGE // storage options ret = verify_storage_opts(hostconfig); @@ -1942,6 +2013,7 @@ out: return ret; } +#ifdef ENABLE_SELINUX static int relabel_mounts_if_needed(defs_mount **mounts, size_t len, const char *mount_label) { int ret = 0; @@ -1976,6 +2048,7 @@ static int relabel_mounts_if_needed(defs_mount **mounts, size_t len, const char out: return ret; } +#endif /* verify container settings start */ int verify_container_settings_start(const oci_runtime_spec *oci_spec) @@ -1989,11 +2062,13 @@ int verify_container_settings_start(const oci_runtime_spec *oci_spec) ret = -1; goto out; } +#ifdef ENABLE_SELINUX if (relabel_mounts_if_needed(oci_spec->mounts, oci_spec->mounts_len, oci_spec->linux->mount_label) != 0) { ERROR("Failed to relabel mount"); ret = -1; goto out; } +#endif } out: diff --git a/src/utils/cutils/map/rb_tree.c b/src/utils/cutils/map/rb_tree.c index 30f5330..ddae064 100644 --- a/src/utils/cutils/map/rb_tree.c +++ b/src/utils/cutils/map/rb_tree.c @@ -106,16 +106,16 @@ rb_tree_t *rbtree_new(key_comparator comparator, key_value_freer kvfreer) return tree; } -static void rbtree_destory_all(rb_tree_t *tree, rb_node_t *node) +static void rbtree_destroy_all(rb_tree_t *tree, rb_node_t *node) { if (node == tree->nil) { return; } if (node->left != tree->nil) { - rbtree_destory_all(tree, node->left); + rbtree_destroy_all(tree, node->left); } if (node->right != tree->nil) { - rbtree_destory_all(tree, node->right); + rbtree_destroy_all(tree, node->right); } if (tree->kvfreer != NULL) { tree->kvfreer(node->key, node->value); @@ -128,7 +128,7 @@ void rbtree_clear(rb_tree_t *tree) if (tree == NULL) { return; } - rbtree_destory_all(tree, tree->root); + rbtree_destroy_all(tree, tree->root); } void rbtree_free(rb_tree_t *tree) diff --git a/src/utils/cutils/namespace.c b/src/utils/cutils/namespace.c index 202dc55..2916c8b 100644 --- a/src/utils/cutils/namespace.c +++ b/src/utils/cutils/namespace.c @@ -18,18 +18,18 @@ #include "utils.h" -char *connected_container(const char *mode) +char *namespace_get_connected_container(const char *mode) { const char *p = mode != NULL ? (mode + strlen(SHARE_NAMESPACE_PREFIX)) : NULL; - if (is_container(mode)) { + if (namespace_is_container(mode)) { return util_strdup_s(p); } return NULL; } -char *get_host_namespace_path(const char *type) +char *namespace_get_host_namespace_path(const char *type) { if (type == NULL) { return NULL; diff --git a/src/utils/cutils/namespace.h b/src/utils/cutils/namespace.h index 8d7e41a..cf76805 100644 --- a/src/utils/cutils/namespace.h +++ b/src/utils/cutils/namespace.h @@ -58,7 +58,7 @@ typedef enum { #define ETC_HOSTNAME "/etc/hostname" #define RESOLV_CONF_PATH "/etc/resolv.conf" -static inline bool is_host(const char *mode) +static inline bool namespace_is_host(const char *mode) { if (mode != NULL && strcmp(mode, SHARE_NAMESPACE_HOST) == 0) { return true; @@ -66,7 +66,7 @@ static inline bool is_host(const char *mode) return false; } -static inline bool is_none(const char *mode) +static inline bool namespace_is_none(const char *mode) { if (mode != NULL && strcmp(mode, SHARE_NAMESPACE_NONE) == 0) { return true; @@ -74,7 +74,7 @@ static inline bool is_none(const char *mode) return false; } -static inline bool is_container(const char *mode) +static inline bool namespace_is_container(const char *mode) { if (mode != NULL && strncmp(mode, SHARE_NAMESPACE_PREFIX, strlen(SHARE_NAMESPACE_PREFIX)) == 0) { return true; @@ -82,7 +82,7 @@ static inline bool is_container(const char *mode) return false; } -static inline bool is_shareable(const char *mode) +static inline bool namespace_is_shareable(const char *mode) { if (mode != NULL && strcmp(mode, SHARE_NAMESPACE_SHAREABLE) == 0) { return true; @@ -90,8 +90,8 @@ static inline bool is_shareable(const char *mode) return false; } -char *connected_container(const char *mode); -char *get_host_namespace_path(const char *type); +char *namespace_get_connected_container(const char *mode); +char *namespace_get_host_namespace_path(const char *type); #ifdef __cplusplus } diff --git a/src/utils/cutils/path.c b/src/utils/cutils/path.c index 8bf9b67..533480a 100644 --- a/src/utils/cutils/path.c +++ b/src/utils/cutils/path.c @@ -90,7 +90,7 @@ static int do_clean_path(const char *respath, const char *limit_respath, const c return 0; } -char *cleanpath(const char *path, char *realpath, size_t realpath_len) +char *util_clean_path(const char *path, char *realpath, size_t realpath_len) { char *respath = NULL; char *dest = NULL; @@ -168,7 +168,7 @@ static int do_path_realloc(const char *start, const char *end, char **rpath, cha } else { new_size += PATH_MAX; } - nret = mem_realloc((void **)(&new_rpath), new_size, *rpath, PATH_MAX); + nret = util_mem_realloc((void **)(&new_rpath), new_size, *rpath, PATH_MAX); if (nret) { ERROR("Failed to realloc memory for files limit variables"); return -1; @@ -363,7 +363,7 @@ static char *eval_symlinks_in_scope(const char *fullpath, const char *rootpath) return NULL; } - root = cleanpath(rootpath, resroot, sizeof(resroot)); + root = util_clean_path(rootpath, resroot, sizeof(resroot)); if (root == NULL) { ERROR("Failed to get cleaned path"); return NULL; @@ -418,20 +418,20 @@ out: return NULL; } -char *follow_symlink_in_scope(const char *fullpath, const char *rootpath) +char *util_follow_symlink_in_scope(const char *fullpath, const char *rootpath) { char resfull[PATH_MAX] = { 0 }; char *full = NULL; char resroot[PATH_MAX] = { 0 }; char *root = NULL; - full = cleanpath(fullpath, resfull, sizeof(resfull)); + full = util_clean_path(fullpath, resfull, sizeof(resfull)); if (full == NULL) { ERROR("Failed to get cleaned path"); return NULL; } - root = cleanpath(rootpath, resroot, sizeof(resroot)); + root = util_clean_path(rootpath, resroot, sizeof(resroot)); if (root == NULL) { ERROR("Failed to get cleaned path"); return NULL; @@ -440,7 +440,7 @@ char *follow_symlink_in_scope(const char *fullpath, const char *rootpath) return eval_symlinks_in_scope(full, root); } -bool specify_current_dir(const char *path) +bool util_specify_current_dir(const char *path) { char *dup = NULL; char *base = NULL; @@ -461,7 +461,7 @@ bool specify_current_dir(const char *path) return res; } -bool has_trailing_path_separator(const char *path) +bool util_has_trailing_path_separator(const char *path) { return path != NULL && strlen(path) > 0 && (path[strlen(path) - 1] == '/'); } @@ -471,7 +471,7 @@ static void set_char_to_separator(char *p) *p = '/'; } -char *preserve_trailing_dot_or_separator(const char *cleanedpath, const char *originalpath) +char *util_preserve_trailing_dot_or_separator(const char *cleanedpath, const char *originalpath) { int nret; char respath[PATH_MAX + 3] = { 0 }; @@ -490,21 +490,21 @@ char *preserve_trailing_dot_or_separator(const char *cleanedpath, const char *or return NULL; } - if (!specify_current_dir(cleanedpath) && specify_current_dir(originalpath)) { - if (!has_trailing_path_separator(respath)) { + if (!util_specify_current_dir(cleanedpath) && util_specify_current_dir(originalpath)) { + if (!util_has_trailing_path_separator(respath)) { set_char_to_separator(&respath[strlen(respath)]); } respath[strlen(respath)] = '.'; } - if (!has_trailing_path_separator(respath) && has_trailing_path_separator(originalpath)) { + if (!util_has_trailing_path_separator(respath) && util_has_trailing_path_separator(originalpath)) { set_char_to_separator(&respath[strlen(respath)]); } return util_strdup_s(respath); } -int filepath_split(const char *path, char **dir, char **base) +int util_filepath_split(const char *path, char **dir, char **base) { ssize_t i; char *dup = NULL; @@ -539,7 +539,7 @@ int filepath_split(const char *path, char **dir, char **base) return 0; } -int split_dir_and_base_name(const char *path, char **dir, char **base) +int util_split_dir_and_base_name(const char *path, char **dir, char **base) { char *dupdir = NULL; char *dupbase = NULL; @@ -561,7 +561,7 @@ int split_dir_and_base_name(const char *path, char **dir, char **base) return 0; } -char *get_resource_path(const char *rootpath, const char *path) +char *util_get_resource_path(const char *rootpath, const char *path) { int nret; char tmppath[PATH_MAX] = { 0 }; @@ -572,14 +572,14 @@ char *get_resource_path(const char *rootpath, const char *path) return NULL; } - if (cleanpath(tmppath, fullpath, sizeof(fullpath)) == NULL) { + if (util_clean_path(tmppath, fullpath, sizeof(fullpath)) == NULL) { return NULL; } - return follow_symlink_in_scope(fullpath, rootpath); + return util_follow_symlink_in_scope(fullpath, rootpath); } -int resolve_path(const char *rootpath, const char *path, char **resolvedpath, char **abspath) +int util_resolve_path(const char *rootpath, const char *path, char **resolvedpath, char **abspath) { int ret = -1; int nret; @@ -599,24 +599,24 @@ int resolve_path(const char *rootpath, const char *path, char **resolvedpath, ch return -1; } - if (cleanpath(tmppath, cleanedpath, sizeof(cleanedpath)) == NULL) { + if (util_clean_path(tmppath, cleanedpath, sizeof(cleanedpath)) == NULL) { ERROR("Failed to get cleaned path: %s", tmppath); return -1; } - *abspath = preserve_trailing_dot_or_separator(cleanedpath, tmppath); + *abspath = util_preserve_trailing_dot_or_separator(cleanedpath, tmppath); if (*abspath == NULL) { ERROR("Failed to preserve path"); goto cleanup; } - nret = filepath_split(*abspath, &dirpath, &basepath); + nret = util_filepath_split(*abspath, &dirpath, &basepath); if (nret < 0) { ERROR("Failed to split path"); goto cleanup; } - resolved_dir_path = get_resource_path(rootpath, dirpath); + resolved_dir_path = util_get_resource_path(rootpath, dirpath); if (resolved_dir_path == NULL) { ERROR("Failed to get resource path"); goto cleanup; @@ -648,17 +648,17 @@ cleanup: return ret; } -int split_path_dir_entry(const char *path, char **dir, char **base) +int util_split_path_dir_entry(const char *path, char **dir, char **base) { #define EXTRA_LEN 3 char cleaned[PATH_MAX + EXTRA_LEN] = { 0 }; char *dup = NULL; - if (cleanpath(path, cleaned, PATH_MAX) == NULL) { + if (util_clean_path(path, cleaned, PATH_MAX) == NULL) { ERROR("Failed to clean path"); return -1; } - if (specify_current_dir(path)) { + if (util_specify_current_dir(path)) { set_char_to_separator(&cleaned[strlen(cleaned)]); cleaned[strlen(cleaned)] = '.'; } @@ -694,7 +694,7 @@ static char *find_realpath(const char *path) } // is not absolutely path if (target[0] != '\0' && target[0] != '/') { - if (split_path_dir_entry(iter_path, &parent, NULL) < 0) { + if (util_split_path_dir_entry(iter_path, &parent, NULL) < 0) { goto out; } free(iter_path); @@ -721,7 +721,7 @@ out: return NULL; } -int realpath_in_scope(const char *rootfs, const char *path, char **real_path) +int util_realpath_in_scope(const char *rootfs, const char *path, char **real_path) { int ret = 0; char full_path[PATH_MAX] = { 0 }; @@ -734,7 +734,7 @@ int realpath_in_scope(const char *rootfs, const char *path, char **real_path) ret = -1; goto out; } - if (cleanpath(full_path, cleaned, PATH_MAX) == NULL) { + if (util_clean_path(full_path, cleaned, PATH_MAX) == NULL) { ERROR("Failed to clean path: %s", full_path); ret = -1; goto out; diff --git a/src/utils/cutils/path.h b/src/utils/cutils/path.h index 21986ec..7f926b2 100644 --- a/src/utils/cutils/path.h +++ b/src/utils/cutils/path.h @@ -22,34 +22,33 @@ extern "C" { #endif /* - * cleanpath is similar to realpath of glibc, but not expands symbolic links, + * util_clean_path is similar to realpath of glibc, but not expands symbolic links, * and not check the existence of components of the path. */ -char *cleanpath(const char *path, char *realpath, size_t realpath_len); +char *util_clean_path(const char *path, char *realpath, size_t realpath_len); -bool specify_current_dir(const char *path); +bool util_specify_current_dir(const char *path); -char *follow_symlink_in_scope(const char *fullpath, const char *rootpath); +char *util_follow_symlink_in_scope(const char *fullpath, const char *rootpath); -int split_dir_and_base_name(const char *path, char **dir, char **base); +int util_split_dir_and_base_name(const char *path, char **dir, char **base); -int filepath_split(const char *path, char **dir, char **base); +int util_filepath_split(const char *path, char **dir, char **base); -char *get_resource_path(const char *rootpath, const char *path); +char *util_get_resource_path(const char *rootpath, const char *path); -int resolve_path(const char *rootpath, const char *path, char **resolvedpath, char **abspath); +int util_resolve_path(const char *rootpath, const char *path, char **resolvedpath, char **abspath); -bool has_trailing_path_separator(const char *path); +bool util_has_trailing_path_separator(const char *path); -char *preserve_trailing_dot_or_separator(const char *cleanedpath, const char *originalpath); +char *util_preserve_trailing_dot_or_separator(const char *cleanedpath, const char *originalpath); -int split_path_dir_entry(const char *path, char **dir, char **base); +int util_split_path_dir_entry(const char *path, char **dir, char **base); -int realpath_in_scope(const char *rootfs, const char *path, char **real_path); +int util_realpath_in_scope(const char *rootfs, const char *path, char **real_path); #ifdef __cplusplus } #endif #endif - diff --git a/src/utils/cutils/utils.c b/src/utils/cutils/utils.c index e9ef33b..a7a4150 100644 --- a/src/utils/cutils/utils.c +++ b/src/utils/cutils/utils.c @@ -45,9 +45,7 @@ #include "utils_string.h" #include "utils_verify.h" -#define MAX_NUM_STR_LEN 21 - -int mem_realloc(void **newptr, size_t newsize, void *oldptr, size_t oldsize) +int util_mem_realloc(void **newptr, size_t newsize, void *oldptr, size_t oldsize) { void *tmp = NULL; @@ -105,7 +103,7 @@ static int util_read_pipe(int pipe_fd, char **out_buf, size_t *out_buf_size, siz } new_size = old_size + PIPE_BUF + 1; - ret = mem_realloc((void *)(&tmp), new_size, (void *)buffer, old_size); + ret = util_mem_realloc((void *)(&tmp), new_size, (void *)buffer, old_size); if (ret != 0) { ERROR("Memory out"); ret = -1; @@ -244,20 +242,6 @@ int util_sig_parse(const char *sig_name) return -1; } -bool util_check_signal_valid(int sig) -{ - size_t i; - const struct signame signames[] = SIGNAL_MAP_DEFAULT; - - for (i = 0; i < sizeof(signames) / sizeof(signames[0]); i++) { - if (signames[i].num == sig) { - return true; - } - } - - return false; -} - void *util_smart_calloc_s(size_t unit_size, size_t count) { if (unit_size == 0) { @@ -296,7 +280,7 @@ char *util_strdup_s(const char *src) return dst; } -int wait_for_pid(pid_t pid) +int util_wait_for_pid(pid_t pid) { int st; int nret = 0; @@ -318,7 +302,7 @@ rep: return 0; } -int wait_for_pid_status(pid_t pid) +int util_wait_for_pid_status(pid_t pid) { int st; int nret = 0; @@ -706,12 +690,12 @@ bool util_exec_top_cmd(exec_top_func_t cb_func, char **args, const char *pid_arg if (stdout_close_flag != 0 && stderr_close_flag != 0) { break; } - usleep_nointerupt(1000); + util_usleep_nointerupt(1000); } marshal_stderr_msg(&stderr_buffer, &stderr_real_size); - status = wait_for_pid_status(pid); + status = util_wait_for_pid_status(pid); ret = deal_with_result_of_waitpid(status, &stderr_buffer, stderr_real_size); @@ -840,12 +824,12 @@ bool util_exec_cmd(exec_func_t cb_func, void *args, const char *stdin_msg, char if (stdout_close_flag != 0 && stderr_close_flag != 0) { break; } - usleep_nointerupt(1000); + util_usleep_nointerupt(1000); } marshal_stderr_msg(&stderr_buffer, &stderr_real_size); - status = wait_for_pid_status(pid); + status = util_wait_for_pid_status(pid); ret = deal_with_result_of_waitpid(status, &stderr_buffer, stderr_real_size); @@ -857,7 +841,7 @@ out: return ret; } -char **get_backtrace(void) +char **util_get_backtrace(void) { #define BACKTRACE_SIZE 16 int addr_cnts; @@ -877,78 +861,6 @@ char **get_backtrace(void) return syms; } -static long long get_time_unit(int unit) -{ - long long u[255] = { 0 }; - - u['M'] = Time_Milli; - u['s'] = Time_Second; - u['m'] = Time_Minute; - u['h'] = Time_Hour; - - return u[unit]; -} - -static int get_time_ns(long long *pns, long long unit) -{ - if (unit == 0) { - return -1; - } - - if (INT64_MAX / *pns >= unit) { - *pns *= unit; - return 0; - } - - return -1; -} - -int util_parse_time_str_to_nanoseconds(const char *value, int64_t *nanoseconds) -{ - int ret = 0; - long long tmp = 0; - char unit = 0; - size_t len = 0; - char *num_str = NULL; - - if (value == NULL || nanoseconds == NULL) { - return -1; - } - - if (util_reg_match("^([0-9]+)+(ms|s|m|h)$", value) != 0) { - return -1; - } - num_str = util_strdup_s(value); - len = strlen(value); - - if (strstr(value, "ms") == NULL) { - unit = *(value + len - 1); - *(num_str + len - 1) = '\0'; - } else { - unit = 'M'; - *(num_str + len - 2) = '\0'; - } - ret = util_safe_llong(num_str, &tmp); - if (ret < 0) { - ERROR("Illegal unsigned integer: %s", num_str); - ret = -1; - goto out; - } - if (tmp == 0) { - goto out; - } - - ret = get_time_ns(&tmp, get_time_unit(unit)); - if (ret != 0) { - ERROR("failed get nano seconds for %s", num_str); - } - *nanoseconds = (int64_t)tmp; - -out: - free(num_str); - return ret; -} - /* isulad: get starttime of process pid */ proc_t *util_get_process_proc_info(pid_t pid) { @@ -1031,7 +943,7 @@ int util_env_insert(char ***penv, size_t *penv_len, const char *key, size_t key_ return -1; } - ret = mem_realloc((void **)(&temp), (env_len + 1) * sizeof(char *), env, env_len * sizeof(char *)); + ret = util_mem_realloc((void **)(&temp), (env_len + 1) * sizeof(char *), env, env_len * sizeof(char *)); if (ret != 0) { ERROR("Failed to realloc memory for envionment variables"); return -1; @@ -1117,38 +1029,7 @@ out: return ret; } -char *util_str_token(char **input, const char *delimiter) -{ - char *str = NULL; - char *delimiter_found = NULL; - char *tok = NULL; - size_t tok_length = 0; - - if (input == NULL || delimiter == NULL) { - return NULL; - } - - str = *input; - - if (str == NULL) { - return NULL; - } - delimiter_found = strstr(str, delimiter); - if (delimiter_found != NULL) { - tok_length = delimiter_found - str; - } else { - tok_length = strlen(str); - } - tok = strndup(str, tok_length); - if (tok == NULL) { - ERROR("strndup failed"); - return NULL; - } - *input = delimiter_found != NULL ? delimiter_found + strlen(delimiter) : NULL; - return tok; -} - -bool pid_max_kernel_namespaced() +bool util_check_pid_max_kernel_namespaced() { bool ret = false; FILE *fp = NULL; @@ -1172,37 +1053,7 @@ out: return ret; } -bool check_sysctl_valid(const char *sysctl_key) -{ - size_t i = 0; - size_t full_keys_len = 0; - size_t key_prefixes_len = 0; - const char *sysctl_full_keys[] = { "kernel.msgmax", "kernel.msgmnb", "kernel.msgmni", "kernel.sem", - "kernel.shmall", "kernel.shmmax", "kernel.shmmni", "kernel.shm_rmid_forced" - }; - const char *sysctl_key_prefixes[] = { "net.", "fs.mqueue." }; - - if (sysctl_key == NULL) { - return false; - } - - full_keys_len = sizeof(sysctl_full_keys) / sizeof(char *); - key_prefixes_len = sizeof(sysctl_key_prefixes) / sizeof(char *); - - for (i = 0; i < full_keys_len; i++) { - if (strcmp(sysctl_full_keys[i], sysctl_key) == 0) { - return true; - } - } - for (i = 0; i < key_prefixes_len; i++) { - if (strncmp(sysctl_key_prefixes[i], sysctl_key, strlen(sysctl_key_prefixes[i])) == 0) { - return true; - } - } - return false; -} - -void free_sensitive_string(char *str) +void util_free_sensitive_string(char *str) { if (!util_valid_str(str)) { goto out; @@ -1214,7 +1065,7 @@ out: free(str); } -void memset_sensitive_string(char *str) +void util_memset_sensitive_string(char *str) { if (!util_valid_str(str)) { return; @@ -1223,113 +1074,6 @@ void memset_sensitive_string(char *str) (void)memset(str, 0, strlen(str)); } -static char *get_mtpoint(const char *line) -{ - int i; - const char *tmp = NULL; - char *pend = NULL; - char *sret = NULL; - size_t len; - - if (line == NULL) { - goto err_out; - } - - tmp = line; - - for (i = 0; i < 4; i++) { - tmp = strchr(tmp, ' '); - if (tmp == NULL) { - goto err_out; - } - tmp++; - } - pend = strchr(tmp, ' '); - if ((pend == NULL) || pend == tmp) { - goto err_out; - } - - /* stuck a \0 after the mountpoint */ - len = (size_t)(pend - tmp); - sret = util_common_calloc_s(len + 1); - if (sret == NULL) { - goto err_out; - } - (void)memcpy(sret, tmp, len); - sret[len] = '\0'; - -err_out: - return sret; -} - -bool detect_mount(const char *path) -{ - FILE *fp = NULL; - char *line = NULL; - char *mountpoint = NULL; - size_t length = 0; - bool bret = false; - - fp = util_fopen("/proc/self/mountinfo", "r"); - if (fp == NULL) { - ERROR("Failed opening /proc/self/mountinfo"); - return false; - } - - while (getline(&line, &length, fp) != -1) { - mountpoint = get_mtpoint(line); - if (mountpoint == NULL) { - INFO("Error reading mountinfo: bad line '%s'", line); - continue; - } - if (strcmp(mountpoint, path) == 0) { - free(mountpoint); - bret = true; - goto out; - } - free(mountpoint); - } -out: - fclose(fp); - free(line); - return bret; -} - -bool util_deal_with_mount_info(mount_info_call_back_t cb, const char *pattern) -{ - FILE *fp = NULL; - char *line = NULL; - char *mountpoint = NULL; - size_t length = 0; - bool bret = true; - int nret = 0; - - fp = util_fopen("/proc/self/mountinfo", "r"); - if (fp == NULL) { - ERROR("Failed opening /proc/self/mountinfo"); - return false; - } - - while (getline(&line, &length, fp) != -1) { - mountpoint = get_mtpoint(line); - if (mountpoint == NULL) { - INFO("Error reading mountinfo: bad line '%s'", line); - continue; - } - nret = cb(mountpoint, pattern); - free(mountpoint); - if (nret != 0) { - bret = false; - goto out; - } - } - -out: - fclose(fp); - free(line); - return bret; -} - static int set_echo_back(bool echo_back) { struct termios old, new; @@ -1429,7 +1173,7 @@ static int util_input(char *buf, size_t maxlen, bool echo_back) return ret; } -// Get input from stdin, echo back if get any charactor. +// Get input from stdin, echo back if get any character. int util_input_echo(char *buf, size_t maxlen) { return util_input(buf, maxlen, true); @@ -1441,7 +1185,7 @@ int util_input_noecho(char *buf, size_t maxlen) return util_input(buf, maxlen, false); } -void usleep_nointerupt(unsigned long usec) +void util_usleep_nointerupt(unsigned long usec) { #define SECOND_TO_USECOND_MUTIPLE 1000000 int ret = 0; @@ -1492,71 +1236,6 @@ int util_generate_random_str(char *id, size_t len) return 0; } -void add_array_elem(char **array, size_t total, size_t *pos, const char *elem) -{ - if (*pos + 1 >= total - 1) { - return; - } - array[*pos] = util_strdup_s(elem); - *pos += 1; -} - -void add_array_kv(char **array, size_t total, size_t *pos, const char *k, const char *v) -{ - if (k == NULL || v == NULL) { - return; - } - add_array_elem(array, total, pos, k); - add_array_elem(array, total, pos, v); -} - -int util_validate_env(const char *env, char **dst) -{ - int ret = 0; - char *value = NULL; - - char **arr = util_string_split_multi(env, '='); - if (arr == NULL) { - ERROR("Failed to split env string"); - return -1; - } - if (strlen(arr[0]) == 0) { - ERROR("Invalid environment variable: %s", env); - ret = -1; - goto out; - } - - if (util_array_len((const char **)arr) > 1) { - *dst = util_strdup_s(env); - goto out; - } - - value = getenv(env); - if (value == NULL) { - *dst = NULL; - goto out; - } else { - int sret; - size_t len = strlen(env) + 1 + strlen(value) + 1; - *dst = (char *)util_common_calloc_s(len); - if (*dst == NULL) { - ERROR("Out of memory"); - ret = -1; - goto out; - } - sret = snprintf(*dst, len, "%s=%s", env, value); - if (sret < 0 || (size_t)sret >= len) { - ERROR("Failed to compose env string"); - ret = -1; - goto out; - } - } - -out: - util_free_array(arr); - return ret; -} - int util_check_inherited_exclude_fds(bool closeall, int *fds_to_ignore, size_t len_fds) { struct dirent *pdirent = NULL; @@ -1613,42 +1292,6 @@ restart: return 0; } -int get_cpu_num_cores(void) -{ - int ncpus = (int)sysconf(_SC_NPROCESSORS_ONLN); - if (ncpus < 1) { - ERROR("Cannot determine number of CPUs: assuming 1\n"); - ncpus = 1; - } - return ncpus; -} - -char *util_uint_to_string(long long unsigned int data) -{ - char numstr[MAX_NUM_STR_LEN] = { 0 }; - int ret; - - ret = snprintf(numstr, sizeof(numstr), "%llu", data); - if (ret < 0 || (size_t)ret >= sizeof(numstr)) { - return NULL; - } - - return util_strdup_s(numstr); -} - -char *util_int_to_string(long long int data) -{ - char numstr[MAX_NUM_STR_LEN] = { 0 }; - int ret; - - ret = snprintf(numstr, sizeof(numstr), "%lld", data); - if (ret < 0 || (size_t)ret >= sizeof(numstr)) { - return NULL; - } - - return util_strdup_s(numstr); -} - static char *get_cpu_variant() { char *variant = NULL; @@ -1679,7 +1322,7 @@ static char *get_cpu_variant() util_trim_newline(start_pos); start_pos = util_trim_space(start_pos); - variant = strings_to_lower(start_pos); + variant = util_strings_to_lower(start_pos); out: free(cpuinfo); @@ -1688,7 +1331,7 @@ out: return variant; } -int normalized_host_os_arch(char **host_os, char **host_arch, char **host_variant) +int util_normalized_host_os_arch(char **host_os, char **host_arch, char **host_variant) { int ret = 0; struct utsname uts; @@ -1705,7 +1348,7 @@ int normalized_host_os_arch(char **host_os, char **host_arch, char **host_varian goto out; } - *host_os = strings_to_lower(uts.sysname); + *host_os = util_strings_to_lower(uts.sysname); if (strcasecmp("i386", uts.machine) == 0) { *host_arch = util_strdup_s("386"); @@ -1792,4 +1435,41 @@ out: free(proc); free(p_proc); return ret; +} + +void util_parse_user_group(const char *username, char **user, char **group, char **tmp_dup) +{ + char *tmp = NULL; + char *pdot = NULL; + + if (user == NULL || group == NULL || tmp_dup == NULL) { + return; + } + + if (username != NULL) { + tmp = util_strdup_s(username); + + // for free tmp in caller + *tmp_dup = tmp; + + pdot = strstr(tmp, ":"); + if (pdot != NULL) { + *pdot = '\0'; + if (pdot != tmp) { + // User found + *user = tmp; + } + if (*(pdot + 1) != '\0') { + // group found + *group = pdot + 1; + } + } else { + // No : found + if (*tmp != '\0') { + *user = tmp; + } + } + } + + return; } \ No newline at end of file diff --git a/src/utils/cutils/utils.h b/src/utils/cutils/utils.h index ca3afb1..1ee0b14 100644 --- a/src/utils/cutils/utils.h +++ b/src/utils/cutils/utils.h @@ -106,31 +106,11 @@ extern "C" { #define SIZE_TB (1024LL * SIZE_GB) #define SIZE_PB (1024LL * SIZE_TB) -#define Time_Nano 1LL -#define Time_Micro (1000LL * Time_Nano) -#define Time_Milli (1000LL * Time_Micro) -#define Time_Second (1000LL * Time_Milli) -#define Time_Minute (60LL * Time_Second) -#define Time_Hour (60LL * Time_Minute) - /* Max regular file size for isula\isulad to open as same as docker */ #define REGULAR_FILE_SIZE (10 * SIZE_MB) -#define rFC339Local "2006-01-02T15:04:05" -#define rFC339NanoLocal "2006-01-02T15:04:05.999999999" -#define dateLocal "2006-01-02" -#define defaultContainerTime "0001-01-01T00:00:00Z" #define TIME_STR_SIZE 512 -#define HOST_NAME_REGEXP \ - "^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]*[a-zA-Z0-9])\\.)*" \ - "([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\\-]*[A-Za-z0-9])$" -#define __TagPattern "^:([A-Za-z_0-9][A-Za-z_0-9.-]{0,127})$" -#define __NamePattern \ - "^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])" \ - "((\\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+)?(:[0-9]+)?/)?[a-z0-9]" \ - "+((([._]|__|[-]*)[a-z0-9]+)+)?((/[a-z0-9]+((([._]|__|[-]*)[a-z0-9]+)+)?)+)?$" - // native umask value #define ANNOTATION_UMAKE_KEY "native.umask" #define UMASK_NORMAL "normal" @@ -319,7 +299,7 @@ struct signame { } \ } while (0) -int mem_realloc(void **newptr, size_t newsize, void *oldptr, size_t oldsize); +int util_mem_realloc(void **newptr, size_t newsize, void *oldptr, size_t oldsize); int util_check_inherited(bool closeall, int fd_to_ignore); @@ -331,7 +311,7 @@ void *util_common_calloc_s(size_t size); char *util_strdup_s(const char *src); -int wait_for_pid(pid_t pid); +int util_wait_for_pid(pid_t pid); void util_contain_errmsg(const char *errmsg, int *exit_code); @@ -343,7 +323,7 @@ proc_t *util_stat2proc(const char *s, size_t len); bool util_process_alive(pid_t pid, unsigned long long start_time); -int wait_for_pid_status(pid_t pid); +int util_wait_for_pid_status(pid_t pid); typedef void (*exec_func_t)(void *args); bool util_exec_cmd(exec_func_t cb_func, void *args, const char *stdin_msg, char **stdout_msg, char **stderr_msg); @@ -352,9 +332,7 @@ typedef void (*exec_top_func_t)(char **args, const char *pid_args, size_t args_l bool util_exec_top_cmd(exec_top_func_t cb_func, char **args, const char *pid_args, size_t args_len, char **stdout_msg, char **stderr_msg); -char **get_backtrace(void); - -int util_parse_time_str_to_nanoseconds(const char *value, int64_t *nanoseconds); +char **util_get_backtrace(void); proc_t *util_get_process_proc_info(pid_t pid); @@ -364,47 +342,29 @@ int util_env_insert(char ***penv, size_t *penv_len, const char *key, size_t key_ int util_env_set_val(char ***penv, const size_t *penv_len, const char *key, size_t key_len, const char *newkv); char *util_env_get_val(char **env, size_t env_len, const char *key, size_t key_len); -char *util_str_token(char **input, const char *delimiter); -bool check_sysctl_valid(const char *sysctl_key); -bool pid_max_kernel_namespaced(); -void free_sensitive_string(char *str); -void memset_sensitive_string(char *str); +bool util_check_pid_max_kernel_namespaced(); + +void util_free_sensitive_string(char *str); +void util_memset_sensitive_string(char *str); int util_input_readall(char *buf, size_t maxlen); int util_input_echo(char *buf, size_t maxlen); int util_input_noecho(char *buf, size_t maxlen); -bool util_check_signal_valid(int sig); - -void usleep_nointerupt(unsigned long usec); +void util_usleep_nointerupt(unsigned long usec); int util_generate_random_str(char *id, size_t len); -void add_array_elem(char **array, size_t total, size_t *pos, const char *elem); - -void add_array_kv(char **array, size_t total, size_t *pos, const char *k, const char *v); - -typedef int (*mount_info_call_back_t)(const char *, const char *); -bool util_deal_with_mount_info(mount_info_call_back_t cb, const char *); - -int util_validate_env(const char *env, char **dst); - int util_check_inherited_exclude_fds(bool closeall, int *fds_to_ignore, size_t len_fds); -int get_cpu_num_cores(void); - -char *util_uint_to_string(long long unsigned int data); - -char *util_int_to_string(long long int data); +char *util_without_sha256_prefix(char *digest); -char *without_sha256_prefix(char *digest); - -int normalized_host_os_arch(char **host_os, char **host_arch, char **host_variant); - -char *util_full_digest_str(char *str); +int util_normalized_host_os_arch(char **host_os, char **host_arch, char **host_variant); int util_read_pid_ppid_info(uint32_t pid, pid_ppid_info_t *pid_info); +void util_parse_user_group(const char *username, char **user, char **group, char **tmp_dup); + #ifdef __cplusplus } #endif diff --git a/src/utils/cutils/utils_convert.c b/src/utils/cutils/utils_convert.c index c14e147..077b062 100644 --- a/src/utils/cutils/utils_convert.c +++ b/src/utils/cutils/utils_convert.c @@ -20,6 +20,10 @@ #include #include #include +#include +#include "utils.h" + +#define MAX_NUM_STR_LEN 21 static inline bool is_invalid_error_str(const char *err_str, const char *numstr) { @@ -107,6 +111,29 @@ int util_safe_uint(const char *numstr, unsigned int *converted) return 0; } +int util_safe_uint64(const char *numstr, uint64_t *converted) +{ + char *err_str = NULL; + uint64_t ull; + + if (numstr == NULL || converted == NULL) { + return -EINVAL; + } + + errno = 0; + ull = strtoull(numstr, &err_str, 0); + if (errno > 0) { + return -errno; + } + + if (is_invalid_error_str(err_str, numstr)) { + return -EINVAL; + } + + *converted = (uint64_t)ull; + return 0; +} + int util_safe_llong(const char *numstr, long long *converted) { char *err_str = NULL; @@ -180,3 +207,28 @@ int util_str_to_bool(const char *boolstr, bool *converted) return 0; } +char *util_uint_to_string(long long unsigned int data) +{ + char numstr[MAX_NUM_STR_LEN] = { 0 }; + int ret; + + ret = snprintf(numstr, sizeof(numstr), "%llu", data); + if (ret < 0 || (size_t)ret >= sizeof(numstr)) { + return NULL; + } + + return util_strdup_s(numstr); +} + +char *util_int_to_string(long long int data) +{ + char numstr[MAX_NUM_STR_LEN] = { 0 }; + int ret; + + ret = snprintf(numstr, sizeof(numstr), "%lld", data); + if (ret < 0 || (size_t)ret >= sizeof(numstr)) { + return NULL; + } + + return util_strdup_s(numstr); +} \ No newline at end of file diff --git a/src/utils/cutils/utils_convert.h b/src/utils/cutils/utils_convert.h index 5b4ae3d..e1c70ba 100644 --- a/src/utils/cutils/utils_convert.h +++ b/src/utils/cutils/utils_convert.h @@ -28,10 +28,12 @@ int util_safe_uint(const char *numstr, unsigned int *converted); int util_safe_llong(const char *numstr, long long *converted); int util_safe_strtod(const char *numstr, double *converted); int util_str_to_bool(const char *boolstr, bool *converted); +int util_safe_uint64(const char *numstr, uint64_t *converted); +char *util_uint_to_string(long long unsigned int data); +char *util_int_to_string(long long int data); #ifdef __cplusplus } #endif #endif // UTILS_CUTILS_UTILS_CONVERT_H - diff --git a/src/utils/cutils/utils_file.c b/src/utils/cutils/utils_file.c index 266afea..7a965c0 100644 --- a/src/utils/cutils/utils_file.c +++ b/src/utils/cutils/utils_file.c @@ -413,7 +413,7 @@ char *util_path_join(const char *dir, const char *file) return NULL; } - if (cleanpath(path, cleaned, sizeof(cleaned)) == NULL) { + if (util_clean_path(path, cleaned, sizeof(cleaned)) == NULL) { ERROR("Failed to clean path: %s", path); return NULL; } @@ -567,7 +567,7 @@ int util_open(const char *filename, int flags, mode_t mode) { char rpath[PATH_MAX] = { 0x00 }; - if (cleanpath(filename, rpath, sizeof(rpath)) == NULL) { + if (util_clean_path(filename, rpath, sizeof(rpath)) == NULL) { return -1; } if (mode) { @@ -589,8 +589,8 @@ FILE *util_fopen(const char *filename, const char *mode) return NULL; } - if (cleanpath(filename, rpath, sizeof(rpath)) == NULL) { - ERROR("cleanpath failed"); + if (util_clean_path(filename, rpath, sizeof(rpath)) == NULL) { + ERROR("util_clean_path failed"); return NULL; } if (strncmp(mode, "a+", 2) == 0) { @@ -840,7 +840,7 @@ int64_t util_file_size(const char *filename) return (int64_t)st.st_size; } -int util_scan_subdirs(const char *directory, subdir_callback_t cb) +int util_scan_subdirs(const char *directory, subdir_callback_t cb, void *context) { DIR *dir = NULL; struct dirent *direntp = NULL; @@ -862,7 +862,7 @@ int util_scan_subdirs(const char *directory, subdir_callback_t cb) continue; } - if (!cb(directory, direntp)) { + if (!cb(directory, direntp, context)) { ERROR("Dealwith subdir: %s failed", direntp->d_name); ret = -1; break; @@ -976,7 +976,7 @@ char *look_path(const char *file, char **err) } /* if slash in file, directly use file and do not try PATH. */ - if (strings_contains_any(file, "/")) { + if (util_strings_contains_any(file, "/")) { int en = find_executable(file); if (en == 0) { return util_strdup_s(file); @@ -1414,7 +1414,7 @@ int util_atomic_write_file(const char *fname, const char *content, size_t conten return 0; } - if (cleanpath(fname, rpath, sizeof(rpath)) == NULL) { + if (util_clean_path(fname, rpath, sizeof(rpath)) == NULL) { return -1; } @@ -1444,7 +1444,7 @@ free_out: return ret; } -static char *isula_utils_fisula_utils_read_file(FILE *stream, size_t *length) +static char *do_read_file(FILE *stream, size_t *length) { #define JSON_MAX_SIZE (10LL * 1024LL * 1024LL) char *buf = NULL; @@ -1504,7 +1504,7 @@ static int do_check_args(const char *path) return 0; } -char *isula_utils_read_file(const char *path) +char *util_read_content_from_file(const char *path) { #define FILE_MODE 0640 char *buf = NULL; @@ -1535,12 +1535,12 @@ char *isula_utils_read_file(const char *path) return NULL; } - buf = isula_utils_fisula_utils_read_file(fp, &length); + buf = do_read_file(fp, &length); (void)fclose(fp); return buf; } -int isula_utils_read_line(FILE *fp, read_line_callback_t cb, void *context) +int util_proc_file_line_by_line(FILE *fp, read_line_callback_t cb, void *context) { size_t len = 0; char *line = NULL; diff --git a/src/utils/cutils/utils_file.h b/src/utils/cutils/utils_file.h index 2b37fee..1bd2d69 100644 --- a/src/utils/cutils/utils_file.h +++ b/src/utils/cutils/utils_file.h @@ -82,21 +82,21 @@ int util_copy_file(const char *src_file, const char *dst_file, mode_t mode); char *util_path_base(const char *path); -char *isula_utils_read_file(const char *path); +char *util_read_content_from_file(const char *path); void util_calculate_dir_size(const char *dirpath, int recursive_depth, int64_t *total_size, int64_t *total_inode); void utils_calculate_dir_size_without_hardlink(const char *dirpath, int64_t *total_size, int64_t *total_inode); -typedef bool (*subdir_callback_t)(const char *, const struct dirent *); +typedef bool (*subdir_callback_t)(const char *, const struct dirent *, void *context); -int util_scan_subdirs(const char *directory, subdir_callback_t cb); +int util_scan_subdirs(const char *directory, subdir_callback_t cb, void *context); int util_atomic_write_file(const char *fname, const char *content, size_t content_len, mode_t mode); typedef bool (*read_line_callback_t)(const char *, void *context); -int isula_utils_read_line(FILE *fp, read_line_callback_t cb, void *context); +int util_proc_file_line_by_line(FILE *fp, read_line_callback_t cb, void *context); #ifdef __cplusplus } diff --git a/src/utils/cutils/utils_fs.c b/src/utils/cutils/utils_fs.c index e018744..788557f 100644 --- a/src/utils/cutils/utils_fs.c +++ b/src/utils/cutils/utils_fs.c @@ -42,8 +42,8 @@ #define VXFS_SUPER_MAGIC 0xa501fcf5 #endif -#ifndef OVERLAY_SUPER_MAGIC -#define OVERLAY_SUPER_MAGIC 0x794c7630 +#ifndef OVERLAYFS_SUPER_MAGIC +#define OVERLAYFS_SUPER_MAGIC 0x794c7630 #endif #ifndef NSFS_MAGIC @@ -386,6 +386,41 @@ out: return bret; } +bool util_deal_with_mount_info(mount_info_call_back_t cb, const char *pattern) +{ + FILE *fp = NULL; + char *line = NULL; + char *mountpoint = NULL; + size_t length = 0; + bool bret = true; + int nret = 0; + + fp = util_fopen("/proc/self/mountinfo", "r"); + if (fp == NULL) { + ERROR("Failed opening /proc/self/mountinfo"); + return false; + } + + while (getline(&line, &length, fp) != -1) { + mountpoint = get_mtpoint(line); + if (mountpoint == NULL) { + INFO("Error reading mountinfo: bad line '%s'", line); + continue; + } + nret = cb(mountpoint, pattern); + free(mountpoint); + if (nret != 0) { + bret = false; + goto out; + } + } + +out: + fclose(fp); + free(line); + return bret; +} + // is_remount returns true if either device name or flags identify a remount request, false otherwise. static bool is_remount(const char *src, unsigned long mntflags) { @@ -577,7 +612,7 @@ child_out: } } - ret = wait_for_pid(pid); + ret = util_wait_for_pid(pid); if (ret != 0) { ERROR("Wait util_mount_from failed"); } diff --git a/src/utils/cutils/utils_fs.h b/src/utils/cutils/utils_fs.h index 198e4d4..6ab6b78 100644 --- a/src/utils/cutils/utils_fs.h +++ b/src/utils/cutils/utils_fs.h @@ -36,9 +36,10 @@ int util_force_mount(const char *src, const char *dst, const char *mtype, const bool util_detect_mounted(const char *path); int util_ensure_mounted_as(const char *dst, const char *mntopts); int util_mount_from(const char *base, const char *src, const char *dst, const char *mtype, const char *mntopts); +typedef int (*mount_info_call_back_t)(const char *, const char *); +bool util_deal_with_mount_info(mount_info_call_back_t cb, const char *); #ifdef __cplusplus } #endif #endif // UTILS_CUTILS_UTILS_FS_H - diff --git a/src/utils/cutils/utils_regex.c b/src/utils/cutils/utils_regex.c index ca82227..81b1ba1 100644 --- a/src/utils/cutils/utils_regex.c +++ b/src/utils/cutils/utils_regex.c @@ -72,7 +72,7 @@ static int get_regex_size_from_wildcard(const char *wildcard, const char *escape size_t i, tmp; for (i = 0; i < escapes_size; i++) { - tmp = strings_count(wildcard, escapes[i]); + tmp = util_strings_count(wildcard, escapes[i]); if (tmp > SIZE_MAX - size) { ERROR("Invalid wildcard"); return -1; @@ -80,7 +80,7 @@ static int get_regex_size_from_wildcard(const char *wildcard, const char *escape size += tmp; } - tmp = strings_count(wildcard, '*'); + tmp = util_strings_count(wildcard, '*'); if (tmp > SIZE_MAX - size - strlen(wildcard) - 3) { ERROR("Invalid wildcard"); return -1; @@ -138,4 +138,3 @@ int util_wildcard_to_regex(const char *wildcard, char **regex) return 0; } - diff --git a/src/utils/cutils/utils_string.c b/src/utils/cutils/utils_string.c index 6543021..d303114 100644 --- a/src/utils/cutils/utils_string.c +++ b/src/utils/cutils/utils_string.c @@ -47,7 +47,7 @@ static struct unit_map_def const g_unit_map[] = { static size_t const g_unit_map_len = sizeof(g_unit_map) / sizeof(g_unit_map[0]); -bool strings_contains_any(const char *str, const char *substr) +bool util_strings_contains_any(const char *str, const char *substr) { size_t i = 0; size_t j; @@ -71,7 +71,7 @@ bool strings_contains_any(const char *str, const char *substr) return false; } -bool strings_contains_word(const char *str, const char *substr) +bool util_strings_contains_word(const char *str, const char *substr) { if (str == NULL || substr == NULL) { return false; @@ -83,7 +83,7 @@ bool strings_contains_word(const char *str, const char *substr) return false; } -int strings_count(const char *str, unsigned char c) +int util_strings_count(const char *str, unsigned char c) { size_t i = 0; int res = 0; @@ -102,9 +102,9 @@ int strings_count(const char *str, unsigned char c) return res; } -// strings_in_slice tests whether a string is contained in array of strings or not. +// util_strings_in_slice tests whether a string is contained in array of strings or not. // Comparison is case insensitive -bool strings_in_slice(const char **strarray, size_t alen, const char *str) +bool util_strings_in_slice(const char **strarray, size_t alen, const char *str) { size_t i; @@ -123,7 +123,7 @@ bool strings_in_slice(const char **strarray, size_t alen, const char *str) // Returns a string that is generated after converting // all uppercase characters in the str to lowercase. -char *strings_to_lower(const char *str) +char *util_strings_to_lower(const char *str) { char *newstr = NULL; char *pos = NULL; @@ -145,7 +145,7 @@ char *strings_to_lower(const char *str) // Returns a string that is generated after converting // all lowercase characters in the str to uppercase. -char *strings_to_upper(const char *str) +char *util_strings_to_upper(const char *str) { char *newstr = NULL; char *pos = NULL; @@ -182,7 +182,7 @@ static int parse_unit_multiple(const char *unit, int64_t *mltpl) return -EINVAL; } -static int util_parse_size_int_and_float(const char *numstr, int64_t mlt, int64_t *converted) +int util_parse_size_int_and_float(const char *numstr, int64_t mlt, int64_t *converted) { long long int_size = 0; double float_size = 0; @@ -461,7 +461,7 @@ err_out: return NULL; } -const char *str_skip_str(const char *str, const char *skip) +const char *util_str_skip_str(const char *str, const char *skip) { if (str == NULL || skip == NULL) { return NULL; @@ -613,7 +613,7 @@ char *util_trim_quotation(char *str) return str; } -char **str_array_dup(const char **src, size_t len) +char **util_str_array_dup(const char **src, size_t len) { size_t i; char **dest = NULL; @@ -710,7 +710,7 @@ char *util_string_append(const char *post, const char *pre) return res_string; } -int dup_array_of_strings(const char **src, size_t src_len, char ***dst, size_t *dst_len) +int util_dup_array_of_strings(const char **src, size_t src_len, char ***dst, size_t *dst_len) { size_t i; @@ -824,8 +824,7 @@ bool util_has_suffix(const char *str, const char *suffix) return true; } -int util_string_array_unique(const char **elements, size_t length, char ***unique_elements, - size_t *unique_elements_len) +int util_string_array_unique(const char **elements, size_t length, char ***unique_elements, size_t *unique_elements_len) { int ret = 0; size_t i; @@ -885,21 +884,33 @@ out: return ret; } -int util_parse_bool_string(const char *str, bool *converted) +char *util_str_token(char **input, const char *delimiter) { - int ret = 0; + char *str = NULL; + char *delimiter_found = NULL; + char *tok = NULL; + size_t tok_length = 0; - if (str == NULL || converted == NULL) { - return -EINVAL; + if (input == NULL || delimiter == NULL) { + return NULL; } - if (strcasecmp(str, "true") == 0) { - *converted = true; - } else if (strcasecmp(str, "false") == 0) { - *converted = false; + str = *input; + + if (str == NULL) { + return NULL; + } + delimiter_found = strstr(str, delimiter); + if (delimiter_found != NULL) { + tok_length = delimiter_found - str; } else { - ret = -EINVAL; + tok_length = strlen(str); } - - return ret; -} + tok = strndup(str, tok_length); + if (tok == NULL) { + ERROR("strndup failed"); + return NULL; + } + *input = delimiter_found != NULL ? delimiter_found + strlen(delimiter) : NULL; + return tok; +} \ No newline at end of file diff --git a/src/utils/cutils/utils_string.h b/src/utils/cutils/utils_string.h index 4d48f72..48733f3 100644 --- a/src/utils/cutils/utils_string.h +++ b/src/utils/cutils/utils_string.h @@ -24,17 +24,17 @@ extern "C" { #endif -bool strings_contains_any(const char *str, const char *substr); +bool util_strings_contains_any(const char *str, const char *substr); -bool strings_contains_word(const char *str, const char *substr); +bool util_strings_contains_word(const char *str, const char *substr); -int strings_count(const char *str, unsigned char c); +int util_strings_count(const char *str, unsigned char c); -bool strings_in_slice(const char **strarray, size_t alen, const char *str); +bool util_strings_in_slice(const char **strarray, size_t alen, const char *str); -char *strings_to_lower(const char *str); +char *util_strings_to_lower(const char *str); -char *strings_to_upper(const char *str); +char *util_strings_to_upper(const char *str); int util_parse_byte_size_string(const char *s, int64_t *converted); @@ -50,7 +50,7 @@ char **util_string_split_multi(const char *src_str, char delim); char **util_string_split_n(const char *src_str, char delim, size_t n); -const char *str_skip_str(const char *str, const char *skip); +const char *util_str_skip_str(const char *str, const char *skip); char *util_string_delchar(const char *ss, unsigned char c); @@ -60,13 +60,13 @@ char *util_trim_space(char *str); char *util_trim_quotation(char *str); -char **str_array_dup(const char **src, size_t len); +char **util_str_array_dup(const char **src, size_t len); char *util_string_join(const char *sep, const char **parts, size_t len); char *util_string_append(const char *post, const char *pre); -int dup_array_of_strings(const char **src, size_t src_len, char ***dst, size_t *dst_len); +int util_dup_array_of_strings(const char **src, size_t src_len, char ***dst, size_t *dst_len); char *util_sub_string(const char *source, size_t offset, size_t length); @@ -79,11 +79,11 @@ bool util_has_suffix(const char *str, const char *suffix); int util_string_array_unique(const char **elements, size_t length, char ***unique_elements, size_t *unique_elements_len); -int util_parse_bool_string(const char *str, bool *converted); +int util_parse_size_int_and_float(const char *numstr, int64_t mlt, int64_t *converted); +char *util_str_token(char **input, const char *delimiter); #ifdef __cplusplus } #endif #endif // UTILS_CUTILS_UTILS_STRING_H - diff --git a/src/utils/cutils/utils_timestamp.c b/src/utils/cutils/utils_timestamp.c index 41a0e1c..23f3c77 100644 --- a/src/utils/cutils/utils_timestamp.c +++ b/src/utils/cutils/utils_timestamp.c @@ -77,7 +77,7 @@ int types_timestamp_cmp_nanos(const types_timestamp_t *t1, const types_timestamp } /* types timestamp cmp */ -int types_timestamp_cmp(const types_timestamp_t *t1, const types_timestamp_t *t2) +int util_types_timestamp_cmp(const types_timestamp_t *t1, const types_timestamp_t *t2) { int ret = 0; @@ -106,7 +106,7 @@ int types_timestamp_cmp(const types_timestamp_t *t1, const types_timestamp_t *t2 } /* get timestamp */ -bool get_timestamp(const char *str_time, types_timestamp_t *timestamp) +bool util_get_timestamp(const char *str_time, types_timestamp_t *timestamp) { int64_t seconds = 0; int32_t nanos = 0; @@ -118,7 +118,7 @@ bool get_timestamp(const char *str_time, types_timestamp_t *timestamp) return false; } - if (!get_tm_from_str(str_time, &tm_day, &nanos)) { + if (!util_get_tm_from_str(str_time, &tm_day, &nanos)) { return false; } @@ -189,12 +189,12 @@ out: } /* get time buffer */ -bool get_time_buffer(const types_timestamp_t *timestamp, char *timebuffer, size_t maxsize) +bool util_get_time_buffer(const types_timestamp_t *timestamp, char *timebuffer, size_t maxsize) { return get_time_buffer_help(timestamp, timebuffer, maxsize, false); } -bool get_now_time_stamp(types_timestamp_t *timestamp) +bool util_get_now_time_stamp(types_timestamp_t *timestamp) { int err = 0; struct timespec ts; @@ -211,7 +211,7 @@ bool get_now_time_stamp(types_timestamp_t *timestamp) return true; } -int64_t get_now_time_nanos() +int64_t util_get_now_time_nanos() { int err = 0; struct timespec ts; @@ -226,30 +226,30 @@ int64_t get_now_time_nanos() } /* get now time buffer */ -bool get_now_time_buffer(char *timebuffer, size_t maxsize) +bool util_get_now_time_buffer(char *timebuffer, size_t maxsize) { types_timestamp_t timestamp; - if (get_now_time_stamp(×tamp) == false) { + if (util_get_now_time_stamp(×tamp) == false) { return false; } - return get_time_buffer(×tamp, timebuffer, maxsize); + return util_get_time_buffer(×tamp, timebuffer, maxsize); } /* get now local utc time buffer */ -bool get_now_local_utc_time_buffer(char *timebuffer, size_t maxsize) +bool util_get_now_local_utc_time_buffer(char *timebuffer, size_t maxsize) { types_timestamp_t timestamp; - if (get_now_time_stamp(×tamp) == false) { + if (util_get_now_time_stamp(×tamp) == false) { return false; } return get_time_buffer_help(×tamp, timebuffer, maxsize, true); } -int get_time_interval(types_timestamp_t first, types_timestamp_t last, int64_t *result) +int util_get_time_interval(types_timestamp_t first, types_timestamp_t last, int64_t *result) { int64_t seconds_diff = 0; int64_t nanos_diff = 0; @@ -348,7 +348,7 @@ static void parsing_time_data(const char *time, struct tm *tm) parsing_time_data_sec(tm, time, &i); } -bool parsing_time(const char *format, const char *time, struct tm *tm, int32_t *nanos) +bool util_parsing_time(const char *format, const char *time, struct tm *tm, int32_t *nanos) { size_t len_format = 0; size_t len_time = 0; @@ -429,7 +429,7 @@ int get_valid_days(int mon, int year) return valid_days; } -bool fix_date(struct tm *tm) +bool util_fix_date(struct tm *tm) { if (tm == NULL) { return false; @@ -456,7 +456,7 @@ bool fix_date(struct tm *tm) return true; } -bool get_tm_from_str(const char *str, struct tm *tm, int32_t *nanos) +bool util_get_tm_from_str(const char *str, struct tm *tm, int32_t *nanos) { char *format = NULL; @@ -464,10 +464,10 @@ bool get_tm_from_str(const char *str, struct tm *tm, int32_t *nanos) return false; } - if (strings_contains_any(str, ".")) { + if (util_strings_contains_any(str, ".")) { format = rFC339NanoLocal; - } else if (strings_contains_any(str, "T")) { - int tcolons = strings_count(str, ':'); + } else if (util_strings_contains_any(str, "T")) { + int tcolons = util_strings_count(str, ':'); switch (tcolons) { case 0: format = "2016-01-02T15"; @@ -486,12 +486,12 @@ bool get_tm_from_str(const char *str, struct tm *tm, int32_t *nanos) format = dateLocal; } - if (!parsing_time(format, str, tm, nanos)) { + if (!util_parsing_time(format, str, tm, nanos)) { ERROR("Failed to parse time \"%s\" with format \"%s\"", str, format); return false; } - if (!fix_date(tm)) { + if (!util_fix_date(tm)) { ERROR("\"%s\" is invalid", str); return false; } @@ -578,7 +578,7 @@ static bool get_tm_zone_from_str(const char *str, struct tm *tm, int32_t *nanos, zonestr = util_strdup_s(zp); *zp = '\0'; - if (!get_tm_from_str(tmstr, tm, nanos)) { + if (!util_get_tm_from_str(tmstr, tm, nanos)) { ERROR("Get tm from str failed"); goto err_out; } @@ -616,7 +616,7 @@ static int64_t get_minmus_time(struct tm *tm1, struct tm *tm2) return result; } -int64_t time_seconds_since(const char *in) +int64_t util_time_seconds_since(const char *in) { int32_t nanos = 0; int64_t result = 0; @@ -835,7 +835,7 @@ static int time_format_duration_bad(char *out, size_t len) return 1; /* format ok with bad data, return 1 */ } -int time_format_duration(const char *in, char *out, size_t len) +int util_time_format_duration(const char *in, char *out, size_t len) { int32_t nanos = 0; int64_t result = 0; @@ -873,9 +873,9 @@ int time_format_duration(const char *in, char *out, size_t len) return 0; } -int time_format_duration_ago(const char *in, char *out, size_t len) +int util_time_format_duration_ago(const char *in, char *out, size_t len) { - if (time_format_duration(in, out, len) != 0) { + if (util_time_format_duration(in, out, len) != 0) { ERROR("Get format duration"); return -1; } @@ -908,7 +908,7 @@ static int time_tz_to_seconds_nanos(const char *time_tz, int64_t *seconds, int32 time_str = util_strdup_s(time_tz); time_str[strlen(time_str) - 1] = '\0'; /* strip last 'Z' */ - if (!get_tm_from_str(time_str, &t, &nano)) { + if (!util_get_tm_from_str(time_str, &t, &nano)) { ERROR("get tm from string %s failed", time_str); nret = -1; goto err_out; @@ -927,7 +927,7 @@ err_out: return nret; } -int to_unix_nanos_from_str(const char *str, int64_t *nanos) +int util_to_unix_nanos_from_str(const char *str, int64_t *nanos) { struct tm tm = { 0 }; struct types_timezone tz; @@ -969,3 +969,94 @@ int to_unix_nanos_from_str(const char *str, int64_t *nanos) *nanos = mktime(&tm) * Time_Second + nano; return 0; } + +types_timestamp_t util_to_timestamp_from_str(const char *str) +{ + int64_t nanos = 0; + types_timestamp_t timestamp = { 0 }; + + if (util_to_unix_nanos_from_str(str, &nanos) != 0) { + ERROR("Failed to get created time from image config"); + goto out; + } + + timestamp.has_seconds = true; + timestamp.seconds = nanos / Time_Second; + timestamp.has_nanos = true; + timestamp.nanos = nanos % Time_Second; + +out: + return timestamp; +} + +static int get_time_ns(long long *pns, long long unit) +{ + if (unit == 0) { + return -1; + } + + if (INT64_MAX / *pns >= unit) { + *pns *= unit; + return 0; + } + + return -1; +} + +static long long get_time_unit(int unit) +{ + long long u[255] = { 0 }; + + u['M'] = Time_Milli; + u['s'] = Time_Second; + u['m'] = Time_Minute; + u['h'] = Time_Hour; + + return u[unit]; +} + +int util_time_str_to_nanoseconds(const char *value, int64_t *nanoseconds) +{ + int ret = 0; + long long tmp = 0; + char unit = 0; + size_t len = 0; + char *num_str = NULL; + + if (value == NULL || nanoseconds == NULL) { + return -1; + } + + if (util_reg_match("^([0-9]+)+(ms|s|m|h)$", value) != 0) { + return -1; + } + num_str = util_strdup_s(value); + len = strlen(value); + + if (strstr(value, "ms") == NULL) { + unit = *(value + len - 1); + *(num_str + len - 1) = '\0'; + } else { + unit = 'M'; + *(num_str + len - 2) = '\0'; + } + ret = util_safe_llong(num_str, &tmp); + if (ret < 0) { + ERROR("Illegal unsigned integer: %s", num_str); + ret = -1; + goto out; + } + if (tmp == 0) { + goto out; + } + + ret = get_time_ns(&tmp, get_time_unit(unit)); + if (ret != 0) { + ERROR("failed get nano seconds for %s", num_str); + } + *nanoseconds = (int64_t)tmp; + +out: + free(num_str); + return ret; +} \ No newline at end of file diff --git a/src/utils/cutils/utils_timestamp.h b/src/utils/cutils/utils_timestamp.h index 603fa73..2e93a21 100644 --- a/src/utils/cutils/utils_timestamp.h +++ b/src/utils/cutils/utils_timestamp.h @@ -26,6 +26,18 @@ struct tm; extern "C" { #endif +#define Time_Nano 1LL +#define Time_Micro (1000LL * Time_Nano) +#define Time_Milli (1000LL * Time_Micro) +#define Time_Second (1000LL * Time_Milli) +#define Time_Minute (60LL * Time_Second) +#define Time_Hour (60LL * Time_Minute) + +#define rFC339Local "2006-01-02T15:04:05" +#define rFC339NanoLocal "2006-01-02T15:04:05.999999999" +#define dateLocal "2006-01-02" +#define defaultContainerTime "0001-01-01T00:00:00Z" + typedef struct types_timestamp { bool has_seconds; int64_t seconds; @@ -40,38 +52,41 @@ struct types_timezone { bool unix_nanos_to_timestamp(int64_t nanos, types_timestamp_t *timestamp); -int64_t time_seconds_since(const char *in); +int64_t util_time_seconds_since(const char *in); + +int util_types_timestamp_cmp(const types_timestamp_t *t1, const types_timestamp_t *t2); -int types_timestamp_cmp(const types_timestamp_t *t1, const types_timestamp_t *t2); +bool util_get_timestamp(const char *str_time, types_timestamp_t *timestamp); -bool get_timestamp(const char *str_time, types_timestamp_t *timestamp); +bool util_get_time_buffer(const types_timestamp_t *timestamp, char *timebuffer, size_t maxsize); -bool get_time_buffer(const types_timestamp_t *timestamp, char *timebuffer, size_t maxsize); +bool util_get_now_time_stamp(types_timestamp_t *timestamp); -bool get_now_time_stamp(types_timestamp_t *timestamp); +bool util_get_now_local_utc_time_buffer(char *timebuffer, size_t maxsize); -bool get_now_local_utc_time_buffer(char *timebuffer, size_t maxsize); +bool util_get_now_time_buffer(char *timebuffer, size_t maxsize); -bool get_now_time_buffer(char *timebuffer, size_t maxsize); +int util_get_time_interval(types_timestamp_t first, types_timestamp_t last, int64_t *result); -int get_time_interval(types_timestamp_t first, types_timestamp_t last, int64_t *result); +int util_to_unix_nanos_from_str(const char *str, int64_t *nanos); -int to_unix_nanos_from_str(const char *str, int64_t *nanos); +bool util_parsing_time(const char *format, const char *time, struct tm *tm, int32_t *nanos); -bool parsing_time(const char *format, const char *time, struct tm *tm, int32_t *nanos); +bool util_fix_date(struct tm *tm); -bool fix_date(struct tm *tm); +bool util_get_tm_from_str(const char *str, struct tm *tm, int32_t *nanos); -bool get_tm_from_str(const char *str, struct tm *tm, int32_t *nanos); +int util_time_format_duration(const char *in, char *out, size_t len); -int time_format_duration(const char *in, char *out, size_t len); +int util_time_format_duration_ago(const char *in, char *out, size_t len); -int time_format_duration_ago(const char *in, char *out, size_t len); +types_timestamp_t util_to_timestamp_from_str(const char *str); -int64_t get_now_time_nanos(); +int util_time_str_to_nanoseconds(const char *value, int64_t *nanoseconds); + +int64_t util_get_now_time_nanos(); #ifdef __cplusplus } #endif #endif - diff --git a/src/utils/cutils/utils_verify.c b/src/utils/cutils/utils_verify.c index 530e26b..e8bcba9 100644 --- a/src/utils/cutils/utils_verify.c +++ b/src/utils/cutils/utils_verify.c @@ -225,7 +225,7 @@ bool util_valid_cap(const char *cap) cret = false; goto err_out; } - if (!strings_in_slice(g_all_caps, all_caps_len, tmpcap)) { + if (!util_strings_in_slice(g_all_caps, all_caps_len, tmpcap)) { cret = false; goto err_out; } @@ -640,3 +640,102 @@ bool util_valid_exec_suffix(const char *suffix) return util_reg_match(patten, suffix) == 0; } + +bool util_valid_positive_interger(const char *value) +{ + const char *patten = "^[0-9]*$"; + + if (value == NULL) { + return false; + } + + return util_reg_match(patten, value) == 0; +} + +bool util_valid_device_cgroup_rule(const char *value) +{ + const char *patten = "^([acb]) ([0-9]+|\\*):([0-9]+|\\*) ([rwm]{1,3})$"; + + if (value == NULL) { + return false; + } + + return util_reg_match(patten, value) == 0; +} + +int util_valid_env(const char *env, char **dst) +{ + int ret = 0; + char *value = NULL; + + char **arr = util_string_split_multi(env, '='); + if (arr == NULL) { + ERROR("Failed to split env string"); + return -1; + } + if (strlen(arr[0]) == 0) { + ERROR("Invalid environment variable: %s", env); + ret = -1; + goto out; + } + + if (util_array_len((const char **)arr) > 1) { + *dst = util_strdup_s(env); + goto out; + } + + value = getenv(env); + if (value == NULL) { + *dst = NULL; + goto out; + } else { + int sret; + size_t len = strlen(env) + 1 + strlen(value) + 1; + *dst = (char *)util_common_calloc_s(len); + if (*dst == NULL) { + ERROR("Out of memory"); + ret = -1; + goto out; + } + sret = snprintf(*dst, len, "%s=%s", env, value); + if (sret < 0 || (size_t)sret >= len) { + ERROR("Failed to compose env string"); + ret = -1; + goto out; + } + } + +out: + util_free_array(arr); + return ret; +} + +bool util_valid_sysctl(const char *sysctl_key) +{ + size_t i = 0; + size_t full_keys_len = 0; + size_t key_prefixes_len = 0; + const char *sysctl_full_keys[] = { "kernel.msgmax", "kernel.msgmnb", "kernel.msgmni", "kernel.sem", + "kernel.shmall", "kernel.shmmax", "kernel.shmmni", "kernel.shm_rmid_forced" + }; + const char *sysctl_key_prefixes[] = { "net.", "fs.mqueue." }; + + if (sysctl_key == NULL) { + return false; + } + + full_keys_len = sizeof(sysctl_full_keys) / sizeof(char *); + key_prefixes_len = sizeof(sysctl_key_prefixes) / sizeof(char *); + + for (i = 0; i < full_keys_len; i++) { + if (strcmp(sysctl_full_keys[i], sysctl_key) == 0) { + return true; + } + } + for (i = 0; i < key_prefixes_len; i++) { + if (strncmp(sysctl_key_prefixes[i], sysctl_key, strlen(sysctl_key_prefixes[i])) == 0) { + return true; + } + } + return false; +} \ No newline at end of file diff --git a/src/utils/cutils/utils_verify.h b/src/utils/cutils/utils_verify.h index 7d431b1..26ceb34 100644 --- a/src/utils/cutils/utils_verify.h +++ b/src/utils/cutils/utils_verify.h @@ -25,6 +25,15 @@ extern "C" { #endif +#define HOST_NAME_REGEXP \ + "^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]*[a-zA-Z0-9])\\.)*" \ + "([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\\-]*[A-Za-z0-9])$" +#define __TagPattern "^:([A-Za-z_0-9][A-Za-z_0-9.-]{0,127})$" +#define __NamePattern \ + "^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])" \ + "((\\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+)?(:[0-9]+)?/)?[a-z0-9]" \ + "+((([._]|__|[-]*)[a-z0-9]+)+)?((/[a-z0-9]+((([._]|__|[-]*)[a-z0-9]+)+)?)+)?$" + extern const char *g_all_caps[]; bool util_valid_cmd_arg(const char *arg); @@ -99,6 +108,14 @@ bool util_valid_short_sha256_id(const char *id); bool util_valid_exec_suffix(const char *suffix); +bool util_valid_positive_interger(const char *value); + +bool util_valid_device_cgroup_rule(const char *value); + +int util_valid_env(const char *env, char **dst); + +bool util_valid_sysctl(const char *sysctl_key); + #ifdef __cplusplus } #endif diff --git a/src/utils/http/parser.c b/src/utils/http/parser.c index ec4ae43..2a69fed 100644 --- a/src/utils/http/parser.c +++ b/src/utils/http/parser.c @@ -303,7 +303,7 @@ int parse_http(const char *buf, size_t len, struct parsed_http_message *m, nparsed = parse(buf, len, parser); if (nparsed != len) { - ERROR("Failed to parse it, parsed :%ld, intput:%ld \n", nparsed, len); + ERROR("Failed to parse it, parsed :%zu, intput:%zu \n", nparsed, len); ret = -1; goto free_out; } diff --git a/src/utils/http/rest_common.c b/src/utils/http/rest_common.c index 7d1f1e3..1916959 100644 --- a/src/utils/http/rest_common.c +++ b/src/utils/http/rest_common.c @@ -224,9 +224,9 @@ static int set_http_get_options(const char *socket, char *request_body, size_t b options->input_len = body_len; raw_socket = socket; - unix_raw_socket = str_skip_str(raw_socket, "unix://"); + unix_raw_socket = util_str_skip_str(raw_socket, "unix://"); if (unix_raw_socket == NULL) { - ERROR("Failed to str_skip_str raw_socket"); + ERROR("Failed to util_str_skip_str raw_socket"); return -1; } options->unix_socket_path = util_strdup_s(unix_raw_socket); @@ -291,4 +291,3 @@ void put_body(char *body) { free(body); } - diff --git a/src/utils/sha256/sha256.c b/src/utils/sha256/sha256.c index 31dcc9b..52f2572 100644 --- a/src/utils/sha256/sha256.c +++ b/src/utils/sha256/sha256.c @@ -308,7 +308,7 @@ char *sha256_full_digest_str(char *str) return full_digest; } -char *without_sha256_prefix(char *digest) +char *util_without_sha256_prefix(char *digest) { if (digest == NULL || !util_has_prefix(digest, SHA256_PREFIX)) { ERROR("Invalid digest when strip sha256 prefix"); diff --git a/src/utils/sha256/sha256.h b/src/utils/sha256/sha256.h index 8a40a4f..1c0750f 100644 --- a/src/utils/sha256/sha256.h +++ b/src/utils/sha256/sha256.h @@ -36,7 +36,7 @@ bool sha256_valid_digest_file(const char *path, const char *digest); char *sha256_full_digest_str(char *str); -char *without_sha256_prefix(char *digest); +char *util_without_sha256_prefix(char *digest); #ifdef __cplusplus } diff --git a/src/utils/tar/isulad_tar.c b/src/utils/tar/isulad_tar.c index 7d0088e..a3dcbaf 100644 --- a/src/utils/tar/isulad_tar.c +++ b/src/utils/tar/isulad_tar.c @@ -247,21 +247,21 @@ static int get_rebase_name(const char *path, const char *real_path, return -1; } - if (specify_current_dir(path) && !specify_current_dir(real_path)) { + if (util_specify_current_dir(path) && !util_specify_current_dir(real_path)) { set_char_to_separator(&resolved[strlen(resolved)]); resolved[strlen(resolved)] = '.'; } - if (has_trailing_path_separator(path) && !has_trailing_path_separator(resolved)) { + if (util_has_trailing_path_separator(path) && !util_has_trailing_path_separator(resolved)) { resolved[strlen(resolved)] = '/'; } - nret = split_dir_and_base_name(path, NULL, &path_base); + nret = util_split_dir_and_base_name(path, NULL, &path_base); if (nret != 0) { ERROR("split %s failed", path); goto cleanup; } - nret = split_dir_and_base_name(resolved, NULL, &resolved_base); + nret = util_split_dir_and_base_name(resolved, NULL, &resolved_base); if (nret != 0) { ERROR("split %s failed", resolved); goto cleanup; @@ -309,7 +309,7 @@ int resolve_host_source_path(const char *path, bool follow_link, return -1; } } else { - nret = filepath_split(path, &dirpath, &basepath); + nret = util_filepath_split(path, &dirpath, &basepath); if (nret < 0) { ERROR("Can not split path %s", path); format_errorf(err, "Can not split path %s", path); @@ -326,19 +326,19 @@ int resolve_host_source_path(const char *path, bool follow_link, goto cleanup; } *resolved_path = util_strdup_s(resolved); - nret = split_dir_and_base_name(path, NULL, &tmp_path_base); + nret = util_split_dir_and_base_name(path, NULL, &tmp_path_base); if (nret != 0) { ERROR("split %s failed", path); goto cleanup; } - nret = split_dir_and_base_name(resolved, NULL, &tmp_resolved_base); + nret = util_split_dir_and_base_name(resolved, NULL, &tmp_resolved_base); if (nret != 0) { ERROR("split %s failed", resolved); goto cleanup; } - if (has_trailing_path_separator(path) && strcmp(tmp_path_base, tmp_resolved_base) != 0) { + if (util_has_trailing_path_separator(path) && strcmp(tmp_path_base, tmp_resolved_base) != 0) { *rebase_name = tmp_path_base; tmp_path_base = NULL; } @@ -413,7 +413,7 @@ static int copy_info_destination_path_ret(struct archive_copy_info *info, } // is not absolutely path if (target[0] != '\0') { - if (split_path_dir_entry(iter_path, &parent, NULL) < 0) { + if (util_split_path_dir_entry(iter_path, &parent, NULL) < 0) { goto cleanup; } free(iter_path); @@ -445,7 +445,7 @@ static int copy_info_destination_path_ret(struct archive_copy_info *info, goto cleanup; } - if (split_path_dir_entry(iter_path, &dst_parent, NULL) < 0) { + if (util_split_path_dir_entry(iter_path, &dst_parent, NULL) < 0) { goto cleanup; } @@ -503,7 +503,7 @@ cleanup: static bool asserts_directory(const char *path) { - return has_trailing_path_separator(path) || specify_current_dir(path); + return util_has_trailing_path_separator(path) || util_specify_current_dir(path); } static char *format_transform_of_tar(const char *srcbase, const char *dstbase) @@ -555,10 +555,10 @@ char *prepare_archive_copy(const struct archive_copy_info *srcinfo, const struct char *srcbase = NULL; char *dstbase = NULL; - if (split_path_dir_entry(dstinfo->path, &dstdir, &dstbase) < 0) { + if (util_split_path_dir_entry(dstinfo->path, &dstdir, &dstbase) < 0) { goto cleanup; } - if (split_path_dir_entry(srcinfo->path, NULL, &srcbase) < 0) { + if (util_split_path_dir_entry(srcinfo->path, NULL, &srcbase) < 0) { goto cleanup; } @@ -867,7 +867,7 @@ int tar_resource_rebase(const char *path, const char *rebase, struct io_read_wra format_errorf(err, "lstat %s: %s", path, strerror(errno)); return -1; } - if (split_path_dir_entry(path, &srcdir, &srcbase) < 0) { + if (util_split_path_dir_entry(path, &srcdir, &srcbase) < 0) { ERROR("Can not split path: %s", path); goto cleanup; } diff --git a/src/utils/tar/util_archive.c b/src/utils/tar/util_archive.c index fce94e5..0ae99be 100644 --- a/src/utils/tar/util_archive.c +++ b/src/utils/tar/util_archive.c @@ -292,7 +292,7 @@ child_out: } } - ret = wait_for_pid(pid); + ret = util_wait_for_pid(pid); if (ret != 0) { ERROR("Wait archive_untar_handler failed"); } @@ -605,7 +605,7 @@ child_out: } } - ret = wait_for_pid(pid); + ret = util_wait_for_pid(pid); if (ret != 0) { ERROR("tar failed"); fcntl(pipe_for_read[0], F_SETFL, O_NONBLOCK); diff --git a/test/cmd/isula/CMakeLists.txt b/test/cmd/isula/CMakeLists.txt index e30dfc6..f4701b0 100644 --- a/test/cmd/isula/CMakeLists.txt +++ b/test/cmd/isula/CMakeLists.txt @@ -1,4 +1,4 @@ project(iSulad_UT) -add_subdirectory(infomation) +add_subdirectory(information) add_subdirectory(extend) diff --git a/test/cmd/isula/extend/pause/CMakeLists.txt b/test/cmd/isula/extend/pause/CMakeLists.txt index 9bc48e9..0179674 100644 --- a/test/cmd/isula/extend/pause/CMakeLists.txt +++ b/test/cmd/isula/extend/pause/CMakeLists.txt @@ -18,7 +18,7 @@ add_executable(${EXE} ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/utils/console/console.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/cmd/isula/client_arguments.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/common/err_msg.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/client/libisula.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/client/connect/protocol_type.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/utils/cutils/utils_timestamp.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/utils/cutils/mainloop.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/utils/cutils/error.c diff --git a/test/cmd/isula/extend/pause/pause_ut.cc b/test/cmd/isula/extend/pause/pause_ut.cc index 8039963..538f2d6 100644 --- a/test/cmd/isula/extend/pause/pause_ut.cc +++ b/test/cmd/isula/extend/pause/pause_ut.cc @@ -78,7 +78,7 @@ TEST_F(ContainerPauseUnitTest, test_cmd_pause_main) EXPECT_EXIT(cmd_pause_main(sizeof(argv) / sizeof(argv[0]), const_cast(argv)), testing::ExitedWithCode(0), ""); EXPECT_EXIT(cmd_pause_main(sizeof(argv_failure) / sizeof(argv_failure[0]), const_cast(argv_failure)), - testing::ExitedWithCode(125), "Unkown flag found"); + testing::ExitedWithCode(125), "Unknown flag found"); testing::Mock::VerifyAndClearExpectations(&m_grpcClient); } diff --git a/test/cmd/isula/extend/resume/CMakeLists.txt b/test/cmd/isula/extend/resume/CMakeLists.txt index 6e751ce..729c4d3 100644 --- a/test/cmd/isula/extend/resume/CMakeLists.txt +++ b/test/cmd/isula/extend/resume/CMakeLists.txt @@ -18,7 +18,7 @@ add_executable(${EXE} ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/utils/console/console.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/cmd/isula/client_arguments.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/common/err_msg.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/client/libisula.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/client/connect/protocol_type.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/utils/cutils/utils_timestamp.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/utils/cutils/mainloop.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/utils/cutils/error.c diff --git a/test/cmd/isula/extend/resume/resume_ut.cc b/test/cmd/isula/extend/resume/resume_ut.cc index e317197..48ed525 100644 --- a/test/cmd/isula/extend/resume/resume_ut.cc +++ b/test/cmd/isula/extend/resume/resume_ut.cc @@ -78,7 +78,7 @@ TEST_F(ContainerResumeUnitTest, test_cmd_resume_main) EXPECT_EXIT(cmd_resume_main(sizeof(argv) / sizeof(argv[0]), const_cast(argv)), testing::ExitedWithCode(0), ""); EXPECT_EXIT(cmd_resume_main(sizeof(argv_failure) / sizeof(argv_failure[0]), const_cast(argv_failure)), - testing::ExitedWithCode(125), "Unkown flag found"); + testing::ExitedWithCode(125), "Unknown flag found"); testing::Mock::VerifyAndClearExpectations(&m_grpcClient); } diff --git a/test/cmd/isula/infomation/CMakeLists.txt b/test/cmd/isula/information/CMakeLists.txt similarity index 100% rename from test/cmd/isula/infomation/CMakeLists.txt rename to test/cmd/isula/information/CMakeLists.txt diff --git a/test/cmd/isula/infomation/info/CMakeLists.txt b/test/cmd/isula/information/info/CMakeLists.txt similarity index 97% rename from test/cmd/isula/infomation/info/CMakeLists.txt rename to test/cmd/isula/information/info/CMakeLists.txt index 83a51d4..2f13498 100644 --- a/test/cmd/isula/infomation/info/CMakeLists.txt +++ b/test/cmd/isula/information/info/CMakeLists.txt @@ -19,7 +19,7 @@ add_executable(${EXE} ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/utils/console/console.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/cmd/isula/client_arguments.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/common/err_msg.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/client/libisula.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/client/connect/protocol_type.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/utils/cutils/utils_timestamp.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/utils/cutils/mainloop.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/utils/cutils/error.c diff --git a/test/cmd/isula/infomation/info/info_ut.cc b/test/cmd/isula/information/info/info_ut.cc similarity index 98% rename from test/cmd/isula/infomation/info/info_ut.cc rename to test/cmd/isula/information/info/info_ut.cc index 6a35e22..3b6efcb 100644 --- a/test/cmd/isula/infomation/info/info_ut.cc +++ b/test/cmd/isula/information/info/info_ut.cc @@ -144,7 +144,7 @@ TEST_F(InfoUnitTest, test_cmd_info_main_all) EXPECT_EXIT(cmd_info_main(sizeof(argv) / sizeof(argv[0]), const_cast(argv)), testing::ExitedWithCode(0), ""); EXPECT_EXIT(cmd_info_main(sizeof(argv_failure) / sizeof(argv_failure[0]), const_cast(argv_failure)), - testing::ExitedWithCode(125), "Unkown flag found"); + testing::ExitedWithCode(125), "Unknown flag found"); std::string output = testing::internal::GetCapturedStdout(); if (output.find("devicemapper") == std::string::npos) { diff --git a/test/cmd/isula/infomation/ps/CMakeLists.txt b/test/cmd/isula/information/ps/CMakeLists.txt similarity index 97% rename from test/cmd/isula/infomation/ps/CMakeLists.txt rename to test/cmd/isula/information/ps/CMakeLists.txt index 2aee9d4..9659808 100644 --- a/test/cmd/isula/infomation/ps/CMakeLists.txt +++ b/test/cmd/isula/information/ps/CMakeLists.txt @@ -18,7 +18,7 @@ add_executable(${EXE} ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/utils/console/console.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/cmd/isula/client_arguments.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/common/err_msg.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/client/libisula.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/client/connect/protocol_type.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/utils/cutils/utils_timestamp.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/utils/cutils/mainloop.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/utils/cutils/error.c diff --git a/test/cmd/isula/infomation/ps/ps_ut.cc b/test/cmd/isula/information/ps/ps_ut.cc similarity index 99% rename from test/cmd/isula/infomation/ps/ps_ut.cc rename to test/cmd/isula/information/ps/ps_ut.cc index 643d8fa..7436e93 100644 --- a/test/cmd/isula/infomation/ps/ps_ut.cc +++ b/test/cmd/isula/information/ps/ps_ut.cc @@ -159,7 +159,7 @@ TEST_F(ContainerListUnitTest, test_cmd_list_main_all) EXPECT_EXIT(cmd_list_main(sizeof(argv) / sizeof(argv[0]), const_cast(argv)), testing::ExitedWithCode(0), ""); EXPECT_EXIT(cmd_list_main(sizeof(argv_failure) / sizeof(argv_failure[0]), const_cast(argv_failure)), - testing::ExitedWithCode(125), "Unkown flag found"); + testing::ExitedWithCode(125), "Unknown flag found"); testing::Mock::VerifyAndClearExpectations(&m_grpcClient); } diff --git a/test/cutils/utils_string/utils_string_ut.cc b/test/cutils/utils_string/utils_string_ut.cc index 1d5b6e4..62e6ade 100644 --- a/test/cutils/utils_string/utils_string_ut.cc +++ b/test/cutils/utils_string/utils_string_ut.cc @@ -29,59 +29,57 @@ extern "C" { TEST(utils_string_ut, test_strings_count) { - ASSERT_EQ(strings_count("aaaaaaaaaaaaaaaaaaaa", 'a'), 20); - ASSERT_EQ(strings_count("a", 'a'), 1); - ASSERT_EQ(strings_count("", 'a'), 0); - ASSERT_EQ(strings_count(nullptr, 'c'), 0); + ASSERT_EQ(util_strings_count("aaaaaaaaaaaaaaaaaaaa", 'a'), 20); + ASSERT_EQ(util_strings_count("a", 'a'), 1); + ASSERT_EQ(util_strings_count("", 'a'), 0); + ASSERT_EQ(util_strings_count(nullptr, 'c'), 0); } TEST(utils_string_ut, test_strings_contains_any) { - ASSERT_EQ(strings_contains_any("1234567890abcdefgh!@", "ijklmnopq#123456789"), true); - ASSERT_EQ(strings_contains_any("1234567890abcdefgh!@", "ijklmnopqrstuvw)(*x&-"), false); - ASSERT_EQ(strings_contains_any("1234567890abcdefgh!@", ""), false); - ASSERT_EQ(strings_contains_any("1234567890abcdefgh!@", nullptr), false); - ASSERT_EQ(strings_contains_any("a", "cedefga123415"), true); - ASSERT_EQ(strings_contains_any("", "ijklmnopq#123456789"), false); - ASSERT_EQ(strings_contains_any(nullptr, "ijklmnopq#123456789"), false); + ASSERT_EQ(util_strings_contains_any("1234567890abcdefgh!@", "ijklmnopq#123456789"), true); + ASSERT_EQ(util_strings_contains_any("1234567890abcdefgh!@", "ijklmnopqrstuvw)(*x&-"), false); + ASSERT_EQ(util_strings_contains_any("1234567890abcdefgh!@", ""), false); + ASSERT_EQ(util_strings_contains_any("1234567890abcdefgh!@", nullptr), false); + ASSERT_EQ(util_strings_contains_any("a", "cedefga123415"), true); + ASSERT_EQ(util_strings_contains_any("", "ijklmnopq#123456789"), false); + ASSERT_EQ(util_strings_contains_any(nullptr, "ijklmnopq#123456789"), false); } - TEST(utils_string_ut, test_strings_to_lower) { char *result = nullptr; std::string str = "AB&^%CDE"; - result = strings_to_lower(str.c_str()); + result = util_strings_to_lower(str.c_str()); ASSERT_STRNE(result, nullptr); ASSERT_STREQ("ab&^%cde", result); free(result); str = "abcdefg12345*()%^#@"; - result = strings_to_lower(str.c_str()); + result = util_strings_to_lower(str.c_str()); ASSERT_STRNE(result, nullptr); ASSERT_STREQ(str.c_str(), result); free(result); str = "aBcDeFg12345*()%^#@"; - result = strings_to_lower(str.c_str()); + result = util_strings_to_lower(str.c_str()); ASSERT_STRNE(result, nullptr); ASSERT_STREQ("abcdefg12345*()%^#@", result); free(result); str = ""; - result = strings_to_lower(str.c_str()); + result = util_strings_to_lower(str.c_str()); ASSERT_STRNE(result, nullptr); ASSERT_STREQ(str.c_str(), result); free(result); - result = strings_to_lower(nullptr); + result = util_strings_to_lower(nullptr); ASSERT_STREQ(result, nullptr); - MOCK_SET(util_strdup_s, NULL); str = "A"; - result = strings_to_lower(str.c_str()); + result = util_strings_to_lower(str.c_str()); ASSERT_STREQ(result, NULL); MOCK_CLEAR(util_strdup_s); } @@ -91,40 +89,39 @@ TEST(utils_string_ut, test_strings_to_upper) char *result = nullptr; std::string str = "AB&^%CDE"; - result = strings_to_upper(str.c_str()); + result = util_strings_to_upper(str.c_str()); ASSERT_STRNE(result, nullptr); ASSERT_STREQ(str.c_str(), result); free(result); str = "abcdefg12345*()%^#@"; - result = strings_to_upper(str.c_str()); + result = util_strings_to_upper(str.c_str()); ASSERT_STRNE(result, nullptr); ASSERT_STREQ("ABCDEFG12345*()%^#@", result); free(result); str = "aBcDeFg12345*()%^#@"; - result = strings_to_upper(str.c_str()); + result = util_strings_to_upper(str.c_str()); ASSERT_STRNE(result, nullptr); ASSERT_STREQ("ABCDEFG12345*()%^#@", result); free(result); str = ""; - result = strings_to_upper(str.c_str()); + result = util_strings_to_upper(str.c_str()); ASSERT_STRNE(result, nullptr); ASSERT_STREQ(str.c_str(), result); free(result); - result = strings_to_upper(nullptr); + result = util_strings_to_upper(nullptr); ASSERT_STREQ(result, nullptr); MOCK_SET(util_strdup_s, nullptr); str = "a"; - result = strings_to_upper(str.c_str()); + result = util_strings_to_upper(str.c_str()); ASSERT_STREQ(result, nullptr); MOCK_CLEAR(util_strdup_s); } - TEST(utils_string_ut, test_strings_in_slice) { const char *array_long[] = { "abcd", "1234", nullptr, "", "&^%abc" }; @@ -133,14 +130,14 @@ TEST(utils_string_ut, test_strings_in_slice) const char *array_short[] = { "abcd" }; size_t array_short_len = sizeof(array_short) / sizeof(array_short[0]); - ASSERT_TRUE(strings_in_slice(array_long, array_long_len, "")); - ASSERT_FALSE(strings_in_slice(array_long, array_long_len, "abc")); - ASSERT_FALSE(strings_in_slice(array_long, array_long_len, nullptr)); - ASSERT_TRUE(strings_in_slice(array_short, array_short_len, "abcd")); - ASSERT_FALSE(strings_in_slice(array_short, array_short_len, "bcd")); - ASSERT_FALSE(strings_in_slice(array_short, array_short_len, nullptr)); - ASSERT_FALSE(strings_in_slice(nullptr, 0, "abcd")); - ASSERT_FALSE(strings_in_slice(nullptr, 0, nullptr)); + ASSERT_TRUE(util_strings_in_slice(array_long, array_long_len, "")); + ASSERT_FALSE(util_strings_in_slice(array_long, array_long_len, "abc")); + ASSERT_FALSE(util_strings_in_slice(array_long, array_long_len, nullptr)); + ASSERT_TRUE(util_strings_in_slice(array_short, array_short_len, "abcd")); + ASSERT_FALSE(util_strings_in_slice(array_short, array_short_len, "bcd")); + ASSERT_FALSE(util_strings_in_slice(array_short, array_short_len, nullptr)); + ASSERT_FALSE(util_strings_in_slice(nullptr, 0, "abcd")); + ASSERT_FALSE(util_strings_in_slice(nullptr, 0, nullptr)); } TEST(utils_string_ut, test_util_parse_byte_size_string) @@ -263,7 +260,6 @@ TEST(utils_string_ut, test_util_parse_byte_size_string) ret = util_parse_byte_size_string("1a.a1kI", &converted); ASSERT_NE(ret, 0); - ret = util_parse_byte_size_string(nullptr, &converted); ASSERT_NE(ret, 0); @@ -443,25 +439,25 @@ TEST(utils_string_ut, test_str_skip_str) const char *substr = "abcdefgh"; const char *result = nullptr; - result = str_skip_str(str, substr); + result = util_str_skip_str(str, substr); ASSERT_STREQ(result, "ij1234567890"); - result = str_skip_str(str, "habc"); + result = util_str_skip_str(str, "habc"); ASSERT_STREQ(result, nullptr); - result = str_skip_str(str, ""); + result = util_str_skip_str(str, ""); ASSERT_STREQ(result, str); - result = str_skip_str(str, nullptr); + result = util_str_skip_str(str, nullptr); ASSERT_STREQ(result, nullptr); - result = str_skip_str("a", "a"); + result = util_str_skip_str("a", "a"); ASSERT_STREQ(result, ""); - result = str_skip_str("", ""); + result = util_str_skip_str("", ""); ASSERT_STREQ(result, ""); - result = str_skip_str(nullptr, ""); + result = util_str_skip_str(nullptr, ""); ASSERT_STREQ(result, nullptr); } @@ -492,10 +488,10 @@ TEST(utils_string_ut, test_util_string_delchar) TEST(utils_string_ut, test_util_trim_newline) { - char s_all[ ] = { '\n', '\n', '\n', '\n', '\0' }; - char s_tail[ ] = { '\n', 'a', '\n', 'b', '\n', '\0' }; - char s_not_n[ ] = { 'a', '\n', 'b', 'c', '\0' }; - char s_empty[ ] = { '\0' }; + char s_all[] = { '\n', '\n', '\n', '\n', '\0' }; + char s_tail[] = { '\n', 'a', '\n', 'b', '\n', '\0' }; + char s_not_n[] = { 'a', '\n', 'b', 'c', '\0' }; + char s_empty[] = { '\0' }; char *s_nullptr = nullptr; util_trim_newline(s_all); @@ -516,13 +512,13 @@ TEST(utils_string_ut, test_util_trim_newline) TEST(utils_string_ut, test_util_trim_space) { - char s_all[ ] = { '\f', '\n', '\r', '\t', '\v', ' ', '\0' }; - char s_head[ ] = { '\f', '\n', '\r', 'a', 'b', 'c', '\0' }; - char s_tail[ ] = { 'a', 'b', 'c', '\t', '\v', ' ', '\0' }; - char s_head_tail[ ] = { '\f', 'a', 'b', 'c', '\v', ' ', '\0' }; - char s_mid[ ] = { 'a', 'b', '\r', '\t', '\v', 'c', '\0' }; - char s_not_space[ ] = { 'a', 'a', 'b', 'b', 'c', 'c', '\0' }; - char s_empty[ ] = { '\0' }; + char s_all[] = { '\f', '\n', '\r', '\t', '\v', ' ', '\0' }; + char s_head[] = { '\f', '\n', '\r', 'a', 'b', 'c', '\0' }; + char s_tail[] = { 'a', 'b', 'c', '\t', '\v', ' ', '\0' }; + char s_head_tail[] = { '\f', 'a', 'b', 'c', '\v', ' ', '\0' }; + char s_mid[] = { 'a', 'b', '\r', '\t', '\v', 'c', '\0' }; + char s_not_space[] = { 'a', 'a', 'b', 'b', 'c', 'c', '\0' }; + char s_empty[] = { '\0' }; char *s_nullptr = nullptr; char *result = nullptr; @@ -553,14 +549,14 @@ TEST(utils_string_ut, test_util_trim_space) TEST(utils_string_ut, test_util_trim_quotation) { - char s_all[ ] = { '"', '"', '"', '\n', '"', '\0' }; - char s_head[ ] = { '"', '"', 'a', 'b', 'c', '\0' }; - char s_tail_n[ ] = { 'a', 'b', 'c', '\n', '\n', '\0' }; - char s_tail_quo[ ] = { 'a', 'b', 'c', '"', '"', '\0' }; - char s_head_tail[ ] = { '"', '"', 'a', '\n', '"', '\0' }; - char s_mid[ ] = { 'a', 'b', '"', '\n', 'c', '\0' }; - char s_not_space[ ] = { 'a', 'b', 'c', 'd', 'e', '\0' }; - char s_empty[ ] = { '\0' }; + char s_all[] = { '"', '"', '"', '\n', '"', '\0' }; + char s_head[] = { '"', '"', 'a', 'b', 'c', '\0' }; + char s_tail_n[] = { 'a', 'b', 'c', '\n', '\n', '\0' }; + char s_tail_quo[] = { 'a', 'b', 'c', '"', '"', '\0' }; + char s_head_tail[] = { '"', '"', 'a', '\n', '"', '\0' }; + char s_mid[] = { 'a', 'b', '"', '\n', 'c', '\0' }; + char s_not_space[] = { 'a', 'b', 'c', 'd', 'e', '\0' }; + char s_empty[] = { '\0' }; char *s_nullptr = nullptr; char *result = nullptr; @@ -602,7 +598,7 @@ TEST(utils_string_ut, test_str_array_dup) char **result = nullptr; - result = str_array_dup(array_long, array_long_len); + result = util_str_array_dup(array_long, array_long_len); ASSERT_NE(result, nullptr); ASSERT_STREQ(result[0], "abcd"); free(result[0]); @@ -616,14 +612,14 @@ TEST(utils_string_ut, test_str_array_dup) ASSERT_STREQ(result[5], nullptr); free(result); - result = str_array_dup(array_short, array_short_len); + result = util_str_array_dup(array_short, array_short_len); ASSERT_NE(result, nullptr); ASSERT_STREQ(result[0], "abcd"); free(result[0]); ASSERT_STREQ(result[1], nullptr); free(result); - result = str_array_dup(nullptr, 0); + result = util_str_array_dup(nullptr, 0); ASSERT_EQ(result, nullptr); } @@ -719,7 +715,7 @@ TEST(utils_string_ut, test_dup_array_of_strings) size_t result_len = 0; int ret; - ret = dup_array_of_strings(array_long, array_long_len, &result, &result_len); + ret = util_dup_array_of_strings(array_long, array_long_len, &result, &result_len); ASSERT_EQ(ret, 0); ASSERT_EQ(array_long_len, result_len); ASSERT_NE(result, nullptr); @@ -734,13 +730,13 @@ TEST(utils_string_ut, test_dup_array_of_strings) free(result[4]); free(result); - ret = dup_array_of_strings(array_long, array_long_len, &result, nullptr); + ret = util_dup_array_of_strings(array_long, array_long_len, &result, nullptr); ASSERT_NE(ret, 0); - ret = dup_array_of_strings(array_long, array_long_len, nullptr, &result_len); + ret = util_dup_array_of_strings(array_long, array_long_len, nullptr, &result_len); ASSERT_NE(ret, 0); - ret = dup_array_of_strings(array_short, array_short_len, &result, &result_len); + ret = util_dup_array_of_strings(array_short, array_short_len, &result, &result_len); ASSERT_EQ(ret, 0); ASSERT_EQ(array_short_len, result_len); ASSERT_NE(result, nullptr); @@ -748,11 +744,11 @@ TEST(utils_string_ut, test_dup_array_of_strings) free(result[0]); free(result); - ret = dup_array_of_strings(nullptr, 0, &result, &result_len); + ret = util_dup_array_of_strings(nullptr, 0, &result, &result_len); ASSERT_EQ(ret, 0); MOCK_SET(calloc, nullptr); - ret = dup_array_of_strings(array_long, array_long_len, &result, &result_len); + ret = util_dup_array_of_strings(array_long, array_long_len, &result, &result_len); ASSERT_NE(ret, 0); MOCK_CLEAR(calloc); } diff --git a/test/image/oci/oci_config_merge/CMakeLists.txt b/test/image/oci/oci_config_merge/CMakeLists.txt index 7ecce47..53f9d3f 100644 --- a/test/image/oci/oci_config_merge/CMakeLists.txt +++ b/test/image/oci/oci_config_merge/CMakeLists.txt @@ -4,6 +4,7 @@ SET(EXE oci_config_merge_ut) add_executable(${EXE} ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/modules/image/oci/oci_config_merge.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/modules/image/image_spec_merge.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/utils/cutils/utils.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/utils/cutils/utils_regex.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/utils/cutils/utils_verify.c @@ -11,6 +12,7 @@ add_executable(${EXE} ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/utils/cutils/utils_string.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/utils/cutils/utils_convert.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/utils/cutils/utils_file.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/utils/cutils/utils_timestamp.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/utils/cutils/map/map.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/utils/cutils/map/rb_tree.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/utils/cutils/util_atomic.c @@ -47,6 +49,7 @@ target_include_directories(${EXE} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/modules/container/health_check ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/modules/events ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/modules/runtime + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/modules/image ${CMAKE_BINARY_DIR}/conf ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/utils/sha256 ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/config diff --git a/test/image/oci/registry/registry_ut.cc b/test/image/oci/registry/registry_ut.cc index cc51818..f656a49 100644 --- a/test/image/oci/registry/registry_ut.cc +++ b/test/image/oci/registry/registry_ut.cc @@ -56,7 +56,7 @@ using ::testing::Invoke; std::string get_dir() { - char abs_path[PATH_MAX]; + char abs_path[PATH_MAX] { 0x00 }; int ret = readlink("/proc/self/exe", abs_path, sizeof(abs_path)); if (ret < 0 || (size_t)ret >= sizeof(abs_path)) { return ""; @@ -369,7 +369,12 @@ int invokeStorageLayerCreate(const char *layer_id, storage_layer_create_opts_t * return 0; } -int invokeStorageSetHoldFlag(const char *layer_id, bool hold) +int invokeStorageIncHoldRefs(const char *layer_id) +{ + return 0; +} + +int invokeStorageDecHoldRefs(const char *layer_id) { return 0; } @@ -512,8 +517,10 @@ void mockCommonAll(MockStorage *mock, MockOciImage *oci_image_mock) .WillRepeatedly(Invoke(invokeStorageGetImgTopLayer)); EXPECT_CALL(*mock, StorageLayerCreate(::testing::_, ::testing::_)) .WillRepeatedly(Invoke(invokeStorageLayerCreate)); - EXPECT_CALL(*mock, StorageSetHoldFlag(::testing::_, ::testing::_)) - .WillRepeatedly(Invoke(invokeStorageSetHoldFlag)); + EXPECT_CALL(*mock, StorageIncHoldRefs(::testing::_)) + .WillRepeatedly(Invoke(invokeStorageIncHoldRefs)); + EXPECT_CALL(*mock, StorageDecHoldRefs(::testing::_)) + .WillRepeatedly(Invoke(invokeStorageDecHoldRefs)); EXPECT_CALL(*mock, StorageLayerGet(::testing::_)) .WillRepeatedly(Invoke(invokeStorageLayerGet)); EXPECT_CALL(*mock, StorageLayerTryRepairLowers(::testing::_, ::testing::_)) diff --git a/test/image/oci/storage/images/storage_images_ut.cc b/test/image/oci/storage/images/storage_images_ut.cc index 04d953a..4115e91 100644 --- a/test/image/oci/storage/images/storage_images_ut.cc +++ b/test/image/oci/storage/images/storage_images_ut.cc @@ -47,7 +47,7 @@ using ::testing::_; std::string GetDirectory() { - char abs_path[PATH_MAX]; + char abs_path[PATH_MAX] { 0x00 }; int ret = readlink("/proc/self/exe", abs_path, sizeof(abs_path)); if (ret < 0 || (size_t)ret >= sizeof(abs_path)) { return ""; @@ -261,7 +261,7 @@ TEST_F(StorageImagesCompatibilityUnitTest, test_load_v1_image) char store_real_path[PATH_MAX] = { 0x00 }; struct storage_module_init_options opts; std::string dir = GetDirectory() + "/data"; - ASSERT_STRNE(cleanpath(dir.c_str(), store_real_path, sizeof(store_real_path)), nullptr); + ASSERT_STRNE(util_clean_path(dir.c_str(), store_real_path, sizeof(store_real_path)), nullptr); EXPECT_CALL(m_storage_mock, StorageLayersGetByCompressDigest(_)) .WillRepeatedly(Invoke(invokeStorageLayersGetByCompressDigest)); @@ -283,7 +283,7 @@ protected: { struct storage_module_init_options opts; std::string dir = GetDirectory() + "/data"; - ASSERT_STRNE(cleanpath(dir.c_str(), store_real_path, sizeof(store_real_path)), nullptr); + ASSERT_STRNE(util_clean_path(dir.c_str(), store_real_path, sizeof(store_real_path)), nullptr); opts.storage_root = strdup(store_real_path); opts.driver_name = strdup("overlay"); @@ -409,7 +409,7 @@ TEST_F(StorageImagesUnitTest, test_image_store_create) GetDirectory() + "/data/resources/ffc8ef7968a2acb7545006bed022001addaa262c0f760883146c4a4fae54e689/" "=c2hhMjU2OmZmYzhlZjc5NjhhMmFjYjc1NDUwMDZiZWQwMjIwMDFhZGRhYTI2MmMwZjc2MDg4MzE0NmM0YTRmYWU1NGU2ODk="; - ASSERT_STRNE(cleanpath(config_file.c_str(), real_path, sizeof(real_path)), "manifest"); + ASSERT_STRNE(util_clean_path(config_file.c_str(), real_path, sizeof(real_path)), "manifest"); std::ifstream t(real_path); std::string buffer((std::istreambuf_iterator(t)), std::istreambuf_iterator()); @@ -432,7 +432,7 @@ TEST_F(StorageImagesUnitTest, test_image_store_create) std::string manifest_file = GetDirectory() + "/data/resources/ffc8ef7968a2acb7545006bed022001addaa262c0f760883146c4a4fae54e689/" + "manifest"; - ASSERT_STRNE(cleanpath(manifest_file.c_str(), real_path, sizeof(real_path)), nullptr); + ASSERT_STRNE(util_clean_path(manifest_file.c_str(), real_path, sizeof(real_path)), nullptr); std::ifstream manifest_stream(real_path); std::string manifest_content((std::istreambuf_iterator(manifest_stream)), std::istreambuf_iterator()); diff --git a/test/image/oci/storage/layers/storage_driver_ut.cc b/test/image/oci/storage/layers/storage_driver_ut.cc index 88e6f68..f99ac00 100644 --- a/test/image/oci/storage/layers/storage_driver_ut.cc +++ b/test/image/oci/storage/layers/storage_driver_ut.cc @@ -42,7 +42,7 @@ using ::testing::FLAGS_gmock_catch_leaked_mocks; std::string GetDirectory() { - char abs_path[PATH_MAX]; + char abs_path[PATH_MAX] { 0x00 }; int ret = readlink("/proc/self/exe", abs_path, sizeof(abs_path)); if (ret < 0 || (size_t)ret >= sizeof(abs_path)) { return ""; @@ -105,7 +105,7 @@ protected: std::string data_dir = GetDirectory() + "/data"; struct storage_module_init_options *opts; - ASSERT_STRNE(cleanpath(data_dir.c_str(), data_path, sizeof(data_path)), nullptr); + ASSERT_STRNE(util_clean_path(data_dir.c_str(), data_path, sizeof(data_path)), nullptr); std::string cp_command = "cp -r " + std::string(data_path) + " " + isulad_dir; ASSERT_EQ(system(cp_command.c_str()), 0); diff --git a/test/image/oci/storage/layers/storage_layers_ut.cc b/test/image/oci/storage/layers/storage_layers_ut.cc index f99c6bc..c0bc756 100644 --- a/test/image/oci/storage/layers/storage_layers_ut.cc +++ b/test/image/oci/storage/layers/storage_layers_ut.cc @@ -43,7 +43,7 @@ using ::testing::_; std::string GetDirectory() { - char abs_path[PATH_MAX]; + char abs_path[PATH_MAX] { 0x00 }; int ret = readlink("/proc/self/exe", abs_path, sizeof(abs_path)); if (ret < 0 || (size_t)ret >= sizeof(abs_path)) { return ""; @@ -158,13 +158,13 @@ protected: std::string run_dir = isulad_dir + "data/run"; std::string data_dir = GetDirectory() + "/data"; - ASSERT_STRNE(cleanpath(data_dir.c_str(), data_path, sizeof(data_path)), nullptr); + ASSERT_STRNE(util_clean_path(data_dir.c_str(), data_path, sizeof(data_path)), nullptr); std::string cp_command = "cp -r " + std::string(data_path) + " " + isulad_dir; ASSERT_EQ(system(cp_command.c_str()), 0); - ASSERT_STRNE(cleanpath(root_dir.c_str(), real_path, sizeof(real_path)), nullptr); + ASSERT_STRNE(util_clean_path(root_dir.c_str(), real_path, sizeof(real_path)), nullptr); opts.storage_root = strdup(real_path); - ASSERT_STRNE(cleanpath(run_dir.c_str(), real_run_path, sizeof(real_run_path)), nullptr); + ASSERT_STRNE(util_clean_path(run_dir.c_str(), real_run_path, sizeof(real_run_path)), nullptr); opts.storage_run_root = strdup(real_run_path); opts.driver_name = strdup("overlay"); diff --git a/test/image/oci/storage/rootfs/storage_rootfs_ut.cc b/test/image/oci/storage/rootfs/storage_rootfs_ut.cc index b2adc1a..a4864da 100644 --- a/test/image/oci/storage/rootfs/storage_rootfs_ut.cc +++ b/test/image/oci/storage/rootfs/storage_rootfs_ut.cc @@ -35,7 +35,7 @@ std::string META_DATA_CONTENT = "metadata test"; std::string GetDirectory() { - char abs_path[PATH_MAX]; + char abs_path[PATH_MAX] { 0x00 }; int ret = readlink("/proc/self/exe", abs_path, sizeof(abs_path)); if (ret < 0 || (size_t)ret >= sizeof(abs_path)) { return ""; @@ -88,7 +88,7 @@ protected: { struct storage_module_init_options opts; std::string dir = GetDirectory() + "/data"; - ASSERT_STRNE(cleanpath(dir.c_str(), store_real_path, sizeof(store_real_path)), nullptr); + ASSERT_STRNE(util_clean_path(dir.c_str(), store_real_path, sizeof(store_real_path)), nullptr); opts.storage_root = strdup(store_real_path); opts.driver_name = strdup("overlay"); @@ -189,24 +189,6 @@ TEST_F(StorageRootfsUnitTest, test_rootfs_store_exists) ASSERT_FALSE(rootfs_store_exists(incorrectId.c_str())); } -TEST_F(StorageRootfsUnitTest, test_rootfs_store_metadata) -{ - std::string incorrectId { "ff67da98ab8540d713209" }; - char *metadata = NULL; - - metadata = rootfs_store_metadata(ids.at(0).c_str()); - ASSERT_STREQ(metadata, META_DATA_CONTENT.c_str()); - free(metadata); - metadata = NULL; - - metadata = rootfs_store_metadata(ids.at(1).c_str()); - ASSERT_STREQ(metadata, "{}"); - free(metadata); - metadata = NULL; - - ASSERT_EQ(rootfs_store_metadata(incorrectId.c_str()), nullptr); -} - TEST_F(StorageRootfsUnitTest, test_rootfs_store_get_all_rootfs) { std::string source = std::string(store_real_path) + "/overlay-containers/" + ids.at(0); diff --git a/test/mocks/namespace_mock.cc b/test/mocks/namespace_mock.cc index 087cf48..823791c 100644 --- a/test/mocks/namespace_mock.cc +++ b/test/mocks/namespace_mock.cc @@ -24,7 +24,7 @@ void MockNamespace_SetMock(MockNamespace* mock) g_namespace_mock = mock; } -char *connected_container(const char *mode) +char *namespace_get_connected_container(const char *mode) { if (g_namespace_mock != nullptr) { return g_namespace_mock->ConnectedContainer(mode); diff --git a/test/mocks/storage_mock.cc b/test/mocks/storage_mock.cc index 1b50040..9976314 100644 --- a/test/mocks/storage_mock.cc +++ b/test/mocks/storage_mock.cc @@ -137,10 +137,18 @@ void free_layer(struct layer *l) return; } -int storage_set_hold_flag(const char *layer_id, bool hold) +int storage_inc_hold_refs(const char *layer_id) { if (g_storage_mock != NULL) { - return g_storage_mock->StorageSetHoldFlag(layer_id, hold); + return g_storage_mock->StorageIncHoldRefs(layer_id); + } + return -1; +} + +int storage_dec_hold_refs(const char *layer_id) +{ + if (g_storage_mock != NULL) { + return g_storage_mock->StorageIncHoldRefs(layer_id); } return -1; } diff --git a/test/mocks/storage_mock.h b/test/mocks/storage_mock.h index 9e34907..84eb56f 100644 --- a/test/mocks/storage_mock.h +++ b/test/mocks/storage_mock.h @@ -37,7 +37,8 @@ public: MOCK_METHOD1(StorageLayerGet, struct layer * (const char *layer_id)); MOCK_METHOD2(StorageLayerTryRepairLowers, int(const char *layer_id, const char *last_layer_id)); MOCK_METHOD1(FreeLayer, void(struct layer *l)); - MOCK_METHOD2(StorageSetHoldFlag, int (const char *layer_id, bool hold)); + MOCK_METHOD1(StorageIncHoldRefs, int (const char *layer_id)); + MOCK_METHOD1(StorageDecHoldRefs, int (const char *layer_id)); }; void MockStorage_SetMock(MockStorage* mock); diff --git a/test/path/path_ut.cc b/test/path/path_ut.cc index afd164a..ce6dcc0 100644 --- a/test/path/path_ut.cc +++ b/test/path/path_ut.cc @@ -48,9 +48,7 @@ static char *getcwd_specify(char *str, size_t size) return str; } -static int create_tmp_symbolic_link(const char *path, - const char *path_file, - const char *path_link) +static int create_tmp_symbolic_link(const char *path, const char *path_file, const char *path_link) { if (path == nullptr || path_file == nullptr || path_link == nullptr) { return -1; @@ -93,46 +91,46 @@ TEST(path_ut, test_cleanpath) std::string str; char realpath[PATH_MAX]; - result = cleanpath(nullptr, realpath, sizeof(realpath)); + result = util_clean_path(nullptr, realpath, sizeof(realpath)); ASSERT_STREQ(result, nullptr); str = ""; - result = cleanpath(str.c_str(), realpath, sizeof(realpath)); + result = util_clean_path(str.c_str(), realpath, sizeof(realpath)); ASSERT_STREQ(result, nullptr); str = "/home/dir/../file"; - result = cleanpath(str.c_str(), realpath, sizeof(realpath)); + result = util_clean_path(str.c_str(), realpath, sizeof(realpath)); ASSERT_STREQ(result, "/home/file"); str = "/home/dir/./file"; - result = cleanpath(str.c_str(), realpath, sizeof(realpath)); + result = util_clean_path(str.c_str(), realpath, sizeof(realpath)); ASSERT_STREQ(result, "/home/dir/file"); str = "./dir/file"; MOCK_SET_V(getcwd, getcwd_specify); - result = cleanpath(str.c_str(), realpath, sizeof(realpath)); + result = util_clean_path(str.c_str(), realpath, sizeof(realpath)); ASSERT_STREQ(result, "/home/dir/file"); MOCK_CLEAR(getcwd); str = "/home/file"; - result = cleanpath(str.c_str(), realpath, PATH_LENGTH_TEST); + result = util_clean_path(str.c_str(), realpath, PATH_LENGTH_TEST); ASSERT_STREQ(result, nullptr); str = "/home/file"; - result = cleanpath(str.c_str(), nullptr, 0); + result = util_clean_path(str.c_str(), nullptr, 0); ASSERT_STREQ(result, nullptr); } TEST(path_ut, test_specify_current_dir) { - ASSERT_FALSE(specify_current_dir(nullptr)); - ASSERT_TRUE(specify_current_dir("")); - ASSERT_TRUE(specify_current_dir("/home/.")); - ASSERT_TRUE(specify_current_dir(".")); - ASSERT_FALSE(specify_current_dir("/home/file")); - ASSERT_FALSE(specify_current_dir("/home/..")); - ASSERT_FALSE(specify_current_dir("/home")); - ASSERT_FALSE(specify_current_dir("home")); + ASSERT_FALSE(util_specify_current_dir(nullptr)); + ASSERT_TRUE(util_specify_current_dir("")); + ASSERT_TRUE(util_specify_current_dir("/home/.")); + ASSERT_TRUE(util_specify_current_dir(".")); + ASSERT_FALSE(util_specify_current_dir("/home/file")); + ASSERT_FALSE(util_specify_current_dir("/home/..")); + ASSERT_FALSE(util_specify_current_dir("/home")); + ASSERT_FALSE(util_specify_current_dir("home")); } TEST(path_ut, test_follow_symlink_in_scope) @@ -140,35 +138,35 @@ TEST(path_ut, test_follow_symlink_in_scope) std::string fullpath, rootpath; char *res = nullptr; - res = follow_symlink_in_scope(nullptr, nullptr); + res = util_follow_symlink_in_scope(nullptr, nullptr); ASSERT_STREQ(res, nullptr); free(res); res = nullptr; fullpath = ""; rootpath = ""; - res = follow_symlink_in_scope(fullpath.c_str(), rootpath.c_str()); + res = util_follow_symlink_in_scope(fullpath.c_str(), rootpath.c_str()); ASSERT_STREQ(res, nullptr); free(res); res = nullptr; fullpath = "/home/dir/file"; rootpath = "/home"; - res = follow_symlink_in_scope(fullpath.c_str(), rootpath.c_str()); + res = util_follow_symlink_in_scope(fullpath.c_str(), rootpath.c_str()); ASSERT_STREQ(res, "/home/dir/file"); free(res); res = nullptr; fullpath = "/home/dir/file"; rootpath = "/home/dir/../file"; - res = follow_symlink_in_scope(fullpath.c_str(), rootpath.c_str()); + res = util_follow_symlink_in_scope(fullpath.c_str(), rootpath.c_str()); ASSERT_STREQ(res, nullptr); free(res); res = nullptr; fullpath = "/home/dir/file"; rootpath = "/home/dir/../"; - res = follow_symlink_in_scope(fullpath.c_str(), rootpath.c_str()); + res = util_follow_symlink_in_scope(fullpath.c_str(), rootpath.c_str()); ASSERT_STREQ(res, "/home/dir/file"); free(res); res = nullptr; @@ -180,7 +178,7 @@ TEST(path_ut, test_follow_symlink_in_scope) const char *path_link = "/tmp/just_for_ut/link"; ASSERT_EQ(create_tmp_symbolic_link(path, path_file, path_link), 0); MOCK_SET_V(readlink, readlink_specify); - res = follow_symlink_in_scope(fullpath.c_str(), rootpath.c_str()); + res = util_follow_symlink_in_scope(fullpath.c_str(), rootpath.c_str()); ASSERT_STREQ(res, "/tmp/just_for_ut/dir/file"); MOCK_CLEAR(readlink); ASSERT_EQ(util_recursive_rmdir("/tmp/just_for_ut", 0), 0); @@ -193,31 +191,31 @@ TEST(path_ut, test_split_dir_and_base_name) char *dir = nullptr; char *base = nullptr; - ASSERT_EQ(split_dir_and_base_name(nullptr, &dir, &base), -1); + ASSERT_EQ(util_split_dir_and_base_name(nullptr, &dir, &base), -1); free(dir); dir = nullptr; free(base); base = nullptr; - ASSERT_EQ(split_dir_and_base_name("", &dir, &base), 0); + ASSERT_EQ(util_split_dir_and_base_name("", &dir, &base), 0); free(dir); dir = nullptr; free(base); base = nullptr; - ASSERT_EQ(split_dir_and_base_name("/home/file", &dir, &base), 0); + ASSERT_EQ(util_split_dir_and_base_name("/home/file", &dir, &base), 0); free(dir); dir = nullptr; free(base); base = nullptr; - ASSERT_EQ(split_dir_and_base_name("/home/file", nullptr, nullptr), 0); + ASSERT_EQ(util_split_dir_and_base_name("/home/file", nullptr, nullptr), 0); free(dir); dir = nullptr; free(base); base = nullptr; - split_dir_and_base_name("/home/file", &dir, &base); + util_split_dir_and_base_name("/home/file", &dir, &base); ASSERT_STREQ(dir, "/home"); ASSERT_STREQ(base, "file"); free(dir); @@ -231,31 +229,31 @@ TEST(path_ut, test_filepath_split) char *dir = nullptr; char *base = nullptr; - ASSERT_EQ(filepath_split(nullptr, &dir, &base), -1); + ASSERT_EQ(util_filepath_split(nullptr, &dir, &base), -1); free(dir); dir = nullptr; free(base); base = nullptr; - ASSERT_EQ(filepath_split("", &dir, &base), 0); + ASSERT_EQ(util_filepath_split("", &dir, &base), 0); free(dir); dir = nullptr; free(base); base = nullptr; - ASSERT_EQ(filepath_split("/home/file", &dir, &base), 0); + ASSERT_EQ(util_filepath_split("/home/file", &dir, &base), 0); free(dir); dir = nullptr; free(base); base = nullptr; - ASSERT_EQ(filepath_split("/home/file", nullptr, nullptr), 0); + ASSERT_EQ(util_filepath_split("/home/file", nullptr, nullptr), 0); free(dir); dir = nullptr; free(base); base = nullptr; - filepath_split("/home/file", &dir, &base); + util_filepath_split("/home/file", &dir, &base); ASSERT_STREQ(dir, "/home/"); ASSERT_STREQ(base, "file"); free(dir); @@ -263,7 +261,7 @@ TEST(path_ut, test_filepath_split) free(base); base = nullptr; - filepath_split("/home/", &dir, &base); + util_filepath_split("/home/", &dir, &base); ASSERT_STREQ(dir, "/home/"); ASSERT_STREQ(base, ""); free(dir); @@ -276,32 +274,32 @@ TEST(path_ut, test_get_resource_path) { char *res = nullptr; - res = get_resource_path(nullptr, "./test"); + res = util_get_resource_path(nullptr, "./test"); ASSERT_STREQ(res, nullptr); free(res); res = nullptr; - res = get_resource_path("", ""); + res = util_get_resource_path("", ""); ASSERT_STREQ(res, nullptr); free(res); res = nullptr; - res = get_resource_path("/home", "./test"); + res = util_get_resource_path("/home", "./test"); ASSERT_STREQ(res, "/home/test"); free(res); res = nullptr; - res = get_resource_path("/home/dir", "tmp/.././test"); + res = util_get_resource_path("/home/dir", "tmp/.././test"); ASSERT_STREQ(res, "/home/dir/test"); free(res); res = nullptr; - res = get_resource_path("/home/dir", ".././test"); + res = util_get_resource_path("/home/dir", ".././test"); ASSERT_STREQ(res, nullptr); free(res); res = nullptr; - res = get_resource_path("/home////dir", ".///./././test/file"); + res = util_get_resource_path("/home////dir", ".///./././test/file"); ASSERT_STREQ(res, "/home/dir/test/file"); free(res); res = nullptr; @@ -313,7 +311,7 @@ TEST(path_ut, test_resolve_path) char *resolvedpath = nullptr; char *abspath = nullptr; - ASSERT_EQ(resolve_path(nullptr, nullptr, &resolvedpath, &abspath), -1); + ASSERT_EQ(util_resolve_path(nullptr, nullptr, &resolvedpath, &abspath), -1); free(resolvedpath); resolvedpath = nullptr; free(abspath); @@ -321,7 +319,7 @@ TEST(path_ut, test_resolve_path) rootpath = ""; path = ""; - ASSERT_EQ(resolve_path(rootpath.c_str(), path.c_str(), &resolvedpath, &abspath), -1); + ASSERT_EQ(util_resolve_path(rootpath.c_str(), path.c_str(), &resolvedpath, &abspath), -1); free(resolvedpath); resolvedpath = nullptr; free(abspath); @@ -329,7 +327,7 @@ TEST(path_ut, test_resolve_path) rootpath = "/home"; path = "/home/dir/test"; - ASSERT_EQ(resolve_path(rootpath.c_str(), path.c_str(), &resolvedpath, &abspath), 0); + ASSERT_EQ(util_resolve_path(rootpath.c_str(), path.c_str(), &resolvedpath, &abspath), 0); free(resolvedpath); resolvedpath = nullptr; free(abspath); @@ -338,10 +336,10 @@ TEST(path_ut, test_resolve_path) TEST(path_ut, test_has_trailing_path_separator) { - ASSERT_FALSE(has_trailing_path_separator(nullptr)); - ASSERT_FALSE(has_trailing_path_separator("")); - ASSERT_TRUE(has_trailing_path_separator("/home/")); - ASSERT_FALSE(has_trailing_path_separator("/home")); + ASSERT_FALSE(util_has_trailing_path_separator(nullptr)); + ASSERT_FALSE(util_has_trailing_path_separator("")); + ASSERT_TRUE(util_has_trailing_path_separator("/home/")); + ASSERT_FALSE(util_has_trailing_path_separator("/home")); } TEST(path_ut, test_preserve_trailing_dot_or_separator) @@ -349,26 +347,26 @@ TEST(path_ut, test_preserve_trailing_dot_or_separator) std::string cleanedpath, originalpath; char *res = nullptr; - res = preserve_trailing_dot_or_separator(nullptr, nullptr); + res = util_preserve_trailing_dot_or_separator(nullptr, nullptr); ASSERT_STREQ(res, nullptr); free(res); res = nullptr; - res = preserve_trailing_dot_or_separator("", ""); + res = util_preserve_trailing_dot_or_separator("", ""); ASSERT_STREQ(res, nullptr); free(res); res = nullptr; cleanedpath = "/home/test"; originalpath = "/home/test/."; - res = preserve_trailing_dot_or_separator(cleanedpath.c_str(), originalpath.c_str()); + res = util_preserve_trailing_dot_or_separator(cleanedpath.c_str(), originalpath.c_str()); ASSERT_STREQ(res, "/home/test/."); free(res); res = nullptr; cleanedpath = "/home/test"; originalpath = "/home/test/"; - res = preserve_trailing_dot_or_separator(cleanedpath.c_str(), originalpath.c_str()); + res = util_preserve_trailing_dot_or_separator(cleanedpath.c_str(), originalpath.c_str()); ASSERT_STREQ(res, "/home/test/"); free(res); res = nullptr; diff --git a/test/runtime/isula/CMakeLists.txt b/test/runtime/isula/CMakeLists.txt index 9b4b350..4305997 100644 --- a/test/runtime/isula/CMakeLists.txt +++ b/test/runtime/isula/CMakeLists.txt @@ -10,6 +10,7 @@ add_executable(${EXE} ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/utils_string.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/utils_convert.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/utils_file.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/utils_timestamp.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/util_atomic.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/sha256/sha256.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/tar/util_gzip.c diff --git a/test/runtime/lcr/CMakeLists.txt b/test/runtime/lcr/CMakeLists.txt index 829027e..6f8f784 100644 --- a/test/runtime/lcr/CMakeLists.txt +++ b/test/runtime/lcr/CMakeLists.txt @@ -10,6 +10,7 @@ add_executable(${EXE} ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/utils_string.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/utils_convert.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/utils_file.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/utils_timestamp.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/util_atomic.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/sha256/sha256.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/path.c diff --git a/test/specs/specs/CMakeLists.txt b/test/specs/specs/CMakeLists.txt index c9c29b2..e64f76a 100644 --- a/test/specs/specs/CMakeLists.txt +++ b/test/specs/specs/CMakeLists.txt @@ -10,6 +10,7 @@ add_executable(${EXE} ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/utils_string.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/utils_convert.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/utils_file.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/utils_timestamp.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/util_atomic.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/sha256/sha256.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/path.c diff --git a/test/specs/specs_extend/CMakeLists.txt b/test/specs/specs_extend/CMakeLists.txt index 6193a89..50f30ad 100644 --- a/test/specs/specs_extend/CMakeLists.txt +++ b/test/specs/specs_extend/CMakeLists.txt @@ -10,6 +10,7 @@ add_executable(${EXE} ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/utils_string.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/utils_convert.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/utils_file.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/utils_timestamp.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/util_atomic.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/sha256/sha256.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/path.c -- 2.20.1