From a71db030c8d47355ede7955c44e5bce757b2ed43 Mon Sep 17 00:00:00 2001 From: gaorui Date: Tue, 13 Dec 2022 10:51:36 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90=E5=AE=B9=E5=99=A8=E9=9A=94=E7=A6=BB?= =?UTF-8?q?=E3=80=91=E6=97=B6=E9=92=9F=E5=91=BD=E5=90=8D=E7=A9=BA=E9=97=B4?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I9927563a6c3490e3644c49bd256baa0fa15e1d60 Signed-off-by: gaorui --- compat/posix/src/time.c | 28 +- fs/proc/os_adapt/pid_proc.c | 61 +++- fs/proc/os_adapt/sys_user.c | 1 + kernel/Kconfig | 7 + kernel/base/BUILD.gn | 2 + kernel/base/container/los_container_bundle.c | 60 +++- kernel/base/container/los_string_util.c | 105 +++++++ kernel/base/container/los_time_container.c | 290 ++++++++++++++++++ kernel/base/core/los_process.c | 12 +- kernel/base/include/los_container_bundle.h | 4 + kernel/base/include/los_process_pri.h | 3 +- kernel/base/include/los_string_util.h | 44 +++ kernel/base/include/los_time_container.h | 82 +++++ testsuites/unittest/BUILD.gn | 5 + testsuites/unittest/config.gni | 1 + .../libc/posix/container/It_posix_container.h | 11 + .../unittest/libc/posix/container/config.gni | 9 + .../full/It_posix_container_time_001.cpp | 74 +++++ .../full/It_posix_container_time_002.cpp | 127 ++++++++ .../full/It_posix_container_time_003.cpp | 95 ++++++ .../full/It_posix_container_time_004.cpp | 110 +++++++ .../full/It_posix_container_time_005.cpp | 113 +++++++ .../full/It_posix_container_time_006.cpp | 53 ++++ .../full/It_posix_container_time_007.cpp | 68 ++++ .../full/It_posix_container_time_008.cpp | 71 +++++ .../full/It_posix_container_time_009.cpp | 73 +++++ .../posix/container/posix_container_test.cpp | 46 +++ 27 files changed, 1539 insertions(+), 16 deletions(-) create mode 100644 kernel/base/container/los_string_util.c create mode 100644 kernel/base/container/los_time_container.c create mode 100644 kernel/base/include/los_string_util.h create mode 100644 kernel/base/include/los_time_container.h create mode 100644 testsuites/unittest/libc/posix/container/full/It_posix_container_time_001.cpp create mode 100644 testsuites/unittest/libc/posix/container/full/It_posix_container_time_002.cpp create mode 100644 testsuites/unittest/libc/posix/container/full/It_posix_container_time_003.cpp create mode 100644 testsuites/unittest/libc/posix/container/full/It_posix_container_time_004.cpp create mode 100644 testsuites/unittest/libc/posix/container/full/It_posix_container_time_005.cpp create mode 100644 testsuites/unittest/libc/posix/container/full/It_posix_container_time_006.cpp create mode 100644 testsuites/unittest/libc/posix/container/full/It_posix_container_time_007.cpp create mode 100644 testsuites/unittest/libc/posix/container/full/It_posix_container_time_008.cpp create mode 100644 testsuites/unittest/libc/posix/container/full/It_posix_container_time_009.cpp diff --git a/compat/posix/src/time.c b/compat/posix/src/time.c index 060bb135..eac383ac 100644 --- a/compat/posix/src/time.c +++ b/compat/posix/src/time.c @@ -1,5 +1,4 @@ /* - * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -52,6 +51,9 @@ #ifdef LOSCFG_PID_CONTAINER #include "los_pid_container.h" #endif +#ifdef LOSCFG_TIME_CONTAINER +#include "los_time_container.h" +#endif #define CPUCLOCK_PERTHREAD_MASK 4 #define CPUCLOCK_ID_OFFSET 3 @@ -266,14 +268,13 @@ STATIC INLINE struct timespec64 OsTimeSpecAdd(const struct timespec64 t1, const ret.tv_sec = t1.tv_sec + t2.tv_sec; ret.tv_nsec = t1.tv_nsec + t2.tv_nsec; - if (ret.tv_nsec >= OS_SYS_NS_PER_SECOND) { - ret.tv_sec += 1; - ret.tv_nsec -= OS_SYS_NS_PER_SECOND; - } else if (ret.tv_nsec < 0L) { + + ret.tv_sec += ret.tv_nsec / OS_SYS_NS_PER_SECOND; + ret.tv_nsec = ret.tv_nsec % OS_SYS_NS_PER_SECOND; + if (ret.tv_nsec < 0L){ ret.tv_sec -= 1; ret.tv_nsec += OS_SYS_NS_PER_SECOND; } - return ret; } @@ -661,7 +662,9 @@ int clock_gettime(clockid_t clockID, struct timespec *tp) UINT32 intSave; struct timespec64 tmp = {0}; struct timespec64 hwTime = {0}; - +#ifdef LOSCFG_TIME_CONTAINER + struct timespec64 timeOffsets = {0}; +#endif if (clockID > MAX_CLOCKS) { goto ERROUT; } @@ -674,13 +677,24 @@ int clock_gettime(clockid_t clockID, struct timespec *tp) switch (clockID) { case CLOCK_MONOTONIC_RAW: +#ifdef LOSCFG_TIME_CONTAINER + timeOffsets = OsGetOffsetsFromContainer(); + tmp = OsTimeSpecAdd(hwTime, timeOffsets); + tp->tv_sec = tmp.tv_sec; + tp->tv_nsec = tmp.tv_nsec; +#else tp->tv_sec = hwTime.tv_sec; tp->tv_nsec = hwTime.tv_nsec; +#endif break; case CLOCK_MONOTONIC: LOS_SpinLockSave(&g_timeSpin, &intSave); tmp = OsTimeSpecAdd(hwTime, g_accDeltaFromAdj); LOS_SpinUnlockRestore(&g_timeSpin, intSave); +#ifdef LOSCFG_TIME_CONTAINER + timeOffsets = OsGetOffsetsFromContainer(); + tmp = OsTimeSpecAdd(tmp, timeOffsets); +#endif tp->tv_sec = tmp.tv_sec; tp->tv_nsec = tmp.tv_nsec; break; diff --git a/fs/proc/os_adapt/pid_proc.c b/fs/proc/os_adapt/pid_proc.c index 64c3b5f4..d4e1b06c 100644 --- a/fs/proc/os_adapt/pid_proc.c +++ b/fs/proc/os_adapt/pid_proc.c @@ -52,6 +52,9 @@ #ifdef LOSCFG_NET_CONTAINER #include "los_net_container.h" #endif +#ifdef LOSCFG_TIME_CONTAINER +#include "los_time_container.h" +#endif struct ProcfsPidEntry { char *name; @@ -97,6 +100,9 @@ static struct VnodeOps g_procfsPidCpupRead; #ifdef LOSCFG_CHROOT static struct VnodeOps g_procfsPidRootVops; #endif +#ifdef LOSCFG_TIME_CONTAINER +static struct VnodeOps g_procfsPidTimeOffsetsVops; +#endif int PIDMemInfoProcRead(struct SeqBuf *seqBuf, void *v) { @@ -337,6 +343,9 @@ static const struct ProcfsPidEntry g_procfsPidSubEntries[] = { PID("uid_map", PID_FILE_MODE, &g_procfsComVops, &g_procUidMapOperations), PID("gid_map", PID_FILE_MODE, &g_procfsComVops, &g_procGidMapOperations), #endif +#ifdef LOSCFG_TIME_CONTAINER + PID("time_offsets", PID_FILE_MODE, &g_procfsPidTimeOffsetsVops, &g_procTimeOffsetsOperations), +#endif }; static const struct ProcfsPidEntry procfsContainerSubEntries[] = { @@ -346,7 +355,9 @@ static const struct ProcfsPidEntry procfsContainerSubEntries[] = { CONTAINER("user"), CONTAINER("uts"), CONTAINER("net"), - CONTAINER("ipc") + CONTAINER("ipc"), + CONTAINER("time_for_children"), + CONTAINER("time") }; enum { @@ -356,7 +367,9 @@ enum { USER_CONTAINER, UTS_CONTAINER, NET_CONTAINER, - IPC_CONTAINER + IPC_CONTAINER, + TIME_FOR_CHILDREN_CONTAINER, + TIME_CONTAINER }; static void ProfsSetPidEntryVop(const char *name, struct Vnode *vp, const struct ProcfsPidEntry *ppe, int arrSize) @@ -551,6 +564,15 @@ static ssize_t ProcfsContainerSubReadlink(struct Vnode *vnode, char *buffer, siz } else if (!strncmp(procfsContainerSubEntries[IPC_CONTAINER].name, entry->name, entry->nameLen)) { #ifdef LOSCFG_IPC_CONTAINER vnum = ctnBundle->ipcContainer->containerBase.vnum; +#endif + } else if (!strncmp(procfsContainerSubEntries[TIME_FOR_CHILDREN_CONTAINER].name, entry->name, entry->nameLen) && + strlen(procfsContainerSubEntries[TIME_FOR_CHILDREN_CONTAINER].name) == entry->nameLen) { +#ifdef LOSCFG_TIME_CONTAINER + vnum = ctnBundle->timeContainerForChildren->containerBase.vnum; +#endif + } else if (!strncmp(procfsContainerSubEntries[TIME_CONTAINER].name, entry->name, entry->nameLen)) { +#ifdef LOSCFG_TIME_CONTAINER + vnum = ctnBundle->timeContainer->containerBase.vnum; #endif } @@ -564,6 +586,12 @@ SET_CONTAINERNAME: if (ret < 0) { return ret; } + } else if (!strncmp(procfsContainerSubEntries[TIME_FOR_CHILDREN_CONTAINER].name, entry->name, entry->nameLen)) { + ret = snprintf_s(containerName, CONTAINER_NAME_LEN, CONTAINER_NAME_LEN - 1, "\'%s:[%u]\'", + procfsContainerSubEntries[TIME_CONTAINER].name, vnum); + if (ret < 0) { + return ret; + } } else { ret = snprintf_s(containerName, CONTAINER_NAME_LEN, CONTAINER_NAME_LEN - 1, "\'%s:[%u]\'", entry->name, vnum); if (ret < 0) { @@ -810,6 +838,15 @@ VOID *OsProcfsContainerGet(struct Vnode *vnode) } else if (!strncmp(procfsContainerSubEntries[IPC_CONTAINER].name, entry->name, entry->nameLen)) { #ifdef LOSCFG_IPC_CONTAINER targetContainer = (void *)containerBundle->ipcContainer; +#endif + } else if (!strncmp(procfsContainerSubEntries[TIME_FOR_CHILDREN_CONTAINER].name, entry->name, entry->nameLen) && + strlen(procfsContainerSubEntries[TIME_FOR_CHILDREN_CONTAINER].name) == entry->nameLen) { +#ifdef LOSCFG_TIME_CONTAINER + targetContainer = (void *)containerBundle->timeContainerForChildren; +#endif + } else if (!strncmp(procfsContainerSubEntries[TIME_CONTAINER].name, entry->name, entry->nameLen)) { +#ifdef LOSCFG_TIME_CONTAINER + targetContainer = (void *)containerBundle->timeContainer; #endif } else { PRINT_ERR("Error. entry->name is invalid as %s\n", entry->name); @@ -854,6 +891,15 @@ INT32 OsProcfsContainerTypeGet(struct Vnode *vnode) } else if (!strncmp(procfsContainerSubEntries[IPC_CONTAINER].name, entry->name, entry->nameLen)) { #ifdef LOSCFG_IPC_CONTAINER containerType = CLONE_NEWIPC; +#endif + } else if (!strncmp(procfsContainerSubEntries[TIME_FOR_CHILDREN_CONTAINER].name, entry->name, entry->nameLen) && + strlen(procfsContainerSubEntries[TIME_FOR_CHILDREN_CONTAINER].name) == entry->nameLen) { +#ifdef LOSCFG_TIME_CONTAINER + containerType = CLONE_NEWTIME; +#endif + } else if (!strncmp(procfsContainerSubEntries[TIME_CONTAINER].name, entry->name, entry->nameLen)) { +#ifdef LOSCFG_TIME_CONTAINER + containerType = CLONE_NEWTIME; #endif } else { PRINT_ERR("Error. entry->name is invalid as %s\n", entry->name); @@ -975,3 +1021,14 @@ static struct VnodeOps g_procfsComVops = { .Truncate = VfsProcfsTruncate }; #endif + +#ifdef LOSCFG_TIME_CONTAINER +static struct VnodeOps g_procfsPidTimeOffsetsVops = { + .Lookup = VfsProcfsLookup, + .Getattr = VfsProcfsStat, + .Readdir = VfsProcfsReaddir, + .Opendir = VfsProcfsOpendir, + .Closedir = VfsProcfsClosedir, + .Truncate = VfsProcfsTruncate +}; +#endif diff --git a/fs/proc/os_adapt/sys_user.c b/fs/proc/os_adapt/sys_user.c index 1ce16951..03bdefb3 100644 --- a/fs/proc/os_adapt/sys_user.c +++ b/fs/proc/os_adapt/sys_user.c @@ -56,6 +56,7 @@ static char *g_procfsContainerFn[] = { "max_uts_container", "max_net_container", "max_ipc_container", + "max_time_container" }; struct ContainerConfig g_containerConfig; diff --git a/kernel/Kconfig b/kernel/Kconfig index 457dbdec..4037784b 100644 --- a/kernel/Kconfig +++ b/kernel/Kconfig @@ -133,6 +133,13 @@ config IPC_CONTAINER help This option will enable IPC container. +config TIME_CONTAINER + bool "Enable TIME container" + default n + depends on KERNEL_CONTAINER + help + This option will enable TIME container. + ######################### config options of extended ##################### source "kernel/extended/Kconfig" diff --git a/kernel/base/BUILD.gn b/kernel/base/BUILD.gn index 4f15cbf5..9adf7177 100644 --- a/kernel/base/BUILD.gn +++ b/kernel/base/BUILD.gn @@ -40,6 +40,8 @@ kernel_module(module_name) { "container/los_user_container.c", "container/los_ipc_container.c", "container/los_mnt_container.c", + "container/los_string_util.c", + "container/los_time_container.c", "core/los_bitmap.c", "core/los_process.c", "core/los_smp.c", diff --git a/kernel/base/container/los_container_bundle.c b/kernel/base/container/los_container_bundle.c index 47b2eb12..9b6cbfd6 100644 --- a/kernel/base/container/los_container_bundle.c +++ b/kernel/base/container/los_container_bundle.c @@ -42,6 +42,9 @@ #ifdef LOSCFG_IPC_CONTAINER #include "los_ipc_container.h" #endif +#ifdef LOSCFG_TIME_CONTAINER +#include "los_time_container.h" +#endif const INT32 BUNDLE_INIT_NUM = 3; @@ -63,6 +66,10 @@ ContainerBundle g_rootContainerBundle = { #ifdef LOSCFG_IPC_CONTAINER .ipcContainer = &g_rootIpcContainer, #endif +#ifdef LOSCFG_TIME_CONTAINER + .timeContainer = &g_rootTimeContainer, + .timeContainerForChildren = &g_rootTimeContainer, +#endif }; STATIC VOID FreeContainerBundle(ContainerBundle **pContainer, UINT32 flag); @@ -95,6 +102,12 @@ UINT32 OsInitContainerBundle(VOID) if (ret != LOS_OK) { return ret; } +#endif +#ifdef LOSCFG_TIME_CONTAINER + ret = OsInitTimeContainer(&g_rootTimeContainer); + if (ret != LOS_OK) { + return ret; + } #endif return ret; } @@ -132,6 +145,10 @@ STATIC INLINE ContainerBundle *CreateContainerBundle(VOID) #endif #ifdef LOSCFG_IPC_CONTAINER containerBundle->ipcContainer = NULL; +#endif +#ifdef LOSCFG_TIME_CONTAINER + containerBundle->timeContainer = NULL; + containerBundle->timeContainerForChildren = NULL; #endif atomic_set(&containerBundle->count, 1); return containerBundle; @@ -184,6 +201,15 @@ STATIC UINT32 CreateNewContainers(unsigned long flags, LosProcessCB *runProcessC PRINT_ERR("OsHandleIpcContainer err.\n"); goto ERROR; } +#endif +#ifdef LOSCFG_TIME_CONTAINER + ret = OsHandleTimeContainer(flags, runProcessCB->containerBundle->timeContainerForChildren, &((*newContainer)->timeContainer)); + if (ret != LOS_OK) { + PRINT_ERR("OsHandleTimeContainer err.\n"); + goto ERROR; + } + (*newContainer)->timeContainerForChildren = (*newContainer)->timeContainer; + (VOID)GetTimeContainer((*newContainer)->timeContainerForChildren); #endif return ret; @@ -225,6 +251,12 @@ ContainerBundle *OsCopyContainerBundleOnly(LosProcessCB *processCB) #ifdef LOSCFG_IPC_CONTAINER OsGetIpcContainer(processCB->containerBundle->ipcContainer); newContainerBundle->ipcContainer = processCB->containerBundle->ipcContainer; +#endif +#ifdef LOSCFG_TIME_CONTAINER + (VOID)GetTimeContainer(processCB->containerBundle->timeContainer); + newContainerBundle->timeContainer = processCB->containerBundle->timeContainer; + (VOID)GetTimeContainer(processCB->containerBundle->timeContainerForChildren); + newContainerBundle->timeContainerForChildren = processCB->containerBundle->timeContainerForChildren; #endif return newContainerBundle; } @@ -252,14 +284,19 @@ STATIC INLINE VOID DerefContainerBundle(ContainerBundle **pContainer, UINT32 fla */ UINT32 OsCopyContainers(unsigned long flags, LosProcessCB *childProcessCB, LosProcessCB *runProcessCB) { - INT32 ret = LOS_OK; + UINT32 ret = LOS_OK; BOOL shouldCreateNewBundle = FALSE; - if (!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC | CLONE_NEWPID | CLONE_NEWNET))) { + if (!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC | CLONE_NEWPID | CLONE_NEWNET | CLONE_NEWTIME))) { #ifdef LOSCFG_PID_CONTAINER if (runProcessCB->containerBundle->pidContainerForChildren != runProcessCB->containerBundle->pidContainer) { shouldCreateNewBundle = TRUE; } +#endif +#ifdef LOSCFG_TIME_CONTAINER + if (runProcessCB->containerBundle->timeContainerForChildren != runProcessCB->containerBundle->timeContainer) { + shouldCreateNewBundle = TRUE; + } #endif } else { shouldCreateNewBundle = TRUE; @@ -319,6 +356,15 @@ STATIC VOID FreeContainerBundle(ContainerBundle **pContainer, UINT32 flag) if ((*pContainer)->ipcContainer != NULL) { OsDerefIpcContainer(&(*pContainer)->ipcContainer); } +#endif +#ifdef LOSCFG_TIME_CONTAINER + if ((*pContainer)->timeContainer) { + DerefTimeContainer(&(*pContainer)->timeContainer); + } + + if ((*pContainer)->timeContainerForChildren != NULL) { + DerefTimeContainer(&(*pContainer)->timeContainerForChildren); + } #endif (VOID)LOS_MemFree(m_aucSysMem1, *pContainer); *pContainer = NULL; @@ -337,7 +383,7 @@ VOID OsExitProcessContainer(LosProcessCB *task, UINT32 flag) UINT32 OsUnshareContainers(unsigned long flags, ContainerBundle **bundle) { - if (!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWNET | CLONE_NEWPID | CLONE_NEWIPC))) { + if (!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWNET | CLONE_NEWPID | CLONE_NEWIPC | CLONE_NEWTIME))) { return LOS_OK; } @@ -354,6 +400,14 @@ UINT32 OsUnshareContainers(unsigned long flags, ContainerBundle **bundle) OsGetPidContainer((*bundle)->pidContainer); } #endif +#ifdef LOSCFG_TIME_CONTAINER + if (flags & CLONE_NEWTIME) { + DerefTimeContainer((&(*bundle)->timeContainer)); + (*bundle)->timeContainer = currProcess->containerBundle->timeContainer; + (VOID)GetTimeContainer((*bundle)->timeContainer); + } +#endif + return LOS_OK; } diff --git a/kernel/base/container/los_string_util.c b/kernel/base/container/los_string_util.c new file mode 100644 index 00000000..635fc0f1 --- /dev/null +++ b/kernel/base/container/los_string_util.c @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "los_string_util.h" + +CHAR *OsSkipSpaces(const CHAR *str) +{ + while (isspace(*str)) { + ++str; + } + + return (CHAR *)str; +} + +long long OsSimpleStrtoll(const CHAR *str, CHAR **endp, UINT32 base) +{ + long long result = 0; + long long value; + int plusOrMinusFlag = 1; + + if (!base) { + base = 10; + } + + while( str && !isdigit(*str)) { + if(*str == '-' || *str == '+') { + break; + } + str++; + } + + if (*str == '-' || *str == '+') { + if (*str == '-') { + plusOrMinusFlag = -1; + str++; + } else { + plusOrMinusFlag = 1; + str++; + } + } + + while (isdigit(*str)) { + value = *str - '0'; + result = result * base + value; + str++; + } + if (endp) { + *endp = (CHAR *)str; + } + result *= plusOrMinusFlag; + + return result; +} + +VOID *OsMemdupUserNul(const CHAR *src, size_t len) +{ + CHAR *des = NULL; + if (!src || len <= 0) { + return NULL; + } + + des = LOS_MemAlloc(OS_SYS_MEM_ADDR, len + 1); + if (des == NULL) { + return NULL; + } + if (!LOS_IsUserAddressRange((VADDR_T)(UINTPTR)src, len)) { + memcpy_s(des, len, src, len); + return des; + } + + if (LOS_ArchCopyFromUser(des, src, len) != 0) { + (VOID)LOS_MemFree(OS_SYS_MEM_ADDR, des); + return NULL; + } + + des[len] = '\0'; + return des; +} + diff --git a/kernel/base/container/los_time_container.c b/kernel/base/container/los_time_container.c new file mode 100644 index 00000000..cc52282f --- /dev/null +++ b/kernel/base/container/los_time_container.c @@ -0,0 +1,290 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "los_time_container.h" +#include "los_string_util.h" +#include "proc_fs.h" +#include "los_seq_buf.h" + + +#ifdef LOSCFG_TIME_CONTAINER +extern struct ContainerConfig g_containerConfig; +UINT32 g_currentTimeContainerNum = 1; + +TimeContainer g_rootTimeContainer; + +const UINT32 INIT_TIMECONTAINER_NUM = 2; +const UINT32 DECIMAL_BASE = 10; + +static UINT32 CreateTimeContainer(TimeContainer **newTimeContainer) +{ + UINT32 size = sizeof(TimeContainer); + TimeContainer *timeContainer = LOS_MemAlloc(m_aucSysMem1, size); + if (timeContainer == NULL) { + PRINT_ERR("CreateTimeContainer failed to malloc memory.\n"); + return ENOMEM; + } + + UINT32 intSave; + SCHEDULER_LOCK(intSave); + if (g_currentTimeContainerNum > g_containerConfig.MaxTimeContainer) { + PRINT_ERR("CreateTimeContainer failed, reach to max container config.\n"); + (VOID)LOS_MemFree(m_aucSysMem1, timeContainer); + SCHEDULER_UNLOCK(intSave); + return ENOSPC; + } + g_currentTimeContainerNum += 1; + SCHEDULER_UNLOCK(intSave); + + atomic_set(&timeContainer->count, 1); + *newTimeContainer = timeContainer; + return LOS_OK; +} + +static UINT32 CreateNewTimeContainer(TimeContainer *runTimeContainer, TimeContainer **newTimeContainer) +{ + UINT32 ret; + + ret = CreateTimeContainer(newTimeContainer); + if (ret != LOS_OK) { + PRINT_ERR("newTimeContainer is NULL.\n"); + return ret; + } + + atomic_set(&(*newTimeContainer)->count, 1); + (*newTimeContainer)->frozenOffsets = FALSE; + (*newTimeContainer)->offsets.monotonic.tv_nsec = runTimeContainer->offsets.monotonic.tv_nsec; + (*newTimeContainer)->offsets.monotonic.tv_sec = runTimeContainer->offsets.monotonic.tv_sec; + + OsContainerAllocVnum(&((*newTimeContainer)->containerBase.vnum)); + + return ret; +} + + +UINT32 OsHandleTimeContainer(unsigned long flags, TimeContainer *runTimeContainer, TimeContainer **newTimeContainer) +{ + UINT32 ret; + + if (!(flags & CLONE_NEWTIME)) { + if (!runTimeContainer->frozenOffsets) { + runTimeContainer->frozenOffsets = TRUE; + } + (VOID)GetTimeContainer(runTimeContainer); + *newTimeContainer = runTimeContainer; + return LOS_OK; + } + + ret = CreateNewTimeContainer(runTimeContainer, newTimeContainer); + if (ret != LOS_OK) { + PRINT_ERR("newTimeContainer is NULL.\n"); + return ret; + } + + return ret; +} + +void OsFreeTimeContainer(TimeContainer **timeContainer) +{ + LOS_MemFree(m_aucSysMem1, *timeContainer); + *timeContainer = NULL; + + UINT32 intSave; + SCHEDULER_LOCK(intSave); + g_currentTimeContainerNum -= 1; + SCHEDULER_UNLOCK(intSave); +} + +UINT32 OsReplaceTimeContainerInBundle(ContainerBundle* bundle, struct TimeContainer *targetTimeContainer) +{ + if (!targetTimeContainer->frozenOffsets) { + targetTimeContainer->frozenOffsets = TRUE; + } + DerefTimeContainer(&bundle->timeContainer); + bundle->timeContainer = targetTimeContainer; + (VOID)GetTimeContainer(bundle->timeContainer); + + DerefTimeContainer(&bundle->timeContainerForChildren); + bundle->timeContainerForChildren = targetTimeContainer; + (VOID)GetTimeContainer(bundle->timeContainerForChildren); + + return LOS_OK; +} + +UINT32 OsInitTimeContainer(TimeContainer *timeContainer) +{ + atomic_set(&timeContainer->count, INIT_TIMECONTAINER_NUM); + timeContainer->frozenOffsets = TRUE; + timeContainer->offsets.monotonic.tv_nsec = 0; + timeContainer->offsets.monotonic.tv_sec = 0; + OsContainerAllocVnum(&(timeContainer->containerBase.vnum)); + return LOS_OK; +} + +static INT32 ProcTimeOffsetsOpen(struct Vnode *vnode, struct ProcFile *pf) +{ + TimeContainer *timeContainer = NULL; + LosProcessCB *process = NULL; + UINT32 intSave; + INT32 ret = -EINVAL; + UINT32 pid; + + SCHEDULER_LOCK(intSave); + struct ProcDirEntry *pn = (struct ProcDirEntry *)vnode; + pid = OsSimpleStrtoll(pn->parent->name, NULL, DECIMAL_BASE); + + if (OsProcessIDUserCheckInvalid(pid)) { + SCHEDULER_UNLOCK(intSave); + return ret; + } + + process = OS_PCB_FROM_PID(pid); + if (process != NULL) { + timeContainer = GetTimeContainer(process->containerBundle->timeContainerForChildren); + if (timeContainer == NULL) { + SCHEDULER_UNLOCK(intSave); + return ret; + } + } + SCHEDULER_UNLOCK(intSave); + + pf->sbuf->private = timeContainer; + return 0; +} + +static INT32 ProcTimeOffsetsRelease(struct Vnode *vnode, struct ProcFile *pf) +{ + struct SeqBuf *seq = pf->sbuf; + TimeContainer *timeContainer = seq->private; + DerefTimeContainer(&timeContainer); + return 0; +} + +static INT32 ProcTimeOffsetsRead(struct SeqBuf *seqBuf, VOID *v) +{ + INT32 ret = 0; + TimeContainer *timeContainer = seqBuf->private; + + if (timeContainer != NULL) { + ret = LosBufPrintf(seqBuf, "monotonic %lld %ld\n", timeContainer->offsets.monotonic.tv_sec, timeContainer->offsets.monotonic.tv_nsec); + } + + return ret; +} + +static INT32 ProcSetTimensOffset(CHAR *buf, TimeContainer *timeContainer) +{ + INT32 ret = strlen(buf); + struct timespec64 offsets; + UINT32 intSave; + + if (buf) { + *buf = '\0'; + buf++; + if (*buf == '\0') { + buf = NULL; + } + } + + buf = OsSkipSpaces(buf); + offsets.tv_sec = OsSimpleStrtoll(buf, &buf, DECIMAL_BASE); + + buf = OsSkipSpaces(buf); + offsets.tv_nsec = OsSimpleStrtoll(buf, &buf, DECIMAL_BASE); + + SCHEDULER_LOCK(intSave); + if (timeContainer->frozenOffsets) { + ret = -EACCES; + PRINT_ERR("ProcSetTimensOffset frozenOffsets err\n"); + SCHEDULER_UNLOCK(intSave); + return ret; + } + if(offsets.tv_nsec >= OS_SYS_NS_PER_SECOND) { + ret = -EACCES; + PRINT_ERR("ProcSetTimensOffset tv_nsec Greater than 1000000000 err\n"); + SCHEDULER_UNLOCK(intSave); + return ret; + } + + timeContainer->offsets.monotonic.tv_sec = offsets.tv_sec; + timeContainer->offsets.monotonic.tv_nsec = offsets.tv_nsec; + + SCHEDULER_UNLOCK(intSave); + + return ret; + +} + +ssize_t ProcTimeOffsetsWrite(struct ProcFile *file, const CHAR *buf, size_t size, loff_t *ppos) +{ + const CHAR *MONOTINOC = "monotonic"; + struct SeqBuf *seq = file->sbuf; + TimeContainer *timeContainer = seq->private; + INT32 ret = -EINVAL; + CHAR *kbuf = NULL; + + kbuf = OsMemdupUserNul(buf, size); + if (kbuf == NULL) { + return -EINVAL; + } + + ret = strncmp(kbuf, MONOTINOC, strlen(MONOTINOC)); + if (ret != LOS_OK) { + ret = -EINVAL; + return ret; + } + + ret = ProcSetTimensOffset(kbuf, timeContainer); + if (ret != LOS_OK) { + return ret; + } + + return ret; +} + + +struct ProcFileOperations g_procTimeOffsetsOperations = { + .open = ProcTimeOffsetsOpen, + .write = ProcTimeOffsetsWrite, + .read = ProcTimeOffsetsRead, + .release = ProcTimeOffsetsRelease, +}; + +struct timespec64 OsGetOffsetsFromContainer(VOID) +{ + LosProcessCB *runProcessCB = OsCurrProcessGet(); + struct timespec64 timeOffsets; + + timeOffsets.tv_sec = runProcessCB->containerBundle->timeContainer->offsets.monotonic.tv_sec; + timeOffsets.tv_nsec = runProcessCB->containerBundle->timeContainer->offsets.monotonic.tv_nsec; + + return timeOffsets; +} +#endif + diff --git a/kernel/base/core/los_process.c b/kernel/base/core/los_process.c index a0a9f9bc..470dbf41 100644 --- a/kernel/base/core/los_process.c +++ b/kernel/base/core/los_process.c @@ -1,5 +1,4 @@ /* - * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -81,6 +80,9 @@ #ifdef LOSCFG_IPC_CONTAINER #include "los_ipc_container.h" #endif +#ifdef LOSCFG_TIME_CONTAINER +#include "los_time_container.h" +#endif LITE_OS_SEC_BSS LosProcessCB *g_processCBArray = NULL; LITE_OS_SEC_DATA_INIT STATIC LOS_DL_LIST g_freeProcess; @@ -2234,7 +2236,7 @@ LITE_OS_SEC_TEXT INT32 OsSetns(INT32 fd, INT32 type) LosProcessCB *currProcess = OsCurrProcessGet(); INT32 targetType = 0; INT32 typeMask = CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWUSER | - CLONE_NEWPID | CLONE_NEWNET | CLONE_NEWIPC; + CLONE_NEWPID | CLONE_NEWNET | CLONE_NEWIPC | CLONE_NEWTIME; if (type & (~typeMask)) { PRINT_WARN("setns dont support some type!\n"); @@ -2285,10 +2287,14 @@ LITE_OS_SEC_TEXT INT32 OsSetns(INT32 fd, INT32 type) } else if (targetType == CLONE_NEWIPC) { #ifdef LOSCFG_IPC_CONTAINER OsReplaceIpcContainerInBundle(newBundle, (struct IpcContainer *)targetContainer); +#endif + } else if (targetType == CLONE_NEWTIME) { +#ifdef LOSCFG_TIME_CONTAINER + OsReplaceTimeContainerInBundle(newBundle, (struct TimeContainer *)targetContainer); #endif } else { PRINT_ERR("setns:Error, unexpected type [%#x]\n", targetType); - return LOS_EINVAL; + return -LOS_EINVAL; } #ifdef LOSCFG_IPC_CONTAINER OsDealBeforeAssign(targetType); diff --git a/kernel/base/include/los_container_bundle.h b/kernel/base/include/los_container_bundle.h index 7658a6ee..1eefb550 100644 --- a/kernel/base/include/los_container_bundle.h +++ b/kernel/base/include/los_container_bundle.h @@ -77,6 +77,10 @@ typedef struct ContainerBundle { #ifdef LOSCFG_IPC_CONTAINER struct IpcContainer *ipcContainer; #endif +#ifdef LOSCFG_TIME_CONTAINER + struct TimeContainer *timeContainer; + struct TimeContainer *timeContainerForChildren; +#endif } ContainerBundle; extern ContainerBundle g_rootContainerBundle; diff --git a/kernel/base/include/los_process_pri.h b/kernel/base/include/los_process_pri.h index 37b86d9e..05564ed0 100644 --- a/kernel/base/include/los_process_pri.h +++ b/kernel/base/include/los_process_pri.h @@ -1,5 +1,4 @@ /* - * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -200,6 +199,8 @@ typedef struct ProcessCB { #define CLONE_NEWUSER 0x10000000 /* new user container for child process */ #define CLONE_NEWPID 0x20000000 /* new PID container for child process */ #define CLONE_NEWNET 0x40000000 /* new network container for child process */ +#define CLONE_NEWTIME 0x00000080 /* new time container for child process */ + #define OS_PCB_FROM_PID(processID) (((LosProcessCB *)g_processCBArray) + (processID)) #define OS_PCB_FROM_SIBLIST(ptr) LOS_DL_LIST_ENTRY((ptr), LosProcessCB, siblingList) diff --git a/kernel/base/include/los_string_util.h b/kernel/base/include/los_string_util.h new file mode 100644 index 00000000..d41804ec --- /dev/null +++ b/kernel/base/include/los_string_util.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _STRING_UTIL_H +#define _STRING_UTIL_H + +#include "los_config.h" +#include "ctype.h" +#include "user_copy.h" +#include "los_memory.h" +#include "proc_fs.h" + +CHAR *OsSkipSpaces(const CHAR *str); +long long OsSimpleStrtoll(const CHAR *str, CHAR **endp, UINT32 base); +VOID *OsMemdupUserNul(const CHAR *src, size_t len); + +#endif diff --git a/kernel/base/include/los_time_container.h b/kernel/base/include/los_time_container.h new file mode 100644 index 00000000..617413ec --- /dev/null +++ b/kernel/base/include/los_time_container.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _TIME_CONTAINER_H +#define _TIME_CONTAINER_H +#ifdef LOSCFG_TIME_CONTAINER + +#include "los_container_bundle.h" +#include "los_container_base.h" +#include "time.h" + +typedef struct TimeContainerOffsets { + struct timespec64 monotonic; +}TimeContainerOffsets; + +typedef struct TimeContainer { + atomic_t count; + bool frozenOffsets; + struct TimeContainerOffsets offsets; + struct ContainerBase containerBase; +} TimeContainer; + +extern TimeContainer g_rootTimeContainer; + +extern UINT32 g_currentTimeContainerNum; + +extern struct ProcFileOperations g_procTimeOffsetsOperations; + +UINT32 OsInitTimeContainer(TimeContainer *timeContainer); + +UINT32 OsReplaceTimeContainerInBundle(ContainerBundle* bundle, struct TimeContainer *newTimeContainer); + +UINT32 OsHandleTimeContainer(unsigned long flags, TimeContainer *runTimeContainer, TimeContainer **newTimeContainer); + +VOID OsFreeTimeContainer(TimeContainer **timeContainer); + +struct timespec64 OsGetOffsetsFromContainer(VOID); + +STATIC INLINE TimeContainer *GetTimeContainer(TimeContainer *pTimeContainer) +{ + if (pTimeContainer) { + atomic_inc(&pTimeContainer->count); + } + return pTimeContainer; +} + +STATIC INLINE VOID DerefTimeContainer(TimeContainer **pTimeContainer) +{ + if ((*pTimeContainer != NULL) && (atomic_dec_and_test(&(*pTimeContainer)->count))) { + OsFreeTimeContainer(pTimeContainer); + } +} + +#endif +#endif /* _TIME_CONTAINER_H */ \ No newline at end of file diff --git a/testsuites/unittest/BUILD.gn b/testsuites/unittest/BUILD.gn index f6049a8a..5df97799 100644 --- a/testsuites/unittest/BUILD.gn +++ b/testsuites/unittest/BUILD.gn @@ -91,6 +91,11 @@ if (LOSCFG_USER_TEST_IPC_CONTAINER == "enable" || local_flags += [ "-DLOSCFG_USER_TEST_IPC_CONTAINER" ] } +if (LOSCFG_USER_TEST_TIME_CONTAINER == "enable" || + (LOSCFG_USER_TEST_TIME_CONTAINER == "default" && board_name == "hispark_taurus")) { + local_flags += [ "-DLOSCFG_USER_TEST_TIME_CONTAINER" ] +} + config("public_config_for_door") { cflags = [ "-DLOSCFG_USER_TEST_SMOKE" ] cflags += local_flags diff --git a/testsuites/unittest/config.gni b/testsuites/unittest/config.gni index dd6c0d87..72decc4b 100644 --- a/testsuites/unittest/config.gni +++ b/testsuites/unittest/config.gni @@ -49,6 +49,7 @@ LOSCFG_USER_TEST_PID_CONTAINER = "disable" LOSCFG_USER_TEST_USER_CONTAINER = "disable" LOSCFG_USER_TEST_NET_CONTAINER = "disable" LOSCFG_USER_TEST_IPC_CONTAINER = "disable" +LOSCFG_USER_TEST_TIME_CONTAINER = "disable" LOSCFG_USER_TEST_STABILITY = "disable" LOSCFG_USER_TEST_CHROOT = "disable" LOSCFG_USER_TEST_MNT_CONTAINER = "disable" diff --git a/testsuites/unittest/libc/posix/container/It_posix_container.h b/testsuites/unittest/libc/posix/container/It_posix_container.h index 3873a7c9..91b2b102 100644 --- a/testsuites/unittest/libc/posix/container/It_posix_container.h +++ b/testsuites/unittest/libc/posix/container/It_posix_container.h @@ -213,6 +213,17 @@ void ItPosixContainerIpc004(void); void ItPosixContainerIpc005(void); void ItPosixContainerIpc006(void); #endif +#if defined(LOSCFG_USER_TEST_TIME_CONTAINER) +void ItPosixContainerTime001(void); +void ItPosixContainerTime002(void); +void ItPosixContainerTime003(void); +void ItPosixContainerTime004(void); +void ItPosixContainerTime005(void); +void ItPosixContainerTime006(void); +void ItPosixContainerTime007(void); +void ItPosixContainerTime008(void); +void ItPosixContainerTime009(void); +#endif #endif #if defined(LOSCFG_USER_TEST_STABILITY) diff --git a/testsuites/unittest/libc/posix/container/config.gni b/testsuites/unittest/libc/posix/container/config.gni index 516b6a0f..c2defa3c 100644 --- a/testsuites/unittest/libc/posix/container/config.gni +++ b/testsuites/unittest/libc/posix/container/config.gni @@ -99,6 +99,15 @@ posix_container_sources_full = [ "$TEST_UNITTEST_DIR/libc/posix/container/full/It_posix_container_ipc_004.cpp", "$TEST_UNITTEST_DIR/libc/posix/container/full/It_posix_container_ipc_005.cpp", "$TEST_UNITTEST_DIR/libc/posix/container/full/It_posix_container_ipc_006.cpp", + "$TEST_UNITTEST_DIR/libc/posix/container/full/It_posix_container_time_001.cpp", + "$TEST_UNITTEST_DIR/libc/posix/container/full/It_posix_container_time_002.cpp", + "$TEST_UNITTEST_DIR/libc/posix/container/full/It_posix_container_time_003.cpp", + "$TEST_UNITTEST_DIR/libc/posix/container/full/It_posix_container_time_004.cpp", + "$TEST_UNITTEST_DIR/libc/posix/container/full/It_posix_container_time_005.cpp", + "$TEST_UNITTEST_DIR/libc/posix/container/full/It_posix_container_time_006.cpp", + "$TEST_UNITTEST_DIR/libc/posix/container/full/It_posix_container_time_007.cpp", + "$TEST_UNITTEST_DIR/libc/posix/container/full/It_posix_container_time_008.cpp", + "$TEST_UNITTEST_DIR/libc/posix/container/full/It_posix_container_time_009.cpp", ] posix_container_sources_stability = [ diff --git a/testsuites/unittest/libc/posix/container/full/It_posix_container_time_001.cpp b/testsuites/unittest/libc/posix/container/full/It_posix_container_time_001.cpp new file mode 100644 index 00000000..2529ae6e --- /dev/null +++ b/testsuites/unittest/libc/posix/container/full/It_posix_container_time_001.cpp @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_container.h" + +static int childFunc(void *arg) +{ + int value = *((int*)arg); + if (value != CHILD_FUNC_ARG) { + return EXIT_CODE_ERRNO_1; + } + return 0; +} + +void ItPosixContainerTime001(void) +{ + int ret; + char *stack; + char *stackTop; + int status; + char *containerType = "time"; + char *containerType1 = "time_for_children"; + + stack = (char*)mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0); + stackTop = stack + STACK_SIZE; + std::cout << getpid() << std::endl; + auto linkBuffer = ReadlinkContainer(getpid(), containerType); + auto linkBuffer1 = ReadlinkContainer(getpid(), containerType1); + ret = linkBuffer.compare(linkBuffer1); + ASSERT_EQ(ret, 0); + + int arg = CHILD_FUNC_ARG; + auto pid = clone(childFunc, stackTop, CLONE_NEWTIME | SIGCHLD, &arg); + ASSERT_TRUE(pid != -1); + + auto linkBuffer2 = ReadlinkContainer(pid, containerType); + ret = linkBuffer.compare(linkBuffer2); + ASSERT_EQ(ret, 0); + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + + int exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, 0); +} diff --git a/testsuites/unittest/libc/posix/container/full/It_posix_container_time_002.cpp b/testsuites/unittest/libc/posix/container/full/It_posix_container_time_002.cpp new file mode 100644 index 00000000..d4b019d5 --- /dev/null +++ b/testsuites/unittest/libc/posix/container/full/It_posix_container_time_002.cpp @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_container.h" + +#define STR_LEN 50 +#define SEC 600 +#define NSEC 800000000 + +static int childFunc(void *arg) +{ + char path[STR_LEN]; + char timeOff[STR_LEN]; + char readBuf[STR_LEN]; + int ret; + + sprintf(timeOff,"monotonic %d %d", SEC, NSEC); + sprintf(path,"/proc/%d/time_offsets", getpid()); + int fd = open(path, O_RDWR); + if (fd == -1) { + return EXIT_CODE_ERRNO_1; + } + + ret = read(fd, readBuf, STR_LEN); + if (ret == -1) { + close(fd); + return EXIT_CODE_ERRNO_2; + } + close(fd); + ret = strncmp(timeOff, readBuf, strlen(timeOff)); + if (ret != 0) { + return EXIT_CODE_ERRNO_3; + } + + return 0; +} +static int WriteProcTime(int pid) +{ + int ret = 0; + char path[STR_LEN]; + char timeOff[STR_LEN]; + + sprintf(timeOff,"monotonic %d %d", SEC, NSEC); + sprintf(path,"/proc/%d/time_offsets", pid); + int strLen = strlen(timeOff); + int fd = open(path, O_WRONLY); + if (ret == -1) { + return EXIT_CODE_ERRNO_4; + } + + ret = write(fd, timeOff, strLen); + if (ret != strLen) { + close(fd); + return EXIT_CODE_ERRNO_5; + } + + close(fd); + return 0; + +} + +void ItPosixContainerTime002(void) +{ + int ret; + char *stack; + char *stackTop; + int status; + char *containerType = "time"; + char *containerType1 = "time_for_children"; + + stack = (char*)mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0); + stackTop = stack + STACK_SIZE; + + ret = unshare(CLONE_NEWTIME); + ASSERT_EQ(ret, 0); + + ret = WriteProcTime(getpid()); + ASSERT_EQ(ret, 0); + + auto linkBuffer = ReadlinkContainer(getpid(), containerType); + auto linkBuffer1 = ReadlinkContainer(getpid(), containerType1); + ret = linkBuffer.compare(linkBuffer1); + ASSERT_TRUE(ret != 0); + + int arg = CHILD_FUNC_ARG; + auto pid = clone(childFunc, stackTop, CLONE_NEWTIME | SIGCHLD, &arg); + ASSERT_TRUE(pid != -1); + + auto linkBuffer2 = ReadlinkContainer(pid, containerType); + ret = linkBuffer1.compare(linkBuffer2); + ASSERT_EQ(ret, 0); + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + ret = WIFEXITED(status); + ASSERT_TRUE(ret != 0); + + int exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, 0); +} \ No newline at end of file diff --git a/testsuites/unittest/libc/posix/container/full/It_posix_container_time_003.cpp b/testsuites/unittest/libc/posix/container/full/It_posix_container_time_003.cpp new file mode 100644 index 00000000..7aec6790 --- /dev/null +++ b/testsuites/unittest/libc/posix/container/full/It_posix_container_time_003.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_container.h" + +static int childFunc(void *arg) +{ + int ret; + char *containerType = "time"; + char *containerType1 = "time_for_children"; + char pid_link[100]; + char targetpath[100]; + auto linkBuffer = ReadlinkContainer(getppid(), containerType); + int fd; + + sprintf(pid_link, "%s", linkBuffer.c_str()); + sprintf(targetpath, "/proc/%d/container/time", getppid()); + fd = open(targetpath, O_RDONLY | O_CLOEXEC); + if (fd == -1) { + return EXIT_CODE_ERRNO_1; + } + + ret = setns(fd, CLONE_NEWTIME); + if (ret != 0) { + close(fd); + return EXIT_CODE_ERRNO_2; + } + close(fd); + auto linkBuffer1 = ReadlinkContainer(getpid(), containerType); + auto linkBuffer2 = ReadlinkContainer(getpid(), containerType1); + ret = linkBuffer1.compare(linkBuffer2); + EXPECT_EQ(ret, 0); + if (ret != 0) { + return EXIT_CODE_ERRNO_3; + } + + return 0; +} + +void ItPosixContainerTime003(void) +{ + int ret; + char *stack; + char *stackTop; + int status; + char *containerType = "time"; + char *containerType1 = "time_for_children"; + + stack = (char*)mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0); + stackTop = stack + STACK_SIZE; + + ret = unshare(CLONE_NEWTIME); + ASSERT_EQ(ret, 0); + + auto linkBuffer = ReadlinkContainer(getpid(), containerType1); + + int arg = CHILD_FUNC_ARG; + auto pid = clone(childFunc, stackTop, CLONE_NEWTIME | SIGCHLD, &arg); + ASSERT_TRUE(pid != -1); + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + ret = WIFEXITED(status); + ASSERT_TRUE(ret != 0); + + int exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, 0); +} \ No newline at end of file diff --git a/testsuites/unittest/libc/posix/container/full/It_posix_container_time_004.cpp b/testsuites/unittest/libc/posix/container/full/It_posix_container_time_004.cpp new file mode 100644 index 00000000..25c4acd0 --- /dev/null +++ b/testsuites/unittest/libc/posix/container/full/It_posix_container_time_004.cpp @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_container.h" + +#define STR_LEN 50 +#define SEC 172800 +#define NSEC 800000000 + +static int childFunc(void *arg) +{ + int ret; + struct timespec tp = *((struct timespec *)arg); + struct timespec tp1; + + ret = clock_gettime(CLOCK_MONOTONIC_RAW, &tp1); + if (ret != 0) { + return EXIT_CODE_ERRNO_1; + } + + ret = ((tp1.tv_sec >= tp.tv_sec + SEC)); + if (ret != 1) { + return EXIT_CODE_ERRNO_2; + } + + return 0; +} +static int WriteProcTime(int pid) +{ + int ret; + char path[STR_LEN]; + char timeOff[STR_LEN]; + + sprintf(timeOff,"monotonic %d %d", SEC, NSEC); + sprintf(path,"/proc/%d/time_offsets", pid); + int strLen = strlen(timeOff); + int fd = open(path, O_WRONLY); + if (fd == -1) { + return EXIT_CODE_ERRNO_3; + } + + ret = write(fd, timeOff, strLen); + if (ret != strLen) { + close(fd); + return EXIT_CODE_ERRNO_4; + } + + close(fd); + return 0; + +} + +void ItPosixContainerTime004(void) +{ + int ret; + char *stack; + char *stackTop; + int status; + struct timespec tp; + + stack = (char*)mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0); + stackTop = stack + STACK_SIZE; + + ret = unshare(CLONE_NEWTIME); + ASSERT_EQ(ret, 0); + + ret = WriteProcTime(getpid()); + ASSERT_EQ(ret, 0); + + ret = clock_gettime(CLOCK_MONOTONIC_RAW, &tp); + ASSERT_EQ(ret, 0); + + auto pid = clone(childFunc, stackTop, CLONE_NEWTIME | SIGCHLD, &tp); + ASSERT_TRUE(pid != -1); + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + + int exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, 0); +} \ No newline at end of file diff --git a/testsuites/unittest/libc/posix/container/full/It_posix_container_time_005.cpp b/testsuites/unittest/libc/posix/container/full/It_posix_container_time_005.cpp new file mode 100644 index 00000000..8e958aca --- /dev/null +++ b/testsuites/unittest/libc/posix/container/full/It_posix_container_time_005.cpp @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_container.h" +#include + +#define STR_LEN 50 +#define SEC 172800 +#define NSEC 800000000 + +static int childFunc(void *arg) +{ + int ret; + struct timespec tp = *((struct timespec *)arg); + struct timespec tp1; + memset(&tp1,0x00,sizeof(tp1)); + + ret = clock_gettime(CLOCK_MONOTONIC, &tp1); + if (ret != 0) { + return EXIT_CODE_ERRNO_1; + } + + ret = ((tp1.tv_sec >= tp.tv_sec + SEC)); + if (ret != 1) { + return EXIT_CODE_ERRNO_2; + } + + return 0; +} +static int WriteProcTime(int pid) +{ + int ret; + char path[STR_LEN]; + char timeOff[STR_LEN]; + + sprintf(timeOff,"monotonic %d %d", SEC, NSEC); + sprintf(path,"/proc/%d/time_offsets", pid); + int strLen = strlen(timeOff); + int fd = open(path, O_WRONLY); + if (fd == -1) { + return EXIT_CODE_ERRNO_3; + } + + ret = write(fd, timeOff, strLen); + if (ret != strLen) { + close(fd); + return EXIT_CODE_ERRNO_4; + } + + close(fd); + return 0; + +} + +void ItPosixContainerTime005(void) +{ + int ret; + char *stack; + char *stackTop; + int status; + struct timespec tp; + memset(&tp,0x00,sizeof(tp)); + + stack = (char*)mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0); + stackTop = stack + STACK_SIZE; + + ret = unshare(CLONE_NEWTIME); + ASSERT_EQ(ret, 0); + + ret = WriteProcTime(getpid()); + ASSERT_EQ(ret, 0); + + ret = clock_gettime(CLOCK_MONOTONIC, &tp); + ASSERT_EQ(ret, 0); + + auto pid = clone(childFunc, stackTop, CLONE_NEWTIME | SIGCHLD, &tp); + ASSERT_TRUE(pid != -1); + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + ret = WIFEXITED(status); + ASSERT_TRUE(ret != 0); + + int exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, 0); +} \ No newline at end of file diff --git a/testsuites/unittest/libc/posix/container/full/It_posix_container_time_006.cpp b/testsuites/unittest/libc/posix/container/full/It_posix_container_time_006.cpp new file mode 100644 index 00000000..d2a0f0c5 --- /dev/null +++ b/testsuites/unittest/libc/posix/container/full/It_posix_container_time_006.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_container.h" + +#define MAX_TIME_CONTAINER 64 +#define STR_LEN 100 + +void ItPosixContainerTime006(void) +{ + int ret; + char *fileName = "/proc/sys/user/max_time_container"; + FILE *fp; + char strBuf[STR_LEN]; + + fp = fopen(fileName, "rb"); + ASSERT_TRUE(fp != 0); + + memset(strBuf, 0x00, sizeof(strBuf)); + ret = fread(strBuf, 1, STR_LEN, fp); + ASSERT_TRUE(ret != -1); + + ret = atoi(strBuf); + ASSERT_EQ(ret, MAX_TIME_CONTAINER); + + fclose(fp); +} \ No newline at end of file diff --git a/testsuites/unittest/libc/posix/container/full/It_posix_container_time_007.cpp b/testsuites/unittest/libc/posix/container/full/It_posix_container_time_007.cpp new file mode 100644 index 00000000..89a32419 --- /dev/null +++ b/testsuites/unittest/libc/posix/container/full/It_posix_container_time_007.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_container.h" +#include + +#define STR_LEN 50 +#define SEC 172800 +#define NSEC 80000000 + +static int WriteProcTime(int pid) +{ + int ret; + char path[STR_LEN]; + char timeOff[STR_LEN]; + + sprintf(timeOff,"monotonic %d %d", SEC, NSEC); + sprintf(path,"/proc/%d/time_offsets", pid); + int strLen = strlen(timeOff); + int fd = open(path, O_WRONLY); + if (fd == -1) { + return EXIT_CODE_ERRNO_1; + } + + ret = write(fd, timeOff, strLen); + if (ret != -1) { + close(fd); + return EXIT_CODE_ERRNO_2; + } + + close(fd); + return 0; + +} + +void ItPosixContainerTime007(void) +{ + int ret; + + ret = WriteProcTime(getpid()); + ASSERT_EQ(ret, 0); +} \ No newline at end of file diff --git a/testsuites/unittest/libc/posix/container/full/It_posix_container_time_008.cpp b/testsuites/unittest/libc/posix/container/full/It_posix_container_time_008.cpp new file mode 100644 index 00000000..8405bb56 --- /dev/null +++ b/testsuites/unittest/libc/posix/container/full/It_posix_container_time_008.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_container.h" +#include + +#define STR_LEN 50 +#define SEC 172800 +#define NSEC 800000000000 + +static int WriteProcTime(int pid) +{ + int ret; + char path[STR_LEN]; + char timeOff[STR_LEN]; + + sprintf(timeOff,"monotonic %d %lld", SEC, NSEC); + sprintf(path,"/proc/%d/time_offsets", pid); + int strLen = strlen(timeOff); + int fd = open(path, O_WRONLY); + if (fd == -1) { + return EXIT_CODE_ERRNO_1; + } + + ret = write(fd, timeOff, strLen); + if (ret != -1) { + close(fd); + return EXIT_CODE_ERRNO_2; + } + + close(fd); + return 0; + +} + +void ItPosixContainerTime008(void) +{ + int ret; + + ret = unshare(CLONE_NEWTIME); + ASSERT_EQ(ret, 0); + + ret = WriteProcTime(getpid()); + ASSERT_EQ(ret, 0); +} \ No newline at end of file diff --git a/testsuites/unittest/libc/posix/container/full/It_posix_container_time_009.cpp b/testsuites/unittest/libc/posix/container/full/It_posix_container_time_009.cpp new file mode 100644 index 00000000..35ba4955 --- /dev/null +++ b/testsuites/unittest/libc/posix/container/full/It_posix_container_time_009.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "It_posix_container.h" +#include +#include +#include + +static std::string GenTimeLinkPath(int pid) { + std::ostringstream buf; + buf << "/proc/" << pid << "/container/time"; + return buf.str(); +} + +static std::string ReadlinkTime(int pid) { + auto path = GenTimeLinkPath(pid); + struct stat sb; + + int ret = lstat(path.data(), &sb); + if (ret == -1) { + perror("lstat"); + return std::string(); + } + + auto bufsiz = sb.st_size + 1; + if (sb.st_size == 0) + bufsiz = PATH_MAX; + + std::vector buf(bufsiz); + auto nbytes = readlink(path.c_str(), buf.data(), bufsiz); + if (nbytes == -1) { + perror("readlink"); + return std::string(); + } + + return buf.data(); +} + +void ItPosixContainerTime009(void) +{ + auto timelink = ReadlinkTime(getpid()); + std::cout << "Contents of the time link is: " << timelink << std::endl; + + std::regex reg("'time:\\[[0-9]+\\]'"); + bool ret = std::regex_match(timelink, reg); + ASSERT_TRUE(ret); +} diff --git a/testsuites/unittest/libc/posix/container/posix_container_test.cpp b/testsuites/unittest/libc/posix/container/posix_container_test.cpp index e77458e4..9028969f 100644 --- a/testsuites/unittest/libc/posix/container/posix_container_test.cpp +++ b/testsuites/unittest/libc/posix/container/posix_container_test.cpp @@ -424,6 +424,52 @@ HWTEST_F(PosixContainerTest, ItPosixContainerIpc006, TestSize.Level0) ItPosixContainerIpc006(); } #endif +#if defined(LOSCFG_USER_TEST_TIME_CONTAINER) +HWTEST_F(PosixContainerTest, ItPosixContainerTime001, TestSize.Level0) +{ + ItPosixContainerTime001(); +} + +HWTEST_F(PosixContainerTest, ItPosixContainerTime002, TestSize.Level0) +{ + ItPosixContainerTime002(); +} + +HWTEST_F(PosixContainerTest, ItPosixContainerTime003, TestSize.Level0) +{ + ItPosixContainerTime003(); +} + +HWTEST_F(PosixContainerTest, ItPosixContainerTime004, TestSize.Level0) +{ + ItPosixContainerTime004(); +} + +HWTEST_F(PosixContainerTest, ItPosixContainerTime005, TestSize.Level0) +{ + ItPosixContainerTime005(); +} + +HWTEST_F(PosixContainerTest, ItPosixContainerTime006, TestSize.Level0) +{ + ItPosixContainerTime006(); +} + +HWTEST_F(PosixContainerTest, ItPosixContainerTime007, TestSize.Level0) +{ + ItPosixContainerTime007(); +} + +HWTEST_F(PosixContainerTest, ItPosixContainerTime008, TestSize.Level0) +{ + ItPosixContainerTime008(); +} + +HWTEST_F(PosixContainerTest, ItPosixContainerTime009, TestSize.Level0) +{ + ItPosixContainerTime009(); +} +#endif #endif #if defined(LOSCFG_USER_TEST_STABILITY) -- Gitee