diff --git a/compat/posix/include/mqueue.h b/compat/posix/include/mqueue.h index c15554a2..e6ef8727 100644 --- a/compat/posix/include/mqueue.h +++ b/compat/posix/include/mqueue.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 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: @@ -74,6 +74,10 @@ extern "C" { /* not support prio */ #define MQ_PRIO_MAX 1 +#ifndef MAX_MQ_FD +#define MAX_MQ_FD CONFIG_NQUEUE_DESCRIPTORS +#endif + typedef union send_receive_t { unsigned oth : 3; unsigned grp : 6; diff --git a/compat/posix/src/mqueue.c b/compat/posix/src/mqueue.c index 8e67b035..eded1683 100644 --- a/compat/posix/src/mqueue.c +++ b/compat/posix/src/mqueue.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 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: @@ -44,16 +44,19 @@ #define FNONBLOCK O_NONBLOCK -#ifndef MAX_MQ_FD -#define MAX_MQ_FD CONFIG_NQUEUE_DESCRIPTORS -#endif - +#ifndef LOSCFG_IPC_CONTAINER /* GLOBALS */ STATIC fd_set g_queueFdSet; STATIC struct mqarray g_queueTable[LOSCFG_BASE_IPC_QUEUE_LIMIT]; STATIC pthread_mutex_t g_mqueueMutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; STATIC struct mqpersonal *g_mqPrivBuf[MAX_MQ_FD]; +#define IPC_QUEUE_FD_SET g_queueFdSet +#define IPC_QUEUE_TABLE g_queueTable +#define IPC_QUEUE_MUTEX g_mqueueMutex +#define IPC_QUEUE_MQ_PRIV_BUF g_mqPrivBuf +#endif + /* LOCAL FUNCTIONS */ STATIC INLINE INT32 MqNameCheck(const CHAR *mqName) { @@ -96,12 +99,12 @@ STATIC INLINE struct mqarray *GetMqueueCBByName(const CHAR *name) UINT32 mylen = strlen(name); for (index = 0; index < LOSCFG_BASE_IPC_QUEUE_LIMIT; index++) { - if ((g_queueTable[index].mq_name == NULL) || (strlen(g_queueTable[index].mq_name) != mylen)) { + if ((IPC_QUEUE_TABLE[index].mq_name == NULL) || (strlen(IPC_QUEUE_TABLE[index].mq_name) != mylen)) { continue; } - if (strncmp(name, (const CHAR *)(g_queueTable[index].mq_name), mylen) == 0) { - return &(g_queueTable[index]); + if (strncmp(name, (const CHAR *)(IPC_QUEUE_TABLE[index].mq_name), mylen) == 0) { + return &(IPC_QUEUE_TABLE[index]); } } return NULL; @@ -170,8 +173,8 @@ STATIC struct mqpersonal *DoMqueueCreate(const struct mq_attr *attr, const CHAR goto ERROUT; } - if (g_queueTable[GET_QUEUE_INDEX(mqueueID)].mqcb == NULL) { - mqueueCB = &(g_queueTable[GET_QUEUE_INDEX(mqueueID)]); + if (IPC_QUEUE_TABLE[GET_QUEUE_INDEX(mqueueID)].mqcb == NULL) { + mqueueCB = &(IPC_QUEUE_TABLE[GET_QUEUE_INDEX(mqueueID)]); mqueueCB->mq_id = mqueueID; } @@ -297,7 +300,7 @@ STATIC struct mqpersonal *MqGetPrivDataBuff(mqd_t personal) errno = EBADF; return NULL; } - return g_mqPrivBuf[id]; + return IPC_QUEUE_MQ_PRIV_BUF[id]; } /** @@ -311,13 +314,13 @@ STATIC struct mqpersonal *MqGetPrivDataBuff(mqd_t personal) STATIC INT32 MqAllocSysFd(int maxfdp, struct mqpersonal *privateMqPersonal) { INT32 i; - fd_set *fdset = &g_queueFdSet; + fd_set *fdset = &IPC_QUEUE_FD_SET; for (i = 0; i < maxfdp; i++) { /* sysFd: used bit setting, and get the index of swtmrID buffer */ if (fdset && !(FD_ISSET(i + MQUEUE_FD_OFFSET, fdset))) { FD_SET(i + MQUEUE_FD_OFFSET, fdset); - if (!g_mqPrivBuf[i]) { - g_mqPrivBuf[i] = privateMqPersonal; + if (!IPC_QUEUE_MQ_PRIV_BUF[i]) { + IPC_QUEUE_MQ_PRIV_BUF[i] = privateMqPersonal; return i + MQUEUE_FD_OFFSET; } } @@ -328,10 +331,10 @@ STATIC INT32 MqAllocSysFd(int maxfdp, struct mqpersonal *privateMqPersonal) STATIC VOID MqFreeSysFd(mqd_t personal) { INT32 sysFd = (INT32)personal; - fd_set *fdset = &g_queueFdSet; + fd_set *fdset = &IPC_QUEUE_FD_SET; if (fdset && FD_ISSET(sysFd, fdset)) { FD_CLR(sysFd, fdset); - g_mqPrivBuf[sysFd - MQUEUE_FD_OFFSET] = NULL; + IPC_QUEUE_MQ_PRIV_BUF[sysFd - MQUEUE_FD_OFFSET] = NULL; } } @@ -341,7 +344,7 @@ void MqueueRefer(int sysFd) struct mqarray *mqueueCB = NULL; struct mqpersonal *privateMqPersonal = NULL; - (VOID)pthread_mutex_lock(&g_mqueueMutex); + (VOID)pthread_mutex_lock(&IPC_QUEUE_MUTEX); /* Get the personal sysFd and reset personal fd -1 */ privateMqPersonal = MqGetPrivDataBuff((mqd_t)sysFd); if (privateMqPersonal == NULL) { @@ -354,7 +357,7 @@ void MqueueRefer(int sysFd) privateMqPersonal->mq_refcount++; OUT_UNLOCK: - (VOID)pthread_mutex_unlock(&g_mqueueMutex); + (VOID)pthread_mutex_unlock(&IPC_QUEUE_MUTEX); return; } @@ -498,7 +501,7 @@ mqd_t mq_open(const char *mqName, int openFlag, ...) return (mqd_t)-1; } - (VOID)pthread_mutex_lock(&g_mqueueMutex); + (VOID)pthread_mutex_lock(&IPC_QUEUE_MUTEX); mqueueCB = GetMqueueCBByName(mqName); if ((UINT32)openFlag & (UINT32)O_CREAT) { if (mqueueCB != NULL) { @@ -543,7 +546,7 @@ mqd_t mq_open(const char *mqName, int openFlag, ...) mqFd = (mqd_t)sysFd; } OUT: - (VOID)pthread_mutex_unlock(&g_mqueueMutex); + (VOID)pthread_mutex_unlock(&IPC_QUEUE_MUTEX); return mqFd; } @@ -552,7 +555,7 @@ int mq_close(mqd_t personal) INT32 ret = -1; struct mqpersonal *privateMqPersonal = NULL; - (VOID)pthread_mutex_lock(&g_mqueueMutex); + (VOID)pthread_mutex_lock(&IPC_QUEUE_MUTEX); /* Get the personal sysFd and reset personal fd -1 */ privateMqPersonal = MqGetPrivDataBuff(personal); @@ -577,7 +580,7 @@ int mq_close(mqd_t personal) MqFreeSysFd(personal); OUT_UNLOCK: - (VOID)pthread_mutex_unlock(&g_mqueueMutex); + (VOID)pthread_mutex_unlock(&IPC_QUEUE_MUTEX); return ret; } @@ -596,10 +599,10 @@ int OsMqGetAttr(mqd_t personal, struct mq_attr *mqAttr) return -1; } - (VOID)pthread_mutex_lock(&g_mqueueMutex); + (VOID)pthread_mutex_lock(&IPC_QUEUE_MUTEX); if (privateMqPersonal->mq_status != MQ_USE_MAGIC) { errno = EBADF; - (VOID)pthread_mutex_unlock(&g_mqueueMutex); + (VOID)pthread_mutex_unlock(&IPC_QUEUE_MUTEX); return -1; } @@ -608,7 +611,7 @@ int OsMqGetAttr(mqd_t personal, struct mq_attr *mqAttr) mqAttr->mq_msgsize = mqueueCB->mqcb->queueSize - sizeof(UINT32); mqAttr->mq_curmsgs = mqueueCB->mqcb->readWriteableCnt[OS_QUEUE_READ]; mqAttr->mq_flags = privateMqPersonal->mq_flags; - (VOID)pthread_mutex_unlock(&g_mqueueMutex); + (VOID)pthread_mutex_unlock(&IPC_QUEUE_MUTEX); return 0; } @@ -626,10 +629,10 @@ int OsMqSetAttr(mqd_t personal, const struct mq_attr *mqSetAttr, struct mq_attr return -1; } - (VOID)pthread_mutex_lock(&g_mqueueMutex); + (VOID)pthread_mutex_lock(&IPC_QUEUE_MUTEX); if (privateMqPersonal->mq_status != MQ_USE_MAGIC) { errno = EBADF; - (VOID)pthread_mutex_unlock(&g_mqueueMutex); + (VOID)pthread_mutex_unlock(&IPC_QUEUE_MUTEX); return -1; } @@ -641,7 +644,7 @@ int OsMqSetAttr(mqd_t personal, const struct mq_attr *mqSetAttr, struct mq_attr if (((UINT32)mqSetAttr->mq_flags & (UINT32)FNONBLOCK) == (UINT32)FNONBLOCK) { privateMqPersonal->mq_flags = (INT32)((UINT32)privateMqPersonal->mq_flags | (UINT32)FNONBLOCK); } - (VOID)pthread_mutex_unlock(&g_mqueueMutex); + (VOID)pthread_mutex_unlock(&IPC_QUEUE_MUTEX); return 0; } @@ -662,7 +665,7 @@ int mq_unlink(const char *mqName) return -1; } - (VOID)pthread_mutex_lock(&g_mqueueMutex); + (VOID)pthread_mutex_lock(&IPC_QUEUE_MUTEX); mqueueCB = GetMqueueCBByName(mqName); if (mqueueCB == NULL) { errno = ENOENT; @@ -675,11 +678,11 @@ int mq_unlink(const char *mqName) ret = DoMqueueDelete(mqueueCB); } - (VOID)pthread_mutex_unlock(&g_mqueueMutex); + (VOID)pthread_mutex_unlock(&IPC_QUEUE_MUTEX); return ret; ERROUT_UNLOCK: - (VOID)pthread_mutex_unlock(&g_mqueueMutex); + (VOID)pthread_mutex_unlock(&IPC_QUEUE_MUTEX); return -1; } @@ -767,7 +770,7 @@ int mq_timedsend(mqd_t personal, const char *msg, size_t msgLen, unsigned int ms OS_MQ_GOTO_ERROUT_IF(!MqParamCheck(personal, msg, msgLen), errno); OS_MQ_GOTO_ERROUT_IF(msgPrio > (MQ_PRIO_MAX - 1), EINVAL); - (VOID)pthread_mutex_lock(&g_mqueueMutex); + (VOID)pthread_mutex_lock(&IPC_QUEUE_MUTEX); privateMqPersonal = MqGetPrivDataBuff(personal); OS_MQ_GOTO_ERROUT_UNLOCK_IF(privateMqPersonal == NULL || privateMqPersonal->mq_status != MQ_USE_MAGIC, EBADF); @@ -781,7 +784,7 @@ int mq_timedsend(mqd_t personal, const char *msg, size_t msgLen, unsigned int ms OS_MQ_GOTO_ERROUT_UNLOCK_IF(ConvertTimeout(privateMqPersonal->mq_flags, absTimeout, &absTicks) == -1, errno); mqueueID = mqueueCB->mq_id; - (VOID)pthread_mutex_unlock(&g_mqueueMutex); + (VOID)pthread_mutex_unlock(&IPC_QUEUE_MUTEX); if (LOS_ListEmpty(&mqueueCB->mqcb->readWriteList[OS_QUEUE_READ])) { MqSendNotify(mqueueCB); @@ -793,7 +796,7 @@ int mq_timedsend(mqd_t personal, const char *msg, size_t msgLen, unsigned int ms } return 0; ERROUT_UNLOCK: - (VOID)pthread_mutex_unlock(&g_mqueueMutex); + (VOID)pthread_mutex_unlock(&IPC_QUEUE_MUTEX); ERROUT: return -1; } @@ -815,7 +818,7 @@ ssize_t mq_timedreceive(mqd_t personal, char *msg, size_t msgLen, unsigned int * *msgPrio = 0; } - (VOID)pthread_mutex_lock(&g_mqueueMutex); + (VOID)pthread_mutex_lock(&IPC_QUEUE_MUTEX); privateMqPersonal = MqGetPrivDataBuff(personal); if (privateMqPersonal == NULL || privateMqPersonal->mq_status != MQ_USE_MAGIC) { errno = EBADF; @@ -839,7 +842,7 @@ ssize_t mq_timedreceive(mqd_t personal, char *msg, size_t msgLen, unsigned int * receiveLen = msgLen; mqueueID = mqueueCB->mq_id; - (VOID)pthread_mutex_unlock(&g_mqueueMutex); + (VOID)pthread_mutex_unlock(&IPC_QUEUE_MUTEX); err = LOS_QueueReadCopy(mqueueID, (VOID *)msg, &receiveLen, (UINT32)absTicks); if (map_errno(err) == ENOERR) { @@ -849,7 +852,7 @@ ssize_t mq_timedreceive(mqd_t personal, char *msg, size_t msgLen, unsigned int * } ERROUT_UNLOCK: - (VOID)pthread_mutex_unlock(&g_mqueueMutex); + (VOID)pthread_mutex_unlock(&IPC_QUEUE_MUTEX); ERROUT: return -1; } @@ -898,7 +901,7 @@ int OsMqNotify(mqd_t personal, const struct sigevent *sigev) goto ERROUT; } - (VOID)pthread_mutex_lock(&g_mqueueMutex); + (VOID)pthread_mutex_lock(&IPC_QUEUE_MUTEX); privateMqPersonal = MqGetPrivDataBuff(personal); if (privateMqPersonal == NULL) { goto OUT_UNLOCK; @@ -936,10 +939,10 @@ int OsMqNotify(mqd_t personal, const struct sigevent *sigev) mqnotify->pid = LOS_GetCurrProcessID(); } - (VOID)pthread_mutex_unlock(&g_mqueueMutex); + (VOID)pthread_mutex_unlock(&IPC_QUEUE_MUTEX); return 0; OUT_UNLOCK: - (VOID)pthread_mutex_unlock(&g_mqueueMutex); + (VOID)pthread_mutex_unlock(&IPC_QUEUE_MUTEX); ERROUT: return -1; } diff --git a/fs/proc/os_adapt/process_proc.c b/fs/proc/os_adapt/process_proc.c index 0d4b163e..2d721fe9 100644 --- a/fs/proc/os_adapt/process_proc.c +++ b/fs/proc/os_adapt/process_proc.c @@ -70,6 +70,8 @@ static ssize_t ProcessContainerLink(unsigned int containerID, ContainerType type count = snprintf_s(buffer, bufLen, bufLen - 1, "'uts:[%u]'", containerID); } else if (type == MNT_CONTAINER) { count = snprintf_s(buffer, bufLen, bufLen - 1, "'mnt:[%u]'", containerID); + } else if (type == IPC_CONTAINER) { + count = snprintf_s(buffer, bufLen, bufLen - 1, "'ipc:[%u]'", containerID); } if (count < 0) { @@ -250,6 +252,14 @@ static struct ProcProcess g_procProcess[] = { .fileOps = &PID_CONTAINER_FOPS }, #endif +#ifdef LOSCFG_IPC_CONTAINER + { + .name = "container/ipc", + .mode = S_IFLNK, + .type = IPC_CONTAINER, + .fileOps = &PID_CONTAINER_FOPS + }, +#endif #endif }; diff --git a/kernel/Kconfig b/kernel/Kconfig index a8d68bb5..1c547962 100644 --- a/kernel/Kconfig +++ b/kernel/Kconfig @@ -74,7 +74,7 @@ config KERNEL_CONTAINER depends on KERNEL_VM config PID_CONTAINER - bool "Enable PID container Feature" + bool "Enable pid container Feature" default n depends on KERNEL_CONTAINER @@ -84,7 +84,7 @@ config UTS_CONTAINER depends on KERNEL_CONTAINER config MNT_CONTAINER - bool "Enable MNT container Feature" + bool "Enable mnt container Feature" default n depends on KERNEL_CONTAINER @@ -93,6 +93,11 @@ config CHROOT default n depends on MNT_CONTAINER +config IPC_CONTAINER + bool "Enable ipc container Feature" + default n + depends on KERNEL_CONTAINER + ######################### config options of extended ##################### source "kernel/extended/Kconfig" diff --git a/kernel/base/BUILD.gn b/kernel/base/BUILD.gn index a4820041..a1cd7730 100644 --- a/kernel/base/BUILD.gn +++ b/kernel/base/BUILD.gn @@ -33,6 +33,7 @@ module_name = get_path_info(rebase_path("."), "name") kernel_module(module_name) { sources = [ "container/los_container.c", + "container/los_ipc_container.c", "container/los_mnt_container.c", "container/los_pid_container.c", "container/los_uts_container.c", diff --git a/kernel/base/container/los_container.c b/kernel/base/container/los_container.c index 6eed4e73..61a4019e 100644 --- a/kernel/base/container/los_container.c +++ b/kernel/base/container/los_container.c @@ -59,6 +59,9 @@ VOID OsInitRootContainer(VOID) #endif #ifdef LOSCFG_MNT_CONTAINER (VOID)OsInitRootMntContainer(&g_rootContainer.mntContainer); +#endif +#ifdef LOSCFG_IPC_CONTAINER + (VOID)OsInitRootIpcContainer(&g_rootContainer.ipcContainer); #endif return; } @@ -115,6 +118,12 @@ UINT32 OsCopyContainers(UINTPTR flags, LosProcessCB *child, LosProcessCB *parent if (ret != LOS_OK) { return ret; } +#endif +#ifdef LOSCFG_IPC_CONTAINER + ret = OsCopyIpcContainer(flags, child, parent); + if (ret != LOS_OK) { + return ret; + } #endif return ret; } @@ -136,6 +145,10 @@ VOID OsContainersDestroy(LosProcessCB *processCB) OsMntContainersDestroy(processCB); #endif +#ifdef LOSCFG_IPC_CONTAINER + OsIpcContainersDestroy(processCB); +#endif + #ifndef LOSCFG_PID_CONTAINER LOS_AtomicDec(&curr->container->rc); if (LOS_AtomicRead(&processCB->container->rc) == 1) { @@ -152,12 +165,22 @@ UINT32 OsGetContainerID(Container *container, ContainerType type) } switch (type) { +#ifdef LOSCFG_PID_CONTAINER case PID_CONTAINER: return OsGetPidContainerID(container->pidContainer); +#endif +#ifdef LOSCFG_UTS_CONTAINER case UTS_CONTAINER: return OsGetUtsContainerID(container->utsContainer); +#endif +#ifdef LOSCFG_MNT_CONTAINER case MNT_CONTAINER: return OsGetMntContainerID(container->mntContainer); +#endif +#ifdef LOSCFG_IPC_CONTAINER + case IPC_CONTAINER: + return OsGetIpcContainerID(container->ipcContainer); +#endif default: break; } diff --git a/kernel/base/container/los_ipc_container.c b/kernel/base/container/los_ipc_container.c new file mode 100644 index 00000000..0669250f --- /dev/null +++ b/kernel/base/container/los_ipc_container.c @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2023-2023 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. + */ +#ifdef LOSCFG_IPC_CONTAINER +#include "los_ipc_container_pri.h" +#include "los_config.h" +#include "los_queue_pri.h" +#include "los_vm_shm_pri.h" +#include "los_process_pri.h" +#include "vnode.h" +#include "proc_fs.h" +#include "pthread.h" + +#define IPC_INIT_NUM 3 + +STATIC UINT32 g_currentIpcContainerNum = 0; + +STATIC UINT32 CreateIpcContainer(IpcContainer **newIpcContainer) +{ + pthread_mutexattr_t attr; + UINT32 intSave; + UINT32 size = sizeof(IpcContainer); + IpcContainer *ipcContainer = (IpcContainer *)LOS_MemAlloc(m_aucSysMem1, size); + if (ipcContainer == NULL) { + return ENOMEM; + } + (VOID)memset_s(ipcContainer, size, 0, size); + + ipcContainer->allQueue = OsAllQueueCBInit(&ipcContainer->freeQueueList); + if (ipcContainer->allQueue == NULL) { + (VOID)LOS_MemFree(m_aucSysMem1, ipcContainer); + return ENOMEM; + } + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP); + pthread_mutex_init(&ipcContainer->mqueueMutex, &attr); + + ipcContainer->shmSegs = OsShmCBInit(&ipcContainer->sysvShmMux, &ipcContainer->shmInfo, + &ipcContainer->shmUsedPageCount); + if (ipcContainer->shmSegs == NULL) { + (VOID)LOS_MemFree(m_aucSysMem1, ipcContainer->allQueue); + (VOID)LOS_MemFree(m_aucSysMem1, ipcContainer); + return ENOMEM; + } + + LOS_AtomicSet(&ipcContainer->rc, 1); + ipcContainer->containerID = OsAllocContainerID(); + + SCHEDULER_LOCK(intSave); + g_currentIpcContainerNum += 1; + *newIpcContainer = ipcContainer; + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} + +UINT32 OsInitRootIpcContainer(IpcContainer **ipcContainer) +{ + return CreateIpcContainer(ipcContainer); +} + +UINT32 OsCopyIpcContainer(UINTPTR flags, LosProcessCB *child, LosProcessCB *parent) +{ + UINT32 intSave; + IpcContainer *currIpcContainer = parent->container->ipcContainer; + + if (!(flags & CLONE_NEWIPC)) { + SCHEDULER_LOCK(intSave); + LOS_AtomicInc(&currIpcContainer->rc); + child->container->ipcContainer = currIpcContainer; + SCHEDULER_UNLOCK(intSave); + return LOS_OK; + } + + return CreateIpcContainer(&child->container->ipcContainer); +} + +VOID OsIpcContainersDestroy(LosProcessCB *curr) +{ + UINT32 intSave; + if (curr->container == NULL) { + return; + } + + SCHEDULER_LOCK(intSave); + IpcContainer *ipcContainer = curr->container->ipcContainer; + if (ipcContainer != NULL) { + LOS_AtomicDec(&ipcContainer->rc); + if (LOS_AtomicRead(&ipcContainer->rc) == 0) { + g_currentIpcContainerNum--; + SCHEDULER_UNLOCK(intSave); + ShmDeinit(); + curr->container->ipcContainer = NULL; + (VOID)LOS_MemFree(m_aucSysMem1, ipcContainer->allQueue); + (VOID)LOS_MemFree(m_aucSysMem1, ipcContainer); + return; + } + } + SCHEDULER_UNLOCK(intSave); + return; +} + +UINT32 OsGetIpcContainerID(IpcContainer *ipcContainer) +{ + if (ipcContainer == NULL) { + return OS_INVALID_VALUE; + } + + return ipcContainer->containerID; +} + +IpcContainer *OsGetCurrIpcContainer(VOID) +{ + return OsCurrProcessGet()->container->ipcContainer; +} +#endif diff --git a/kernel/base/container/los_mnt_container.c b/kernel/base/container/los_mnt_container.c index 1782ff47..96743812 100644 --- a/kernel/base/container/los_mnt_container.c +++ b/kernel/base/container/los_mnt_container.c @@ -136,11 +136,12 @@ VOID OsMntContainersDestroy(LosProcessCB *curr) SCHEDULER_LOCK(intSave); MntContainer *mntContainer = curr->container->mntContainer; if (mntContainer != NULL) { + LOS_AtomicDec(&mntContainer->rc); if (LOS_AtomicRead(&mntContainer->rc) == 0) { g_currentMntContainerNum--; + SCHEDULER_UNLOCK(intSave); FreeMountList(&mntContainer->mountList); curr->container->mntContainer = NULL; - SCHEDULER_UNLOCK(intSave); (VOID)LOS_MemFree(m_aucSysMem1, mntContainer); return; } diff --git a/kernel/base/container/los_uts_container.c b/kernel/base/container/los_uts_container.c index c441423d..a28104ec 100644 --- a/kernel/base/container/los_uts_container.c +++ b/kernel/base/container/los_uts_container.c @@ -94,6 +94,7 @@ VOID OsUtsContainersDestroy(LosProcessCB *curr) SCHEDULER_LOCK(intSave); UtsContainer *utsContainer = curr->container->utsContainer; if (utsContainer != NULL) { + LOS_AtomicDec(&utsContainer->rc); if (LOS_AtomicRead(&utsContainer->rc) == 0) { g_currentUtsContainerNum--; curr->container->utsContainer = NULL; diff --git a/kernel/base/core/los_process.c b/kernel/base/core/los_process.c index c597f247..31860852 100644 --- a/kernel/base/core/los_process.c +++ b/kernel/base/core/los_process.c @@ -1893,7 +1893,7 @@ STATIC UINT32 OsCopyMM(UINT32 flags, LosProcessCB *childProcessCB, LosProcessCB return LOS_OK; } - status = LOS_VmSpaceClone(runProcessCB->vmSpace, childProcessCB->vmSpace); + status = LOS_VmSpaceClone(flags, runProcessCB->vmSpace, childProcessCB->vmSpace); if (status != LOS_OK) { return LOS_ENOMEM; } @@ -1906,11 +1906,20 @@ STATIC UINT32 OsCopyFile(UINT32 flags, LosProcessCB *childProcessCB, LosProcessC if (flags & CLONE_FILES) { childProcessCB->files = runProcessCB->files; } else { +#ifdef LOSCFG_IPC_CONTAINER + if (flags & CLONE_NEWIPC) { + OsCurrTaskGet()->cloneIpc = TRUE; + } +#endif childProcessCB->files = dup_fd(runProcessCB->files); +#ifdef LOSCFG_IPC_CONTAINER + OsCurrTaskGet()->cloneIpc = FALSE; +#endif } if (childProcessCB->files == NULL) { return LOS_ENOMEM; } + #ifdef LOSCFG_PROC_PROCESS_DIR INT32 ret = ProcCreateProcessDir(OsGetRootPid(childProcessCB), (UINTPTR)childProcessCB); if (ret < 0) { @@ -1993,7 +2002,6 @@ STATIC UINT32 OsCopyProcessResources(UINT32 flags, LosProcessCB *child, LosProce #ifdef LOSCFG_SECURITY_CAPABILITY OsCopyCapability(run, child); #endif - return LOS_OK; } @@ -2061,6 +2069,12 @@ LITE_OS_SEC_TEXT INT32 OsClone(UINT32 flags, UINTPTR sp, UINT32 size) #ifdef LOSCFG_MNT_CONTAINER cloneFlag |= CLONE_NEWNS; #endif +#ifdef LOSCFG_IPC_CONTAINER + cloneFlag |= CLONE_NEWIPC; + if (((flags & CLONE_NEWIPC) != 0) && ((flags & CLONE_FILES) != 0)) { + return -LOS_EINVAL; + } +#endif #endif if (flags & (~cloneFlag)) { diff --git a/kernel/base/include/los_container_pri.h b/kernel/base/include/los_container_pri.h index 0b9d5682..ba0910ea 100644 --- a/kernel/base/include/los_container_pri.h +++ b/kernel/base/include/los_container_pri.h @@ -42,12 +42,16 @@ #ifdef LOSCFG_MNT_CONTAINER #include "los_mnt_container_pri.h" #endif +#ifdef LOSCFG_IPC_CONTAINER +#include "los_ipc_container_pri.h" +#endif typedef enum { CONTAINER = 0, PID_CONTAINER, UTS_CONTAINER, MNT_CONTAINER, + IPC_CONTAINER, } ContainerType; typedef struct Container { @@ -61,6 +65,9 @@ typedef struct Container { #ifdef LOSCFG_MNT_CONTAINER struct MntContainer *mntContainer; #endif +#ifdef LOSCFG_IPC_CONTAINER + struct IpcContainer *ipcContainer; +#endif } Container; VOID OsContainerInitSystemProcess(LosProcessCB *processCB); diff --git a/kernel/base/include/los_ipc_container_pri.h b/kernel/base/include/los_ipc_container_pri.h new file mode 100644 index 00000000..218954ee --- /dev/null +++ b/kernel/base/include/los_ipc_container_pri.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2023-2023 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 _LOS_IPC_CONTAINER_PRI_H +#define _LOS_IPC_CONTAINER_PRI_H + +#include "los_atomic.h" +#include "los_list.h" +#include "mqueue.h" +#include "fs/file.h" + +#ifdef LOSCFG_IPC_CONTAINER +struct shmIDSource; +typedef struct TagQueueCB LosQueueCB; +typedef struct OsMux LosMux; +typedef LosMux pthread_mutex_t; +typedef struct ProcessCB LosProcessCB; + +typedef struct IpcContainer { + Atomic rc; + LosQueueCB *allQueue; + LOS_DL_LIST freeQueueList; + fd_set queueFdSet; + struct mqarray queueTable[LOSCFG_BASE_IPC_QUEUE_LIMIT]; + pthread_mutex_t mqueueMutex; + struct mqpersonal *mqPrivBuf[MAX_MQ_FD]; + struct shminfo shmInfo; + LosMux sysvShmMux; + struct shmIDSource *shmSegs; + UINT32 shmUsedPageCount; + UINT32 containerID; +} IpcContainer; + +UINT32 OsInitRootIpcContainer(IpcContainer **ipcContainer); + +UINT32 OsCopyIpcContainer(UINTPTR flags, LosProcessCB *child, LosProcessCB *parent); + +VOID OsIpcContainersDestroy(LosProcessCB *curr); + +UINT32 OsGetIpcContainerID(IpcContainer *ipcContainer); + +IpcContainer *OsGetCurrIpcContainer(VOID); + +#define IPC_ALL_QUEUE (OsGetCurrIpcContainer()->allQueue) + +#define FREE_QUEUE_LIST (OsGetCurrIpcContainer()->freeQueueList) + +#define IPC_QUEUE_FD_SET (OsGetCurrIpcContainer()->queueFdSet) + +#define IPC_QUEUE_TABLE (OsGetCurrIpcContainer()->queueTable) + +#define IPC_QUEUE_MUTEX (OsGetCurrIpcContainer()->mqueueMutex) + +#define IPC_QUEUE_MQ_PRIV_BUF (OsGetCurrIpcContainer()->mqPrivBuf) + +#define IPC_SHM_INFO (OsGetCurrIpcContainer()->shmInfo) + +#define IPC_SHM_SYS_VSHM_MUTEX (OsGetCurrIpcContainer()->sysvShmMux) + +#define IPC_SHM_SEGS (OsGetCurrIpcContainer()->shmSegs) + +#define IPC_SHM_USED_PAGE_COUNT (OsGetCurrIpcContainer()->shmUsedPageCount) + +#endif +#endif /* _LOS_IPC_CONTAINER_PRI_H */ diff --git a/kernel/base/include/los_queue_pri.h b/kernel/base/include/los_queue_pri.h index 96472859..4efafe23 100644 --- a/kernel/base/include/los_queue_pri.h +++ b/kernel/base/include/los_queue_pri.h @@ -65,7 +65,7 @@ typedef enum { * @ingroup los_queue * Queue information block structure */ -typedef struct { +typedef struct TagQueueCB { UINT8 *queueHandle; /**< Pointer to a queue handle */ UINT16 queueState; /**< Queue state */ UINT16 queueLen; /**< Queue length */ @@ -108,6 +108,9 @@ typedef struct { * Queue information control block */ extern LosQueueCB *g_allQueue; +#ifndef LOSCFG_IPC_CONTAINER +#define IPC_ALL_QUEUE g_allQueue +#endif /** * @ingroup los_queue @@ -137,7 +140,7 @@ extern LosQueueCB *g_allQueue; * Obtain a handle of the queue that has a specified ID. * */ -#define GET_QUEUE_HANDLE(queueID) (((LosQueueCB *)g_allQueue) + GET_QUEUE_INDEX(queueID)) +#define GET_QUEUE_HANDLE(queueID) (((LosQueueCB *)IPC_ALL_QUEUE) + GET_QUEUE_INDEX(queueID)) /** * @ingroup los_queue @@ -196,6 +199,8 @@ extern VOID *OsQueueMailAlloc(UINT32 queueID, VOID *mailPool, UINT32 timeout); */ extern UINT32 OsQueueMailFree(UINT32 queueID, VOID *mailPool, VOID *mailMem); +extern LosQueueCB *OsAllQueueCBInit(LOS_DL_LIST *freeQueueList); + extern UINT32 OsQueueInit(VOID); #ifdef __cplusplus diff --git a/kernel/base/include/los_sched_pri.h b/kernel/base/include/los_sched_pri.h index aea6d3ca..b17fd729 100644 --- a/kernel/base/include/los_sched_pri.h +++ b/kernel/base/include/los_sched_pri.h @@ -428,6 +428,9 @@ typedef struct TagTaskCB { #ifdef LOSCFG_PID_CONTAINER PidContainer *pidContainer; #endif +#ifdef LOSCFG_IPC_CONTAINER + BOOL cloneIpc; +#endif } LosTaskCB; STATIC INLINE BOOL OsTaskIsRunning(const LosTaskCB *taskCB) diff --git a/kernel/base/include/los_vm_map.h b/kernel/base/include/los_vm_map.h index b0d2fa8b..344e1ad8 100644 --- a/kernel/base/include/los_vm_map.h +++ b/kernel/base/include/los_vm_map.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 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: @@ -290,7 +290,7 @@ STATUS_T LOS_VmSpaceFree(LosVmSpace *space); STATUS_T LOS_VaddrToPaddrMmap(LosVmSpace *space, VADDR_T vaddr, PADDR_T paddr, size_t len, UINT32 flags); BOOL OsUserVmSpaceInit(LosVmSpace *vmSpace, VADDR_T *virtTtb); LosVmSpace *OsCreateUserVmSpace(VOID); -STATUS_T LOS_VmSpaceClone(LosVmSpace *oldVmSpace, LosVmSpace *newVmSpace); +STATUS_T LOS_VmSpaceClone(UINT32 cloneFlags, LosVmSpace *oldVmSpace, LosVmSpace *newVmSpace); LosMux *OsGVmSpaceMuxGet(VOID); STATUS_T OsUnMMap(LosVmSpace *space, VADDR_T addr, size_t size); STATUS_T OsVmSpaceRegionFree(LosVmSpace *space); diff --git a/kernel/base/include/los_vm_shm_pri.h b/kernel/base/include/los_vm_shm_pri.h index b8a7d1f0..24df894f 100644 --- a/kernel/base/include/los_vm_shm_pri.h +++ b/kernel/base/include/los_vm_shm_pri.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 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: @@ -34,17 +34,35 @@ #include "los_typedef.h" #include "los_vm_map.h" - +#include "los_process_pri.h" + #ifdef __cplusplus #if __cplusplus extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ +/* The upper limit size of total shared memory is default 16M */ +#define SHM_MAX_PAGES 4096 +#define SHM_MAX (SHM_MAX_PAGES * PAGE_SIZE) +#define SHM_MIN 1 +#define SHM_MNI 192 +#define SHM_SEG 128 +#define SHM_ALL (SHM_MAX_PAGES) + +struct shmIDSource { + struct shmid_ds ds; + UINT32 status; + LOS_DL_LIST node; +#ifdef LOSCFG_SHELL + CHAR ownerName[OS_PCB_NAME_LEN]; +#endif +}; + VOID OsShmFork(LosVmSpace *space, LosVmMapRegion *oldRegion, LosVmMapRegion *newRegion); VOID OsShmRegionFree(LosVmSpace *space, LosVmMapRegion *region); BOOL OsIsShmRegion(LosVmMapRegion *region); - +struct shmIDSource *OsShmCBInit(LosMux *sysvShmMux, struct shminfo *shmInfo, UINT32 *shmUsedPageCount); #ifdef __cplusplus #if __cplusplus } diff --git a/kernel/base/ipc/los_queue.c b/kernel/base/ipc/los_queue.c index 705c1a9d..8fe06ba2 100644 --- a/kernel/base/ipc/los_queue.c +++ b/kernel/base/ipc/los_queue.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 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: @@ -37,14 +37,51 @@ #include "los_mp.h" #include "los_percpu_pri.h" #include "los_hook.h" +#ifdef LOSCFG_IPC_CONTAINER +#include "los_ipc_container_pri.h" +#endif #ifdef LOSCFG_BASE_IPC_QUEUE #if (LOSCFG_BASE_IPC_QUEUE_LIMIT <= 0) #error "queue maxnum cannot be zero" #endif /* LOSCFG_BASE_IPC_QUEUE_LIMIT <= 0 */ +#ifndef LOSCFG_IPC_CONTAINER LITE_OS_SEC_BSS LosQueueCB *g_allQueue = NULL; LITE_OS_SEC_BSS STATIC LOS_DL_LIST g_freeQueueList; +#define FREE_QUEUE_LIST g_freeQueueList +#endif + +LITE_OS_SEC_TEXT_INIT LosQueueCB *OsAllQueueCBInit(LOS_DL_LIST *freeQueueList) +{ + UINT32 index; + + if (freeQueueList == NULL) { + return NULL; + } + + UINT32 size = LOSCFG_BASE_IPC_QUEUE_LIMIT * sizeof(LosQueueCB); + /* system resident memory, don't free */ + LosQueueCB *allQueue = (LosQueueCB *)LOS_MemAlloc(m_aucSysMem0, size); + if (allQueue == NULL) { + return NULL; + } + (VOID)memset_s(allQueue, size, 0, size); + LOS_ListInit(freeQueueList); + for (index = 0; index < LOSCFG_BASE_IPC_QUEUE_LIMIT; index++) { + LosQueueCB *queueNode = ((LosQueueCB *)allQueue) + index; + queueNode->queueID = index; + LOS_ListTailInsert(freeQueueList, &queueNode->readWriteList[OS_QUEUE_WRITE]); + } + +#ifndef LOSCFG_IPC_CONTAINER + if (OsQueueDbgInitHook() != LOS_OK) { + (VOID)LOS_MemFree(m_aucSysMem0, allQueue); + return NULL; + } +#endif + return allQueue; +} /* * Description : queue initial @@ -52,27 +89,12 @@ LITE_OS_SEC_BSS STATIC LOS_DL_LIST g_freeQueueList; */ LITE_OS_SEC_TEXT_INIT UINT32 OsQueueInit(VOID) { - LosQueueCB *queueNode = NULL; - UINT32 index; - UINT32 size; - - size = LOSCFG_BASE_IPC_QUEUE_LIMIT * sizeof(LosQueueCB); - /* system resident memory, don't free */ - g_allQueue = (LosQueueCB *)LOS_MemAlloc(m_aucSysMem0, size); +#ifndef LOSCFG_IPC_CONTAINER + g_allQueue = OsAllQueueCBInit(&g_freeQueueList); if (g_allQueue == NULL) { return LOS_ERRNO_QUEUE_NO_MEMORY; } - (VOID)memset_s(g_allQueue, size, 0, size); - LOS_ListInit(&g_freeQueueList); - for (index = 0; index < LOSCFG_BASE_IPC_QUEUE_LIMIT; index++) { - queueNode = ((LosQueueCB *)g_allQueue) + index; - queueNode->queueID = index; - LOS_ListTailInsert(&g_freeQueueList, &queueNode->readWriteList[OS_QUEUE_WRITE]); - } - - if (OsQueueDbgInitHook() != LOS_OK) { - return LOS_ERRNO_QUEUE_NO_MEMORY; - } +#endif return LOS_OK; } @@ -111,14 +133,14 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_QueueCreate(CHAR *queueName, UINT16 len, UINT32 } SCHEDULER_LOCK(intSave); - if (LOS_ListEmpty(&g_freeQueueList)) { + if (LOS_ListEmpty(&FREE_QUEUE_LIST)) { SCHEDULER_UNLOCK(intSave); OsQueueCheckHook(); (VOID)LOS_MemFree(m_aucSysMem1, queue); return LOS_ERRNO_QUEUE_CB_UNAVAILABLE; } - unusedQueue = LOS_DL_LIST_FIRST(&g_freeQueueList); + unusedQueue = LOS_DL_LIST_FIRST(&FREE_QUEUE_LIST); LOS_ListDelete(unusedQueue); queueCB = GET_QUEUE_LIST(unusedQueue); queueCB->queueLen = len; @@ -433,7 +455,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_QueueDelete(UINT32 queueID) queueCB->queueID = SET_QUEUE_ID(GET_QUEUE_COUNT(queueCB->queueID) + 1, GET_QUEUE_INDEX(queueCB->queueID)); OsQueueDbgUpdateHook(queueCB->queueID, NULL); - LOS_ListTailInsert(&g_freeQueueList, &queueCB->readWriteList[OS_QUEUE_WRITE]); + LOS_ListTailInsert(&FREE_QUEUE_LIST, &queueCB->readWriteList[OS_QUEUE_WRITE]); SCHEDULER_UNLOCK(intSave); OsHookCall(LOS_HOOK_TYPE_QUEUE_DELETE, queueCB); ret = LOS_MemFree(m_aucSysMem1, (VOID *)queue); diff --git a/kernel/base/misc/sysinfo_shellcmd.c b/kernel/base/misc/sysinfo_shellcmd.c index 46f85f08..b7c56f84 100644 --- a/kernel/base/misc/sysinfo_shellcmd.c +++ b/kernel/base/misc/sysinfo_shellcmd.c @@ -35,6 +35,9 @@ #include "los_queue_pri.h" #include "los_swtmr_pri.h" #include "los_task_pri.h" +#ifdef LOSCFG_IPC_CONTAINER +#include "los_ipc_container_pri.h" +#endif #ifdef LOSCFG_SHELL #include "shcmd.h" @@ -88,7 +91,7 @@ UINT32 OsShellCmdQueueCntGet(VOID) LosQueueCB *queueCB = NULL; intSave = LOS_IntLock(); - queueCB = g_allQueue; + queueCB = IPC_ALL_QUEUE; for (loop = 0; loop < LOSCFG_BASE_IPC_QUEUE_LIMIT; loop++, queueCB++) { if (queueCB->queueState == OS_QUEUE_INUSED) { queueCnt++; diff --git a/kernel/base/vm/los_vm_map.c b/kernel/base/vm/los_vm_map.c index 6ce822c1..5d4f62b3 100644 --- a/kernel/base/vm/los_vm_map.c +++ b/kernel/base/vm/los_vm_map.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 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: @@ -241,20 +241,15 @@ STATIC BOOL OsVmSpaceParamCheck(const LosVmSpace *vmSpace) return TRUE; } -STATUS_T LOS_VmSpaceClone(LosVmSpace *oldVmSpace, LosVmSpace *newVmSpace) +STATUS_T LOS_VmSpaceClone(UINT32 cloneFlags, LosVmSpace *oldVmSpace, LosVmSpace *newVmSpace) { - LosVmMapRegion *oldRegion = NULL; - LosVmMapRegion *newRegion = NULL; LosRbNode *pstRbNode = NULL; LosRbNode *pstRbNodeNext = NULL; STATUS_T ret = LOS_OK; - UINT32 numPages; PADDR_T paddr; VADDR_T vaddr; - UINT32 intSave; LosVmPage *page = NULL; - UINT32 flags; - UINT32 i; + UINT32 flags, i, intSave, numPages; if ((OsVmSpaceParamCheck(oldVmSpace) == FALSE) || (OsVmSpaceParamCheck(newVmSpace) == FALSE)) { return LOS_ERRNO_VM_INVALID_ARGS; @@ -270,8 +265,13 @@ STATUS_T LOS_VmSpaceClone(LosVmSpace *oldVmSpace, LosVmSpace *newVmSpace) newVmSpace->heapNow = oldVmSpace->heapNow; (VOID)LOS_MuxAcquire(&oldVmSpace->regionMux); RB_SCAN_SAFE(&oldVmSpace->regionRbTree, pstRbNode, pstRbNodeNext) - oldRegion = (LosVmMapRegion *)pstRbNode; - newRegion = OsVmRegionDup(newVmSpace, oldRegion, oldRegion->range.base, oldRegion->range.size); + LosVmMapRegion *oldRegion = (LosVmMapRegion *)pstRbNode; +#if defined(LOSCFG_KERNEL_SHM) && defined(LOSCFG_IPC_CONTAINER) + if ((oldRegion->regionFlags & VM_MAP_REGION_FLAG_SHM) && (cloneFlags & CLONE_NEWIPC)) { + continue; + } +#endif + LosVmMapRegion *newRegion = OsVmRegionDup(newVmSpace, oldRegion, oldRegion->range.base, oldRegion->range.size); if (newRegion == NULL) { VM_ERR("dup new region failed"); ret = LOS_ERRNO_VM_NO_MEMORY; diff --git a/kernel/base/vm/shm.c b/kernel/base/vm/shm.c index f56fec42..03b1e26d 100644 --- a/kernel/base/vm/shm.c +++ b/kernel/base/vm/shm.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2020-2023 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: @@ -33,7 +33,6 @@ #include "string.h" #include "time.h" #include "sys/types.h" -#include "sys/shm.h" #include "sys/stat.h" #include "los_config.h" #include "los_init.h" @@ -46,6 +45,8 @@ #include "los_process.h" #include "los_process_pri.h" #include "user_copy.h" +#include "los_vm_shm_pri.h" +#include "sys/shm.h" #ifdef LOSCFG_SHELL #include "shcmd.h" #include "shell.h" @@ -54,20 +55,6 @@ #ifdef LOSCFG_KERNEL_SHM -STATIC LosMux g_sysvShmMux; - -/* private macro */ -#define SYSV_SHM_LOCK() (VOID)LOS_MuxLock(&g_sysvShmMux, LOS_WAIT_FOREVER) -#define SYSV_SHM_UNLOCK() (VOID)LOS_MuxUnlock(&g_sysvShmMux) - -/* The upper limit size of total shared memory is default 16M */ -#define SHM_MAX_PAGES 4096 -#define SHM_MAX (SHM_MAX_PAGES * PAGE_SIZE) -#define SHM_MIN 1 -#define SHM_MNI 192 -#define SHM_SEG 128 -#define SHM_ALL (SHM_MAX_PAGES) - #define SHM_SEG_FREE 0x2000 #define SHM_SEG_USED 0x4000 #define SHM_SEG_REMOVE 0x8000 @@ -91,57 +78,75 @@ STATIC LosMux g_sysvShmMux; #define SHM_GROUPE_TO_USER 3 #define SHM_OTHER_TO_USER 6 -struct shmIDSource { - struct shmid_ds ds; - UINT32 status; - LOS_DL_LIST node; -#ifdef LOSCFG_SHELL - CHAR ownerName[OS_PCB_NAME_LEN]; -#endif -}; +#ifndef LOSCFG_IPC_CONTAINER +STATIC LosMux g_sysvShmMux; /* private data */ -STATIC struct shminfo g_shmInfo = { - .shmmax = SHM_MAX, - .shmmin = SHM_MIN, - .shmmni = SHM_MNI, - .shmseg = SHM_SEG, - .shmall = SHM_ALL, -}; - +STATIC struct shminfo g_shmInfo; STATIC struct shmIDSource *g_shmSegs = NULL; STATIC UINT32 g_shmUsedPageCount; -UINT32 ShmInit(VOID) +#define IPC_SHM_INFO g_shmInfo +#define IPC_SHM_SYS_VSHM_MUTEX g_sysvShmMux +#define IPC_SHM_SEGS g_shmSegs +#define IPC_SHM_USED_PAGE_COUNT g_shmUsedPageCount +#endif + +/* private macro */ +#define SYSV_SHM_LOCK() (VOID)LOS_MuxLock(&IPC_SHM_SYS_VSHM_MUTEX, LOS_WAIT_FOREVER) +#define SYSV_SHM_UNLOCK() (VOID)LOS_MuxUnlock(&IPC_SHM_SYS_VSHM_MUTEX) + +struct shmIDSource *OsShmCBInit(LosMux *sysvShmMux, struct shminfo *shmInfo, UINT32 *shmUsedPageCount) { UINT32 ret; UINT32 i; - ret = LOS_MuxInit(&g_sysvShmMux, NULL); + if ((sysvShmMux == NULL) || (shmInfo == NULL) || (shmUsedPageCount == NULL)) { + return NULL; + } + + ret = LOS_MuxInit(sysvShmMux, NULL); if (ret != LOS_OK) { goto ERROR; } - g_shmSegs = LOS_MemAlloc((VOID *)OS_SYS_MEM_ADDR, sizeof(struct shmIDSource) * g_shmInfo.shmmni); - if (g_shmSegs == NULL) { - (VOID)LOS_MuxDestroy(&g_sysvShmMux); + shmInfo->shmmax = SHM_MAX; + shmInfo->shmmin = SHM_MIN; + shmInfo->shmmni = SHM_MNI; + shmInfo->shmseg = SHM_SEG; + shmInfo->shmall = SHM_ALL; + + struct shmIDSource *shmSegs = LOS_MemAlloc((VOID *)OS_SYS_MEM_ADDR, sizeof(struct shmIDSource) * shmInfo->shmmni); + if (shmSegs == NULL) { + (VOID)LOS_MuxDestroy(sysvShmMux); goto ERROR; } - (VOID)memset_s(g_shmSegs, (sizeof(struct shmIDSource) * g_shmInfo.shmmni), - 0, (sizeof(struct shmIDSource) * g_shmInfo.shmmni)); + (VOID)memset_s(shmSegs, (sizeof(struct shmIDSource) * shmInfo->shmmni), + 0, (sizeof(struct shmIDSource) * shmInfo->shmmni)); - for (i = 0; i < g_shmInfo.shmmni; i++) { - g_shmSegs[i].status = SHM_SEG_FREE; - g_shmSegs[i].ds.shm_perm.seq = i + 1; - LOS_ListInit(&g_shmSegs[i].node); + for (i = 0; i < shmInfo->shmmni; i++) { + shmSegs[i].status = SHM_SEG_FREE; + shmSegs[i].ds.shm_perm.seq = i + 1; + LOS_ListInit(&shmSegs[i].node); } - g_shmUsedPageCount = 0; + *shmUsedPageCount = 0; - return LOS_OK; + return shmSegs; ERROR: VM_ERR("ShmInit fail\n"); - return LOS_NOK; + return NULL; +} + +UINT32 ShmInit(VOID) +{ +#ifndef LOSCFG_IPC_CONTAINER + g_shmSegs = OsShmCBInit(&IPC_SHM_SYS_VSHM_MUTEX, &IPC_SHM_INFO, &IPC_SHM_USED_PAGE_COUNT); + if (g_shmSegs == NULL) { + return LOS_NOK; + } +#endif + return LOS_OK; } LOS_MODULE_INIT(ShmInit, LOS_INIT_LEVEL_VM_COMPLETE); @@ -150,10 +155,10 @@ UINT32 ShmDeinit(VOID) { UINT32 ret; - (VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, g_shmSegs); - g_shmSegs = NULL; + (VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, IPC_SHM_SEGS); + IPC_SHM_SEGS = NULL; - ret = LOS_MuxDestroy(&g_sysvShmMux); + ret = LOS_MuxDestroy(&IPC_SHM_SYS_VSHM_MUTEX); if (ret != LOS_OK) { return -1; } @@ -195,18 +200,18 @@ STATIC INT32 ShmAllocSeg(key_t key, size_t size, INT32 shmflg) struct shmIDSource *seg = NULL; size_t count; - if ((size == 0) || (size < g_shmInfo.shmmin) || - (size > g_shmInfo.shmmax)) { + if ((size == 0) || (size < IPC_SHM_INFO.shmmin) || + (size > IPC_SHM_INFO.shmmax)) { return -EINVAL; } size = LOS_Align(size, PAGE_SIZE); - if ((g_shmUsedPageCount + (size >> PAGE_SHIFT)) > g_shmInfo.shmall) { + if ((IPC_SHM_USED_PAGE_COUNT + (size >> PAGE_SHIFT)) > IPC_SHM_INFO.shmall) { return -ENOMEM; } - for (i = 0; i < g_shmInfo.shmmni; i++) { - if (g_shmSegs[i].status & SHM_SEG_FREE) { - g_shmSegs[i].status &= ~SHM_SEG_FREE; + for (i = 0; i < IPC_SHM_INFO.shmmni; i++) { + if (IPC_SHM_SEGS[i].status & SHM_SEG_FREE) { + IPC_SHM_SEGS[i].status &= ~SHM_SEG_FREE; segNum = i; break; } @@ -216,7 +221,7 @@ STATIC INT32 ShmAllocSeg(key_t key, size_t size, INT32 shmflg) return -ENOSPC; } - seg = &g_shmSegs[segNum]; + seg = &IPC_SHM_SEGS[segNum]; count = LOS_PhysPagesAlloc(size >> PAGE_SHIFT, &seg->node); if (count != (size >> PAGE_SHIFT)) { (VOID)LOS_PhysPagesFree(&seg->node); @@ -224,7 +229,7 @@ STATIC INT32 ShmAllocSeg(key_t key, size_t size, INT32 shmflg) return -ENOMEM; } ShmSetSharedFlag(seg); - g_shmUsedPageCount += size >> PAGE_SHIFT; + IPC_SHM_USED_PAGE_COUNT += size >> PAGE_SHIFT; seg->status |= SHM_SEG_USED; seg->ds.shm_perm.mode = (UINT32)shmflg & ACCESSPERMS; @@ -257,7 +262,7 @@ STATIC INLINE VOID ShmFreeSeg(struct shmIDSource *seg) VM_ERR("free physical pages failed, count = %d, size = %d", count, seg->ds.shm_segsz >> PAGE_SHIFT); return; } - g_shmUsedPageCount -= seg->ds.shm_segsz >> PAGE_SHIFT; + IPC_SHM_USED_PAGE_COUNT -= seg->ds.shm_segsz >> PAGE_SHIFT; seg->status = SHM_SEG_FREE; LOS_ListInit(&seg->node); } @@ -267,8 +272,8 @@ STATIC INT32 ShmFindSegByKey(key_t key) INT32 i; struct shmIDSource *seg = NULL; - for (i = 0; i < g_shmInfo.shmmni; i++) { - seg = &g_shmSegs[i]; + for (i = 0; i < IPC_SHM_INFO.shmmni; i++) { + seg = &IPC_SHM_SEGS[i]; if ((seg->status & SHM_SEG_USED) && (seg->ds.shm_perm.key == key)) { return i; @@ -280,7 +285,7 @@ STATIC INT32 ShmFindSegByKey(key_t key) STATIC INT32 ShmSegValidCheck(INT32 segNum, size_t size, INT32 shmFlg) { - struct shmIDSource *seg = &g_shmSegs[segNum]; + struct shmIDSource *seg = &IPC_SHM_SEGS[segNum]; if (size > seg->ds.shm_segsz) { return -EINVAL; @@ -298,12 +303,12 @@ STATIC struct shmIDSource *ShmFindSeg(int shmid) { struct shmIDSource *seg = NULL; - if ((shmid < 0) || (shmid >= g_shmInfo.shmmni)) { + if ((shmid < 0) || (shmid >= IPC_SHM_INFO.shmmni)) { set_errno(EINVAL); return NULL; } - seg = &g_shmSegs[shmid]; + seg = &IPC_SHM_SEGS[shmid]; if ((seg->status & SHM_SEG_FREE) || ((seg->ds.shm_nattch == 0) && (seg->status & SHM_SEG_REMOVE))) { set_errno(EIDRM); return NULL; @@ -383,8 +388,8 @@ STATIC INT32 ShmSegUsedCount(VOID) INT32 count = 0; struct shmIDSource *seg = NULL; - for (i = 0; i < g_shmInfo.shmmni; i++) { - seg = &g_shmSegs[i]; + for (i = 0; i < IPC_SHM_INFO.shmmni; i++) { + seg = &IPC_SHM_SEGS[i]; if (seg->status & SHM_SEG_USED) { count++; } @@ -676,12 +681,12 @@ INT32 ShmCtl(INT32 shmid, INT32 cmd, struct shmid_ds *buf) } break; case IPC_INFO: - ret = LOS_ArchCopyToUser(buf, &g_shmInfo, sizeof(struct shminfo)); + ret = LOS_ArchCopyToUser(buf, &IPC_SHM_INFO, sizeof(struct shminfo)); if (ret != 0) { ret = EFAULT; goto ERROR; } - ret = g_shmInfo.shmmni; + ret = IPC_SHM_INFO.shmmni; break; case SHM_INFO: shmInfo.shm_rss = 0; @@ -695,7 +700,7 @@ INT32 ShmCtl(INT32 shmid, INT32 cmd, struct shmid_ds *buf) ret = EFAULT; goto ERROR; } - ret = g_shmInfo.shmmni; + ret = IPC_SHM_INFO.shmmni; break; default: VM_ERR("the cmd(%d) is not supported!", cmd); @@ -784,8 +789,8 @@ STATIC VOID OsShmInfoCmd(VOID) PRINTK("\r\n------- Shared Memory Segments -------\n"); PRINTK("key shmid perms bytes nattch status owner\n"); SYSV_SHM_LOCK(); - for (i = 0; i < g_shmInfo.shmmni; i++) { - seg = &g_shmSegs[i]; + for (i = 0; i < IPC_SHM_INFO.shmmni; i++) { + seg = &IPC_SHM_SEGS[i]; if (!(seg->status & SHM_SEG_USED)) { continue; } @@ -801,7 +806,7 @@ STATIC VOID OsShmDeleteCmd(INT32 shmid) { struct shmIDSource *seg = NULL; - if ((shmid < 0) || (shmid >= g_shmInfo.shmmni)) { + if ((shmid < 0) || (shmid >= IPC_SHM_INFO.shmmni)) { PRINT_ERR("shmid is invalid: %d\n", shmid); return; } diff --git a/testsuites/unittest/config.gni b/testsuites/unittest/config.gni index 73f29871..d5918f2c 100644 --- a/testsuites/unittest/config.gni +++ b/testsuites/unittest/config.gni @@ -136,6 +136,7 @@ LOSCFG_USER_TEST_CONTAINER = false LOSCFG_USER_TEST_PID_CONTAINER = false LOSCFG_USER_TEST_UTS_CONTAINER = false LOSCFG_USER_TEST_MNT_CONTAINER = false +LOSCFG_USER_TEST_IPC_CONTAINER = false if (defined(LOSCFG_KERNEL_CONTAINER)) { LOSCFG_USER_TEST_CONTAINER = true if (defined(LOSCFG_PID_CONTAINER)) { @@ -147,4 +148,7 @@ if (defined(LOSCFG_KERNEL_CONTAINER)) { if (defined(LOSCFG_MNT_CONTAINER)) { LOSCFG_USER_TEST_MNT_CONTAINER = true } + if (defined(LOSCFG_IPC_CONTAINER)) { + LOSCFG_USER_TEST_IPC_CONTAINER = true + } } diff --git a/testsuites/unittest/container/BUILD.gn b/testsuites/unittest/container/BUILD.gn index f130dcd0..68d8bd25 100644 --- a/testsuites/unittest/container/BUILD.gn +++ b/testsuites/unittest/container/BUILD.gn @@ -41,6 +41,9 @@ config("container_config") { if (defined(LOSCFG_USER_TEST_MNT_CONTAINER)) { cflags += [ "-DLOSCFG_USER_TEST_MNT_CONTAINER" ] } + if (defined(LOSCFG_USER_TEST_IPC_CONTAINER)) { + cflags += [ "-DLOSCFG_USER_TEST_IPC_CONTAINER" ] + } cflags_cc = cflags } diff --git a/testsuites/unittest/container/It_container_test.cpp b/testsuites/unittest/container/It_container_test.cpp index d7ef0453..33f76789 100644 --- a/testsuites/unittest/container/It_container_test.cpp +++ b/testsuites/unittest/container/It_container_test.cpp @@ -215,7 +215,33 @@ HWTEST_F(ContainerTest, ItContainerChroot001, TestSize.Level0) ItContainerChroot001(); } -#endif /* LOSCFG_MNT_CONTAINER */ +#endif /* LOSCFG_USER_TEST_MNT_CONTAINER */ + +#if defined(LOSCFG_USER_TEST_IPC_CONTAINER) +/** +* @tc.name: Container_IPC_Test_001 +* @tc.desc: ipc container function test case +* @tc.type: FUNC +* @tc.require: issueI6AVMY +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItIpcContainer001, TestSize.Level0) +{ + ItIpcContainer001(); +} + +/** +* @tc.name: Container_IPC_Test_004 +* @tc.desc: ipc container function test case +* @tc.type: FUNC +* @tc.require: issueI6AVMY +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItIpcContainer004, TestSize.Level0) +{ + ItIpcContainer004(); +} +#endif #endif /* LOSCFG_USER_TEST_SMOKE */ #if defined(LOSCFG_USER_TEST_FULL) diff --git a/testsuites/unittest/container/It_container_test.h b/testsuites/unittest/container/It_container_test.h index 4323906d..0dc28ff4 100644 --- a/testsuites/unittest/container/It_container_test.h +++ b/testsuites/unittest/container/It_container_test.h @@ -35,9 +35,14 @@ #include #include #include +#include #include #include #include "osTest.h" +#include "mqueue.h" +#include "sys/time.h" +#include "sys/shm.h" +#include "sys/types.h" const int EXIT_CODE_ERRNO_1 = 1; const int EXIT_CODE_ERRNO_2 = 2; @@ -55,11 +60,19 @@ const int EXIT_CODE_ERRNO_13 = 13; const int EXIT_CODE_ERRNO_14 = 14; const int EXIT_CODE_ERRNO_15 = 15; const int EXIT_CODE_ERRNO_16 = 16; +const int EXIT_CODE_ERRNO_17 = 17; const int EXIT_CODE_ERRNO_255 = 255; const int CONTAINER_FIRST_PID = 1; const int CONTAINER_SECOND_PID = 2; const int CONTAINER_THIRD_PID = 3; +const int MQUEUE_TEST_SIZE = 50; +const int MQUEUE_TEST_MAX_MSG = 255; + +const int SHM_TEST_DATA_SIZE = 1024; +const int SHM_TEST_KEY1 = 1234; +const int SHM_TEST_OPEN_PERM = 0666; +const int CLONE_STACK_MMAP_FLAG = MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK; extern const char *USERDATA_DIR_NAME; extern const char *ACCESS_FILE_NAME; @@ -71,6 +84,8 @@ extern const int BIT_ON_RETURN_VALUE; extern const int STACK_SIZE; extern const int CHILD_FUNC_ARG; +const int MQUEUE_STANDARD_NAME_LENGTH = 255; + int ChildFunction(void *args); pid_t CloneWrapper(int (*func)(void *), int flag, void *args); @@ -79,6 +94,42 @@ std::string GenContainerLinkPath(int pid, const std::string& containerType); extern std::string ReadlinkContainer(int pid, const std::string& containerType); +class MQueueFinalizer { +public: + explicit MQueueFinalizer(mqd_t mqueueParent, const std::string& mqname) + { + m_mqueueParent = mqueueParent; + m_mqname = mqname; + } + ~MQueueFinalizer() + { + if (m_mqueueParent >= 0) { + mq_close(m_mqueueParent); + mq_unlink(m_mqname.c_str()); + } + } +private: + mqd_t m_mqueueParent; + std::string m_mqname; +}; + +class ShmFinalizer { +public: + explicit ShmFinalizer(void* shm, int shmid) + { + m_shm = shm; + m_shmid = shmid; + } + ~ShmFinalizer() + { + shmdt(m_shm); + shmctl(m_shmid, IPC_RMID, nullptr); + } +private: + void* m_shm; + int m_shmid; +}; + #if defined(LOSCFG_USER_TEST_SMOKE) void ItContainer001(void); void ItContainerChroot001(void); @@ -99,6 +150,14 @@ void ItMntContainer006(void); void ItMntContainer007(void); void ItMntContainer008(void); #endif +#if defined(LOSCFG_USER_TEST_IPC_CONTAINER) +void ItIpcContainer001(void); +void ItIpcContainer002(void); +void ItIpcContainer003(void); +void ItIpcContainer004(void); +void ItIpcContainer005(void); +void ItIpcContainer006(void); +#endif #endif #if defined(LOSCFG_USER_TEST_FULL) diff --git a/testsuites/unittest/container/config.gni b/testsuites/unittest/container/config.gni index 772bf450..b1ea1f75 100644 --- a/testsuites/unittest/container/config.gni +++ b/testsuites/unittest/container/config.gni @@ -91,3 +91,14 @@ if (defined(LOSCFG_USER_TEST_MNT_CONTAINER)) { "$TEST_UNITTEST_DIR/container/smoke/It_mnt_container_008.cpp", ] } + +if (defined(LOSCFG_USER_TEST_IPC_CONTAINER)) { + sources_smoke += [ + "$TEST_UNITTEST_DIR/container/smoke/It_ipc_container_001.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_ipc_container_002.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_ipc_container_003.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_ipc_container_004.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_ipc_container_005.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_ipc_container_006.cpp", + ] +} diff --git a/testsuites/unittest/container/smoke/It_ipc_container_001.cpp b/testsuites/unittest/container/smoke/It_ipc_container_001.cpp new file mode 100644 index 00000000..792398e9 --- /dev/null +++ b/testsuites/unittest/container/smoke/It_ipc_container_001.cpp @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2023-2023 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 +#include +#include "It_container_test.h" +using namespace std; + +static int childFunc(void *arg) +{ + int ret; + (void)arg; + mqd_t mqueueChild; + char msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + char mqname[MQUEUE_STANDARD_NAME_LENGTH] = "/testMQueue001"; + const char msgptr[] = "childMsgs"; + struct mq_attr attr = { 0 }; + attr.mq_msgsize = MQUEUE_TEST_SIZE; + attr.mq_maxmsg = MQUEUE_TEST_MAX_MSG; + mqueueChild = mq_open(mqname, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR, &attr); + if (mqueueChild == (mqd_t)-1) { + goto EXIT1; + } + ret = mq_send(mqueueChild, msgptr, strlen(msgptr), 0); + if (ret != 0) { + goto EXIT1; + } + ret = mq_receive(mqueueChild, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + if (ret == -1) { + goto EXIT1; + } + if (strncmp(msgrcd, msgptr, strlen(msgptr)) != 0) { + goto EXIT1; + } + +EXIT1: + if (mqueueChild >= 0) { + ret = mq_close(mqueueChild); + if (ret != 0) { + return EXIT_CODE_ERRNO_1; + } + ret = mq_unlink(mqname); + if (ret != 0) { + return EXIT_CODE_ERRNO_2; + } + } + return EXIT_CODE_ERRNO_7; +} + +void ItIpcContainer001(void) +{ + uint32_t ret; + int status; + int exitCode; + pid_t pid; + mqd_t mqueueParent; + int arg = CHILD_FUNC_ARG; + char *stack = (char *)mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, + -1, 0); + ASSERT_NE(stack, nullptr); + char *stackTop = stack + STACK_SIZE; + char msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + char mqname[MQUEUE_STANDARD_NAME_LENGTH] = "/testMQueue001"; + const char msgptr[] = "parentMsg"; + struct mq_attr attr = { 0 }; + attr.mq_msgsize = MQUEUE_TEST_SIZE; + attr.mq_maxmsg = MQUEUE_TEST_MAX_MSG; + + mqueueParent = mq_open(mqname, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR, NULL); + MQueueFinalizer mQueueFinalizer(mqueueParent, mqname); + + ASSERT_NE(mqueueParent, (mqd_t)-1); + + (void)memset_s(&attr, sizeof(attr), 0, sizeof(attr)); + ret = mq_getattr(mqueueParent, &attr); + ASSERT_EQ(ret, 0); + + attr.mq_flags |= O_NONBLOCK; + ret = mq_setattr(mqueueParent, &attr, NULL); + ASSERT_EQ(ret, 0); + + ret = mq_getattr(mqueueParent, &attr); + ASSERT_EQ(ret, 0); + + ret = mq_send(mqueueParent, msgptr, strlen(msgptr), 0); + ASSERT_EQ(ret, 0); + + pid = clone(childFunc, stackTop, CLONE_NEWIPC | SIGCHLD, &arg); + ASSERT_NE(pid, -1); + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + + exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, EXIT_CODE_ERRNO_7); + + ret = mq_receive(mqueueParent, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ASSERT_NE(ret, -1); + ASSERT_STREQ(msgrcd, msgptr); +} diff --git a/testsuites/unittest/container/smoke/It_ipc_container_002.cpp b/testsuites/unittest/container/smoke/It_ipc_container_002.cpp new file mode 100644 index 00000000..612089fc --- /dev/null +++ b/testsuites/unittest/container/smoke/It_ipc_container_002.cpp @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2023-2023 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 +#include +#include "It_container_test.h" +using namespace std; + +static int childFunc(void *arg) +{ + int ret; + (void)arg; + char msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + char mqname[] = "/testMQueue003"; + const char msgptr[] = "childMsgs"; + struct mq_attr attr = { 0 }; + mqd_t mqueue; + attr.mq_msgsize = MQUEUE_TEST_SIZE; + attr.mq_maxmsg = MQUEUE_TEST_MAX_MSG; + + mqueue = mq_open(mqname, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR, &attr); + if (mqueue == (mqd_t)-1) { + goto EXIT1; + } + ret = mq_send(mqueue, msgptr, strlen(msgptr), 0); + if (ret != 0) { + goto EXIT1; + } + ret = mq_receive(mqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + if (ret != strlen(msgptr)) { + goto EXIT1; + } + if (strncmp(msgrcd, msgptr, strlen(msgptr)) != 0) { + goto EXIT1; + } + +EXIT1: + if (mqueue >= 0) { + ret = mq_close(mqueue); + if (ret != 0) { + return EXIT_CODE_ERRNO_1; + } + ret = mq_unlink(mqname); + if (ret != 0) { + return EXIT_CODE_ERRNO_2; + } + } + return EXIT_CODE_ERRNO_7; +} + +void ItIpcContainer002(void) +{ + uint32_t ret; + int status; + int exitCode; + mqd_t mqueue; + pid_t childPid; + int arg = CHILD_FUNC_ARG; + char *stack = (char *)mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, + -1, 0); + ASSERT_NE(stack, nullptr); + char *stackTop = stack + STACK_SIZE; + struct mq_attr attr = { 0 }; + attr.mq_msgsize = MQUEUE_TEST_SIZE; + attr.mq_maxmsg = MQUEUE_TEST_MAX_MSG; + char msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + char mqname[] = "/testMQueue004"; + const char msgptr[] = "parentMsg"; + std::string containerType = "ipc"; + std::string filePath; + int fd; + int parentPid; + std::string parentlink; + std::string childlink; + + mqueue = mq_open(mqname, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR, NULL); + MQueueFinalizer mQueueFinalizer(mqueue, mqname); + + ASSERT_NE(mqueue, (mqd_t)-1); + + (void)memset_s(&attr, sizeof(attr), 0, sizeof(attr)); + ret = mq_getattr(mqueue, &attr); + ASSERT_EQ(ret, 0); + + attr.mq_flags |= O_NONBLOCK; + ret = mq_setattr(mqueue, &attr, NULL); + ASSERT_EQ(ret, 0); + + ret = mq_getattr(mqueue, &attr); + ASSERT_EQ(ret, 0); + + ret = mq_send(mqueue, msgptr, strlen(msgptr), 0); + ASSERT_EQ(ret, 0); + + childPid = clone(childFunc, stackTop, CLONE_NEWIPC | SIGCHLD, &arg); + ASSERT_NE(childPid, -1); + + parentPid = getpid(); + parentlink = ReadlinkContainer(parentPid, containerType); + childlink = ReadlinkContainer(childPid, containerType); + filePath = GenContainerLinkPath(childPid, containerType); + fd = open(filePath.c_str(), O_RDONLY); + ASSERT_NE(fd, -1); + + ret = setns(fd, CLONE_NEWIPC); + ASSERT_NE(ret, -1); + + ret = close(fd); + ASSERT_NE(ret, -1); + + ret = waitpid(childPid, &status, 0); + ASSERT_EQ(ret, childPid); + + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + + exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, EXIT_CODE_ERRNO_7); +} diff --git a/testsuites/unittest/container/smoke/It_ipc_container_003.cpp b/testsuites/unittest/container/smoke/It_ipc_container_003.cpp new file mode 100644 index 00000000..e28164de --- /dev/null +++ b/testsuites/unittest/container/smoke/It_ipc_container_003.cpp @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2023-2023 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 +#include +#include "It_container_test.h" +using namespace std; + +static int childFunc(void *arg) +{ + int ret; + (void)arg; + char msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + char mqname[] = "/testMQueue005"; + const char msgptr[] = "childMsg"; + struct mq_attr attr = { 0 }; + mqd_t mqueue; + attr.mq_msgsize = MQUEUE_TEST_SIZE; + attr.mq_maxmsg = MQUEUE_TEST_MAX_MSG; + + mqueue = mq_open(mqname, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR, &attr); + if (mqueue == (mqd_t)-1) { + goto EXIT1; + } + ret = mq_send(mqueue, msgptr, strlen(msgptr), 0); + if (ret != 0) { + goto EXIT1; + } + ret = mq_receive(mqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + if (ret != strlen(msgptr)) { + goto EXIT1; + } + if (strncmp(msgrcd, msgptr, strlen(msgptr)) != 0) { + goto EXIT1; + } + +EXIT1: + if (mqueue >= 0) { + ret = mq_close(mqueue); + if (ret != 0) { + return EXIT_CODE_ERRNO_1; + } + ret = mq_unlink(mqname); + if (ret != 0) { + return EXIT_CODE_ERRNO_2; + } + } + return EXIT_CODE_ERRNO_7; +} + +void ItIpcContainer003(void) +{ + int status, exitCode, ret; + int arg = CHILD_FUNC_ARG; + char *stack = (char *)mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, CLONE_STACK_MMAP_FLAG, -1, 0); + ASSERT_NE(stack, nullptr); + char *stackTop = stack + STACK_SIZE; + struct mq_attr attr = { 0 }; + attr.mq_msgsize = MQUEUE_TEST_SIZE; + attr.mq_maxmsg = MQUEUE_TEST_MAX_MSG; + struct sigevent notification; + notification.sigev_notify = 5; /* 5: test data */ + char msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0}; + char mqname[] = "/testMQueue006"; + const char msgptr[] = "parentMsg"; + + ret = unshare(CLONE_NEWIPC); + ASSERT_EQ(ret, 0); + + mqd_t mqueue = mq_open(mqname, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR, &attr); + MQueueFinalizer mQueueFinalizer(mqueue, mqname); + + ASSERT_NE(mqueue, (mqd_t)-1); + + ret = mq_notify(mqueue, ¬ification); + ASSERT_EQ(ret, -1); + ASSERT_EQ(errno, EINVAL); + + notification.sigev_notify = SIGEV_THREAD; + ret = mq_notify(mqueue, ¬ification); + ASSERT_EQ(ret, -1); + ASSERT_EQ(errno, ENOTSUP); + + notification.sigev_notify = SIGEV_NONE; + + ret = mq_notify(-1, ¬ification); + ASSERT_EQ(ret, -1); + ASSERT_EQ(errno, EBADF); + + ret = mq_notify(mqueue, ¬ification); + ASSERT_EQ(ret, 0); + + (void)memset_s(&attr, sizeof(attr), 0, sizeof(attr)); + ret = mq_getattr(mqueue, &attr); + ASSERT_EQ(ret, 0); + + attr.mq_flags |= O_NONBLOCK; + ret = mq_setattr(mqueue, &attr, NULL); + ASSERT_EQ(ret, 0); + + ret = mq_getattr(mqueue, &attr); + ASSERT_EQ(ret, 0); + + ret = mq_send(mqueue, msgptr, strlen(msgptr), 0); + ASSERT_EQ(ret, 0); + + pid_t pid = clone(childFunc, stackTop, CLONE_NEWIPC | SIGCHLD, &arg); + ASSERT_NE(pid, -1); + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + ret = WIFEXITED(status); + ASSERT_NE(pid, 0); + + exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, EXIT_CODE_ERRNO_7); + + ret = mq_notify(mqueue, nullptr); + ASSERT_EQ(ret, 0); + + ret = mq_receive(mqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL); + ASSERT_EQ(ret, strlen(msgptr)); + ASSERT_STREQ(msgrcd, msgptr); +} diff --git a/testsuites/unittest/container/smoke/It_ipc_container_004.cpp b/testsuites/unittest/container/smoke/It_ipc_container_004.cpp new file mode 100644 index 00000000..7a938d94 --- /dev/null +++ b/testsuites/unittest/container/smoke/It_ipc_container_004.cpp @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2023-2023 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_container_test.h" +using namespace std; + +static const char *containerType = "ipc"; + +struct shared_use_st { + char test[SHM_TEST_DATA_SIZE]; +}; + +static int childFunc1(void *arg) +{ + struct shared_use_st *shared = NULL; + const char testBuf[] = "child test shm"; + int ret; + (void)arg; + + int shmid = shmget((key_t)SHM_TEST_KEY1, sizeof(struct shared_use_st), SHM_TEST_OPEN_PERM | IPC_CREAT); + if (shmid == -1) { + return EXIT_CODE_ERRNO_1; + } + + void *shm = shmat(shmid, 0, 0); + if (shm == reinterpret_cast(-1)) { + shmctl(shmid, IPC_RMID, 0); + return EXIT_CODE_ERRNO_2; + } + shared = (struct shared_use_st *)shm; + ret = strncmp(shared->test, testBuf, strlen(testBuf)); + if (ret != 0) { + shmdt(shm); + shmctl(shmid, IPC_RMID, 0); + return EXIT_CODE_ERRNO_3; + } + ret = shmdt(shm); + if (ret == -1) { + shmctl(shmid, IPC_RMID, 0); + return EXIT_CODE_ERRNO_4; + } + return 0; +} + +static int childFunc(void *arg) +{ + const char testBuf[] = "parent test shm"; + const char testBuf1[] = "child test shm"; + int ret, status, pid, exitCode; + (void)arg; + char *stack = (char *)mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, CLONE_STACK_MMAP_FLAG, -1, 0); + if (stack == nullptr) { + return EXIT_CODE_ERRNO_17; + } + char *stackTop = stack + STACK_SIZE; + auto linkBuffer = ReadlinkContainer(getpid(), containerType); + + int shmid = shmget((key_t)SHM_TEST_KEY1, sizeof(struct shared_use_st), SHM_TEST_OPEN_PERM | IPC_CREAT); + if (shmid == -1) { + return EXIT_CODE_ERRNO_1; + } + + void *shm = shmat(shmid, 0, 0); + if (shm == reinterpret_cast(-1)) { + shmctl(shmid, IPC_RMID, 0); + return EXIT_CODE_ERRNO_2; + } + + struct shared_use_st *shared = (struct shared_use_st *)shm; + ret = strncmp(shared->test, testBuf, strlen(testBuf)); + if (ret == 0) { + ret = EXIT_CODE_ERRNO_3; + goto EXIT; + } + + ret = memcpy_s(shared->test, sizeof(struct shared_use_st), testBuf1, sizeof(testBuf1)); + if (ret != 0) { + ret = EXIT_CODE_ERRNO_4; + goto EXIT; + } + + pid = clone(childFunc1, stackTop, SIGCHLD, &arg); + if (pid == -1) { + ret = EXIT_CODE_ERRNO_5; + goto EXIT; + } + + ret = waitpid(pid, &status, 0); + if (ret != pid) { + ret = EXIT_CODE_ERRNO_6; + goto EXIT; + } + + ret = WIFEXITED(status); + if (ret == 0) { + ret = EXIT_CODE_ERRNO_7; + goto EXIT; + } + + exitCode = WEXITSTATUS(status); + if (exitCode != 0) { + ret = EXIT_CODE_ERRNO_8; + goto EXIT; + } + + ret = shmdt(shm); + if (ret == -1) { + shmctl(shmid, IPC_RMID, 0); + return EXIT_CODE_ERRNO_9; + } + + ret = shmctl(shmid, IPC_RMID, 0); + if (ret == -1) { + return EXIT_CODE_ERRNO_10; + } + + return 0; +EXIT: + shmdt(shm); + shmctl(shmid, IPC_RMID, 0); + return ret; +} + +void ItIpcContainer004(void) +{ + const char testBuf[] = "parent test shm"; + int pid, exitCode, status, ret; + void *shm = NULL; + struct shmid_ds ds = {}; + struct shminfo info = {}; + + int arg = CHILD_FUNC_ARG; + char *stack = (char *)mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, CLONE_STACK_MMAP_FLAG, -1, 0); + ASSERT_NE(stack, nullptr); + char *stackTop = stack + STACK_SIZE; + + int shmid = shmget((key_t)SHM_TEST_KEY1, sizeof(struct shared_use_st), SHM_TEST_OPEN_PERM | IPC_CREAT); + ShmFinalizer ShmFinalizer(shm, shmid); + ASSERT_NE(shmid, -1); + + shm = shmat(shmid, 0, 0); + ASSERT_NE((int)shm, -1); + + struct shared_use_st *shared = (struct shared_use_st *)shm; + ret = memcpy_s(shared->test, sizeof(struct shared_use_st), testBuf, sizeof(testBuf)); + ASSERT_EQ(ret, 0); + + pid = clone(childFunc, stackTop, CLONE_NEWIPC | SIGCHLD, &arg); + ASSERT_NE(pid, -1); + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + + exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, 0); + + ret = shmctl(shmid, IPC_STAT, &ds); + ASSERT_EQ(ret, 0); + ASSERT_EQ(ds.shm_segsz, PAGE_SIZE); + ASSERT_EQ(ds.shm_nattch, 1); + ASSERT_EQ(ds.shm_cpid, getpid()); + ASSERT_EQ(ds.shm_lpid, getpid()); + ASSERT_EQ(ds.shm_perm.uid, getuid()); + + ret = shmctl(shmid, SHM_STAT, &ds); + ASSERT_NE(ret, -1); + ASSERT_NE(ret, 0); + + ds.shm_perm.uid = getuid(); + ds.shm_perm.gid = getgid(); + ds.shm_perm.mode = 0; + ret = shmctl(shmid, IPC_SET, &ds); + ASSERT_EQ(ret, 0); + + ret = shmctl(shmid, IPC_INFO, (struct shmid_ds *)&info); + ASSERT_EQ(ret, 192); /* 192: test value */ + ASSERT_EQ(info.shmmax, 0x1000000); /* 0x1000000: Shared memory information */ + ASSERT_EQ(info.shmmin, 1); /* 1: Shared memory information */ + ASSERT_EQ(info.shmmni, 192); /* 192: Shared memory information */ + ASSERT_EQ(info.shmseg, 128); /* 128: Shared memory information */ + ASSERT_EQ(info.shmall, 0x1000); /* 0x1000: Shared memory information */ + + ret = shmdt(shm); + ASSERT_NE(ret, -1); + + ret = shmctl(shmid, IPC_RMID, NULL); + ASSERT_EQ(ret, 0); +} diff --git a/testsuites/unittest/container/smoke/It_ipc_container_005.cpp b/testsuites/unittest/container/smoke/It_ipc_container_005.cpp new file mode 100644 index 00000000..8f65f4c7 --- /dev/null +++ b/testsuites/unittest/container/smoke/It_ipc_container_005.cpp @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2023-2023 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_container_test.h" +using namespace std; + +static const char testBuf[] = "test shm"; +struct shared_use_st { + char test[SHM_TEST_DATA_SIZE]; +}; + +static int childFunc(void *arg) +{ + struct shared_use_st *shared = NULL; + int ret; + (void)arg; + char *containerType = "ipc"; + auto linkBuffer = ReadlinkContainer(getpid(), containerType); + + ret = unshare(CLONE_NEWIPC); + if (ret != 0) { + return EXIT_CODE_ERRNO_1; + } + + auto linkBuffer1 = ReadlinkContainer(getpid(), containerType); + ret = linkBuffer.compare(linkBuffer1); + if (ret == 0) { + return EXIT_CODE_ERRNO_2; + } + + int shmid = shmget((key_t)SHM_TEST_KEY1, sizeof(struct shared_use_st), SHM_TEST_OPEN_PERM | IPC_CREAT); + if (shmid == -1) { + return EXIT_CODE_ERRNO_3; + } + + void *shm = shmat(shmid, 0, 0); + if (shm == reinterpret_cast(-1)) { + shmctl(shmid, IPC_RMID, 0); + return EXIT_CODE_ERRNO_4; + } + + shared = (struct shared_use_st *)shm; + ret = strncmp(shared->test, testBuf, strlen(testBuf)); + if (ret == 0) { + shmdt(shm); + shmctl(shmid, IPC_RMID, 0); + return EXIT_CODE_ERRNO_5; + } + + ret = shmdt(shm); + if (ret == -1) { + shmctl(shmid, IPC_RMID, 0); + return EXIT_CODE_ERRNO_6; + } + + ret = shmctl(shmid, IPC_RMID, 0); + if (ret == -1) { + return EXIT_CODE_ERRNO_7; + } + return 0; +} + +static int testChild(void *arg) +{ + (void)arg; + int ret; + struct shared_use_st *shared = NULL; + int status; + int exitCode; + int pid; + + char *stack = (char *)mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, + -1, 0); + if (stack == nullptr) { + return EXIT_CODE_ERRNO_17; + } + char *stackTop = stack + STACK_SIZE; + + int shmid = shmget((key_t)SHM_TEST_KEY1, sizeof(struct shared_use_st), SHM_TEST_OPEN_PERM | IPC_CREAT); + if (shmid == -1) { + return EXIT_CODE_ERRNO_8; + } + + void *shm = shmat(shmid, 0, 0); + if (shm == reinterpret_cast(-1)) { + shmctl(shmid, IPC_RMID, 0); + return EXIT_CODE_ERRNO_9; + } + + shared = (struct shared_use_st *)shm; + ret = memcpy_s(shared->test, sizeof(struct shared_use_st), testBuf, sizeof(testBuf)); + if (ret != 0) { + shmdt(shm); + shmctl(shmid, IPC_RMID, 0); + return EXIT_CODE_ERRNO_10; + } + + pid = clone(childFunc, stackTop, SIGCHLD, &arg); + if (pid == -1) { + shmdt(shm); + shmctl(shmid, IPC_RMID, 0); + return EXIT_CODE_ERRNO_11; + } + + ret = waitpid(pid, &status, 0); + if (ret != pid) { + shmdt(shm); + shmctl(shmid, IPC_RMID, 0); + return EXIT_CODE_ERRNO_12; + } + + ret = WIFEXITED(status); + if (ret == 0) { + shmdt(shm); + shmctl(shmid, IPC_RMID, 0); + return EXIT_CODE_ERRNO_13; + } + + exitCode = WEXITSTATUS(status); + if (exitCode != 0) { + shmdt(shm); + shmctl(shmid, IPC_RMID, 0); + return EXIT_CODE_ERRNO_14; + } + + ret = shmdt(shm); + if (ret == -1) { + shmctl(shmid, IPC_RMID, 0); + return EXIT_CODE_ERRNO_15; + } + + ret = shmctl(shmid, IPC_RMID, 0); + if (ret == -1) { + return EXIT_CODE_ERRNO_16; + } + return 0; +} + +void ItIpcContainer005(void) +{ + int ret; + int status; + char *stack = (char *)mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, + -1, 0); + ASSERT_NE(stack, nullptr); + + char *stackTop = stack + STACK_SIZE; + + int arg = CHILD_FUNC_ARG; + auto pid = clone(testChild, stackTop, CLONE_NEWIPC | SIGCHLD, &arg); + ASSERT_NE(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); +} diff --git a/testsuites/unittest/container/smoke/It_ipc_container_006.cpp b/testsuites/unittest/container/smoke/It_ipc_container_006.cpp new file mode 100644 index 00000000..d8524513 --- /dev/null +++ b/testsuites/unittest/container/smoke/It_ipc_container_006.cpp @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2023-2023 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_container_test.h" +using namespace std; + +static const char testBuf[] = "test shm"; +static const char *containerType = "ipc"; +struct shared_use_st { + char test[SHM_TEST_DATA_SIZE]; +}; + +static int childFunc1(void *arg) +{ + struct shared_use_st *shared = NULL; + int ret; + (void)arg; + const int sleep_num = 3; /* 3: delay */ + + int shmid = shmget((key_t)SHM_TEST_KEY1, sizeof(struct shared_use_st), SHM_TEST_OPEN_PERM | IPC_CREAT); + if (shmid == -1) { + return EXIT_CODE_ERRNO_1; + } + + void *shm = shmat(shmid, 0, 0); + if (shm == reinterpret_cast(-1)) { + shmctl(shmid, IPC_RMID, 0); + return EXIT_CODE_ERRNO_2; + } + shared = (struct shared_use_st *)shm; + sleep(sleep_num); + ret = strncmp(shared->test, testBuf, strlen(testBuf)); + if (ret != 0) { + shmdt(shm); + shmctl(shmid, IPC_RMID, 0); + return EXIT_CODE_ERRNO_3; + } + + ret = shmdt(shm); + if (ret == -1) { + shmctl(shmid, IPC_RMID, 0); + return EXIT_CODE_ERRNO_4; + } + return 0; +} + +static int childFunc(void *arg) +{ + struct shared_use_st *shared = NULL; + int ret; + (void)arg; + int status; + int exitCode; + const int sleep_num = 1; + auto linkBuffer = ReadlinkContainer(getpid(), containerType); + char *stack = (char *)mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, + -1, 0); + if (stack == nullptr) { + return EXIT_CODE_ERRNO_17; + } + char *stackTop = stack + STACK_SIZE; + + auto pid = clone(childFunc1, stackTop, CLONE_NEWIPC | SIGCHLD, &arg); + if (pid == -1) { + return EXIT_CODE_ERRNO_6; + } + + std::string filePath = GenContainerLinkPath(pid, containerType); + int fd = open(filePath.c_str(), O_RDONLY); + if (fd == -1) { + return EXIT_CODE_ERRNO_7; + } + sleep(sleep_num); + ret = setns(fd, CLONE_NEWIPC); + if (ret == -1) { + close(fd); + return EXIT_CODE_ERRNO_8; + } + close(fd); + auto linkBuffer1 = ReadlinkContainer(getpid(), containerType); + auto linkBuffer2 = ReadlinkContainer(pid, containerType); + ret = linkBuffer.compare(linkBuffer1); + if (ret == 0) { + return EXIT_CODE_ERRNO_9; + } + ret = linkBuffer1.compare(linkBuffer2); + if (ret != 0) { + return EXIT_CODE_ERRNO_10; + } + + int shmid = shmget((key_t)SHM_TEST_KEY1, sizeof(struct shared_use_st), SHM_TEST_OPEN_PERM | IPC_CREAT); + if (shmid == -1) { + return EXIT_CODE_ERRNO_11; + } + + void *shm = shmat(shmid, 0, 0); + if (shm == reinterpret_cast(-1)) { + shmctl(shmid, IPC_RMID, 0); + return EXIT_CODE_ERRNO_12; + } + + shared = (struct shared_use_st *)shm; + + ret = memcpy_s(shared->test, sizeof(struct shared_use_st), testBuf, sizeof(testBuf)); + if (ret != 0) { + shmctl(shmid, IPC_RMID, 0); + return EXIT_CODE_ERRNO_13; + } + + ret = waitpid(pid, &status, 0); + if (ret != pid) { + shmdt(shm); + shmctl(shmid, IPC_RMID, 0); + return EXIT_CODE_ERRNO_14; + } + + exitCode = WEXITSTATUS(status); + if (exitCode != 0) { + shmdt(shm); + shmctl(shmid, IPC_RMID, 0); + return EXIT_CODE_ERRNO_15; + } + + ret = shmdt(shm); + if (ret == -1) { + shmctl(shmid, IPC_RMID, 0); + return EXIT_CODE_ERRNO_16; + } + + ret = shmctl(shmid, IPC_RMID, 0); + if (ret == -1) { + return EXIT_CODE_ERRNO_255; + } + return 0; +} + +void ItIpcContainer006(void) +{ + int ret; + int status; + char *stack = (char *)mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, + -1, 0); + ASSERT_NE(stack, nullptr); + char *stackTop = stack + STACK_SIZE; + + int arg = CHILD_FUNC_ARG; + auto pid = clone(childFunc, stackTop, CLONE_NEWIPC | SIGCHLD, &arg); + ASSERT_NE(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); +} diff --git a/testsuites/unittest/container/smoke/It_mnt_container_004.cpp b/testsuites/unittest/container/smoke/It_mnt_container_004.cpp index 49e9f4b2..98c02220 100644 --- a/testsuites/unittest/container/smoke/It_mnt_container_004.cpp +++ b/testsuites/unittest/container/smoke/It_mnt_container_004.cpp @@ -34,7 +34,6 @@ static int ChildFunc(void *arg) { int ret; int value = *((int *)arg); - if (value != CHILD_FUNC_ARG) { return EXIT_CODE_ERRNO_1; } diff --git a/testsuites/unittest/process/fs/It_process_fs_test.h b/testsuites/unittest/process/fs/It_process_fs_test.h index 974bc40a..f7ac060a 100644 --- a/testsuites/unittest/process/fs/It_process_fs_test.h +++ b/testsuites/unittest/process/fs/It_process_fs_test.h @@ -54,4 +54,5 @@ extern void ItProcessFs012(void); extern void ItProcessFs013(void); extern void ItProcessFs014(void); extern void ItProcessFs015(void); +extern void ItProcessFs021(void); #endif diff --git a/testsuites/unittest/process/fs/config.gni b/testsuites/unittest/process/fs/config.gni index 8de233fe..8da93a5b 100644 --- a/testsuites/unittest/process/fs/config.gni +++ b/testsuites/unittest/process/fs/config.gni @@ -61,6 +61,7 @@ process_fs_sources_smoke = [ "$TEST_UNITTEST_DIR/process/fs/smoke/It_process_fs_013.cpp", "$TEST_UNITTEST_DIR/process/fs/smoke/It_process_fs_014.cpp", "$TEST_UNITTEST_DIR/process/fs/smoke/It_process_fs_015.cpp", + "$TEST_UNITTEST_DIR/process/fs/smoke/It_process_fs_021.cpp", ] process_fs_sources_full = [] diff --git a/testsuites/unittest/process/fs/process_fs_test.cpp b/testsuites/unittest/process/fs/process_fs_test.cpp index 9476be8b..737da9ba 100644 --- a/testsuites/unittest/process/fs/process_fs_test.cpp +++ b/testsuites/unittest/process/fs/process_fs_test.cpp @@ -141,6 +141,18 @@ HWTEST_F(ProcessFsTest, ItProcessFs007, TestSize.Level0) ItProcessFs007(); } +/** +* @tc.name: Process_fs_Test_008 +* @tc.desc: Process mount directory test +* @tc.type: FUNC +* @tc.require: issueI6APW2 +* @tc.author: +*/ +HWTEST_F(ProcessFsTest, ItProcessFs008, TestSize.Level0) +{ + ItProcessFs008(); +} + /** * @tc.name: Process_fs_Test_010 * @tc.desc: Process mount directory test @@ -200,5 +212,17 @@ HWTEST_F(ProcessFsTest, ItProcessFs015, TestSize.Level0) { ItProcessFs015(); } + +/** +* @tc.name: Process_fs_Test_021 +* @tc.desc: Process mount directory test +* @tc.type: FUNC +* @tc.require: issueI6AVMY +* @tc.author: +*/ +HWTEST_F(ProcessFsTest, ItProcessFs021, TestSize.Level0) +{ + ItProcessFs021(); +} #endif } diff --git a/testsuites/unittest/process/fs/smoke/It_process_fs_021.cpp b/testsuites/unittest/process/fs/smoke/It_process_fs_021.cpp new file mode 100644 index 00000000..ed36886b --- /dev/null +++ b/testsuites/unittest/process/fs/smoke/It_process_fs_021.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2023-2023 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 +#include +#include +#include +#include +#include +#include +#include "It_process_fs_test.h" + +void ItProcessFs021(void) +{ + auto path = GenProcPidContainerPath(getpid(), "ipc"); + std::vector buf(PATH_MAX); + auto nbytes = readlink(path.c_str(), buf.data(), PATH_MAX); + ASSERT_NE(nbytes, -1); + + std::regex reg("'ipc:\\[[0-9]+\\]'"); + bool ret = std::regex_match(buf.data(), reg); + ASSERT_EQ(ret, true); +}