diff --git a/compat/posix/include/mqueue.h b/compat/posix/include/mqueue.h index e6ef8727785fcbac16fb21956ec7e43b6ddc3b7d..551dd06a743c5463f3cb271ea5a366c4dbddd11a 100644 --- a/compat/posix/include/mqueue.h +++ b/compat/posix/include/mqueue.h @@ -428,6 +428,7 @@ extern ssize_t mq_timedreceive(mqd_t personal, char *msg, size_t msgLen, extern void MqueueRefer(int sysFd); extern int OsMqNotify(mqd_t personal, const struct sigevent *sigev); +extern VOID OsMqueueCBDestroy(struct mqarray *queueTable); #ifdef __cplusplus #if __cplusplus diff --git a/compat/posix/src/mqueue.c b/compat/posix/src/mqueue.c index eded1683c3e4186422353c10a6730935fd5ce56a..ab22c404bf79892c1d582d681583d9c0c8b6f12b 100644 --- a/compat/posix/src/mqueue.c +++ b/compat/posix/src/mqueue.c @@ -946,4 +946,19 @@ OUT_UNLOCK: ERROUT: return -1; } + +VOID OsMqueueCBDestroy(struct mqarray *queueTable) +{ + if (queueTable == NULL) { + return; + } + + for (UINT32 index = 0; index < LOSCFG_BASE_IPC_QUEUE_LIMIT; index++) { + struct mqarray *mqueueCB = &(queueTable[index]); + if (mqueueCB->mq_name == NULL) { + continue; + } + (VOID)DoMqueueClose(mqueueCB->mq_personal); + } +} #endif diff --git a/fs/proc/include/internal.h b/fs/proc/include/internal.h index fb822d9bf07013d34f058bf20a6910b6d178cc36..861d12d8eefa238334c1a02db5501239a741102b 100644 --- a/fs/proc/include/internal.h +++ b/fs/proc/include/internal.h @@ -77,6 +77,10 @@ void ProcFsCacheInit(void); void ProcFdInit(void); +#ifdef LOSCFG_KERNEL_CONTAINER +void *ProcfsContainerGet(int fd, unsigned int *containerType); +#endif + #ifdef __cplusplus #if __cplusplus } diff --git a/fs/proc/include/proc_fs.h b/fs/proc/include/proc_fs.h index 89e55671c79329c43f10287f784d2a8aa227e1c3..022d92acf4292d62e144b35ec3be0a858a5e20b0 100644 --- a/fs/proc/include/proc_fs.h +++ b/fs/proc/include/proc_fs.h @@ -297,6 +297,7 @@ extern struct ProcDirEntry *ProcCreateData(const char *name, mode_t mode, struct */ extern void ProcFsInit(void); +extern struct ProcDirEntry *VnodeToEntry(struct Vnode *node); #ifdef __cplusplus #if __cplusplus } diff --git a/fs/proc/os_adapt/proc_vfs.c b/fs/proc/os_adapt/proc_vfs.c index dd467b3a77e94ed5fc5f1cde626ca1c222a6e101..f5e34b979c7fd88cdc0a41dd63954e0c259b9602 100644 --- a/fs/proc/os_adapt/proc_vfs.c +++ b/fs/proc/os_adapt/proc_vfs.c @@ -45,7 +45,7 @@ static struct VnodeOps g_procfsVops; static struct file_operations_vfs g_procfsFops; -static struct ProcDirEntry *VnodeToEntry(struct Vnode *node) +struct ProcDirEntry *VnodeToEntry(struct Vnode *node) { return (struct ProcDirEntry *)(node->data); } diff --git a/fs/proc/os_adapt/process_proc.c b/fs/proc/os_adapt/process_proc.c index 962cf6c276275dca5efaa213b65ad6ce4dd8d010..d39580244a731873c96754c2e52fe20a6839ea24 100644 --- a/fs/proc/os_adapt/process_proc.c +++ b/fs/proc/os_adapt/process_proc.c @@ -120,6 +120,38 @@ static ssize_t ProcessContainerReadLink(struct ProcDirEntry *entry, char *buffer static const struct ProcFileOperations PID_CONTAINER_FOPS = { .readLink = ProcessContainerReadLink, }; + +void *ProcfsContainerGet(int fd, unsigned int *containerType) +{ + if ((fd <= 0) || (containerType == NULL)) { + return NULL; + } + + VnodeHold(); + struct Vnode *vnode = VnodeFind(fd); + if (vnode == NULL) { + VnodeDrop(); + return NULL; + } + + struct ProcDirEntry *entry = VnodeToEntry(vnode); + if (entry == NULL) { + VnodeDrop(); + return NULL; + } + + struct ProcessData *data = (struct ProcessData *)entry->data; + if (data == NULL) { + VnodeDrop(); + return NULL; + } + + void *processCB = (void *)ProcGetProcessCB(data); + *containerType = data->type; + VnodeDrop(); + return processCB; +} + #endif /* LOSCFG_KERNEL_CONTAINER */ static int ProcessMemInfoRead(struct SeqBuf *seqBuf, LosProcessCB *pcb) diff --git a/fs/proc/src/proc_file.c b/fs/proc/src/proc_file.c index 739365b6136da61b60d156b367b1b638dba818d5..c78831e0cfa4f8edd5742306218e17802b96c893 100644 --- a/fs/proc/src/proc_file.c +++ b/fs/proc/src/proc_file.c @@ -351,11 +351,12 @@ static struct ProcDirEntry *ProcCreateFile(struct ProcDirEntry *parent, const ch } pn->procFileOps = procFileOps; + pn->type = VNODE_TYPE_REG; +#ifdef LOSCFG_PROC_PROCESS_DIR if (S_ISLNK(mode)) { - pn->type = VNODE_TYPE_LNK; - } else { - pn->type = VNODE_TYPE_REG; + pn->type = VNODE_TYPE_VIR_LNK; } +#endif ret = ProcAddNode(parent, pn); if (ret != 0) { free(pn->pf); @@ -390,7 +391,7 @@ static void ProcEntryClearVnode(struct ProcDirEntry *entry) } if (VnodeFree(item) != LOS_OK) { - PRINT_ERR("ProcEntryClearVnode free failed, entry: %s : 0x%x \n", entry->name, item); + PRINT_ERR("ProcEntryClearVnode free failed, entry: %s\n", entry->name); } } VnodeDrop(); diff --git a/fs/vfs/include/vnode.h b/fs/vfs/include/vnode.h index 8a1b44205424032f4cf0045a5c0af13f0016cbd9..95afde6cecbdea0153ce902d425757376932dcef 100644 --- a/fs/vfs/include/vnode.h +++ b/fs/vfs/include/vnode.h @@ -101,6 +101,9 @@ enum VnodeType { VNODE_TYPE_BCHR, /* block char mix device */ VNODE_TYPE_FIFO, /* pipe */ VNODE_TYPE_LNK, /* link */ +#ifdef LOSCFG_PROC_PROCESS_DIR + VNODE_TYPE_VIR_LNK, /* virtual link */ +#endif }; struct fs_dirent_s; @@ -189,4 +192,7 @@ LIST_HEAD* GetVnodeActiveList(void); LIST_HEAD* GetVnodeVirtualList(void); int VnodeClearCache(void); struct Vnode *GetCurrRootVnode(void); +#ifdef LOSCFG_PROC_PROCESS_DIR +struct Vnode *VnodeFind(int fd); +#endif #endif /* !_VNODE_H_ */ diff --git a/fs/vfs/vnode.c b/fs/vfs/vnode.c index ed15610d518cb53e8a7191b2ef12da80ee2edb59..b8b513dcc58ed869ed11ad4e5374163896a90409 100644 --- a/fs/vfs/vnode.c +++ b/fs/vfs/vnode.c @@ -716,7 +716,8 @@ void VnodeMemoryDump(void) PRINTK("Vnode memory size = %d(B)\n", vnodeCount * sizeof(struct Vnode)); } -struct Vnode *GetVnode(INT32 fd) +#ifdef LOSCFG_PROC_PROCESS_DIR +struct Vnode *VnodeFind(int fd) { INT32 sysFd; @@ -734,6 +735,7 @@ struct Vnode *GetVnode(INT32 fd) return files_get_openfile((int)sysFd); } +#endif LIST_HEAD* GetVnodeFreeList() { diff --git a/kernel/base/container/los_container.c b/kernel/base/container/los_container.c index d0ef1f1fd1528be28402b54250b7f58d8835294b..da0911581a8dae53e2b4d4f9e5c70e56c5de9ec0 100644 --- a/kernel/base/container/los_container.c +++ b/kernel/base/container/los_container.c @@ -29,6 +29,7 @@ */ #include "los_container_pri.h" #include "los_process_pri.h" +#include "internal.h" #ifdef LOSCFG_KERNEL_CONTAINER STATIC Container g_rootContainer; @@ -44,7 +45,7 @@ VOID OsContainerInitSystemProcess(LosProcessCB *processCB) processCB->container = &g_rootContainer; LOS_AtomicInc(&processCB->container->rc); #ifdef LOSCFG_PID_CONTAINER - (VOID)OsAllocSpecifiedVpidUnsafe(processCB->processID, processCB, NULL); + (VOID)OsAllocSpecifiedVpidUnsafe(processCB->processID, processCB->container->pidContainer, processCB, NULL); #endif return; } @@ -194,7 +195,7 @@ VOID OsContainersDestroy(LosProcessCB *processCB) #endif #ifdef LOSCFG_TIME_CONTAINER - OsTimeContainerDestroy(processCB); + OsTimeContainerDestroy(processCB->container); #endif #ifndef LOSCFG_PID_CONTAINER @@ -205,6 +206,45 @@ VOID OsContainersDestroy(LosProcessCB *processCB) #endif } +STATIC VOID DeInitContainers(UINT32 flags, Container *container, LosProcessCB *processCB) +{ + UINT32 intSave; + if (container == NULL) { + return; + } + +#ifdef LOSCFG_PID_CONTAINER + SCHEDULER_LOCK(intSave); + if ((flags & CLONE_NEWPID) != 0) { + OsPidContainerDestroy(container, processCB); + } else { + OsPidContainerDestroy(container, NULL); + } + SCHEDULER_UNLOCK(intSave); +#endif + +#ifdef LOSCFG_UTS_CONTAINER + OsUtsContainerDestroy(container); +#endif +#ifdef LOSCFG_MNT_CONTAINER + OsMntContainerDestroy(container); +#endif +#ifdef LOSCFG_IPC_CONTAINER + OsIpcContainerDestroy(container); +#endif + +#ifdef LOSCFG_TIME_CONTAINER + OsTimeContainerDestroy(container); +#endif + + SCHEDULER_LOCK(intSave); + LOS_AtomicDec(&container->rc); + if (LOS_AtomicRead(&container->rc) == 0) { + (VOID)LOS_MemFree(m_aucSysMem1, container); + } + SCHEDULER_UNLOCK(intSave); +} + UINT32 OsGetContainerID(Container *container, ContainerType type) { if (container == NULL) { @@ -242,90 +282,147 @@ UINT32 OsGetContainerID(Container *container, ContainerType type) return OS_INVALID_VALUE; } -STATIC VOID UnshareDeInitContainer(UINT32 flags, Container *container) +STATIC UINT32 UnshareCreateNewContainers(UINT32 flags, LosProcessCB *curr, Container *newContainer) { - UINT32 intSave; - if (container == NULL) { - return; - } - + UINT32 ret = LOS_OK; #ifdef LOSCFG_PID_CONTAINER - UnshareDeInitPidContainer(container); + ret = OsUnsharePidContainer(flags, curr, newContainer); + if (ret != LOS_OK) { + return ret; + } #endif - #ifdef LOSCFG_UTS_CONTAINER - if ((flags & CLONE_NEWUTS) != 0) { - OsUtsContainerDestroy(container); + ret = OsUnshareUtsContainer(flags, curr, newContainer); + if (ret != LOS_OK) { + return ret; } #endif #ifdef LOSCFG_MNT_CONTAINER - if ((flags & CLONE_NEWNS) != 0) { - OsMntContainerDestroy(container); + ret = OsUnshareMntContainer(flags, curr, newContainer); + if (ret != LOS_OK) { + return ret; } #endif #ifdef LOSCFG_IPC_CONTAINER - if ((flags & CLONE_NEWIPC) != 0) { - OsIpcContainerDestroy(container); + ret = OsUnshareIpcContainer(flags, curr, newContainer); + if (ret != LOS_OK) { + return ret; } #endif - #ifdef LOSCFG_TIME_CONTAINER - UnshareDeInitTimeContainer(container); + ret = OsUnshareTimeContainer(flags, curr, newContainer); + if (ret != LOS_OK) { + return ret; + } #endif + return ret; +} - SCHEDULER_LOCK(intSave); - LOS_AtomicDec(&container->rc); - if (LOS_AtomicRead(&container->rc) == 0) { - (VOID)LOS_MemFree(m_aucSysMem1, container); +INT32 OsUnshare(UINT32 flags) +{ + UINT32 ret; + UINT32 intSave; + LosProcessCB *curr = OsCurrProcessGet(); + Container *oldContainer = curr->container; + UINT32 unshareFlags = CLONE_NEWPID | CLONE_NEWTIME | CLONE_NEWUTS | CLONE_NEWNS | CLONE_NEWIPC; + + if (!(flags & unshareFlags) || ((flags & (~unshareFlags)) != 0)) { + return -EINVAL; + } + + Container *newContainer = CreateContainer(); + if (newContainer == NULL) { + return -ENOMEM; } + + ret = UnshareCreateNewContainers(flags, curr, newContainer); + if (ret != LOS_OK) { + goto EXIT; + } + + SCHEDULER_LOCK(intSave); + oldContainer = curr->container; + curr->container = newContainer; SCHEDULER_UNLOCK(intSave); + + DeInitContainers(flags, oldContainer, NULL); + return LOS_OK; + +EXIT: + DeInitContainers(flags, newContainer, NULL); + return -ret; } -STATIC UINT32 CreateNewContainers(UINT32 flags, LosProcessCB *curr, Container *newContainer) +STATIC UINT32 SetNsGetFlagByContainerType(UINT32 containerType) +{ + if (containerType >= (UINT32)CONTAINER_MAX) { + return 0; + } + ContainerType type = (ContainerType)containerType; + switch (type) { + case PID_CONTAINER: + case PID_CHILD_CONTAINER: + return CLONE_NEWPID; + case UTS_CONTAINER: + return CLONE_NEWUTS; + case MNT_CONTAINER: + return CLONE_NEWNS; + case IPC_CONTAINER: + return CLONE_NEWIPC; + case TIME_CONTAINER: + case TIME_CHILD_CONTAINER: + return CLONE_NEWTIME; + default: + break; + } + return 0; +} + +STATIC UINT32 SetNsCreateNewContainers(UINT32 flags, Container *newContainer, Container *container) { UINT32 ret = LOS_OK; #ifdef LOSCFG_PID_CONTAINER - ret = OsUnsharePidContainer(flags, curr, newContainer); + ret = OsSetNsPidContainer(flags, container, newContainer); if (ret != LOS_OK) { return ret; } #endif #ifdef LOSCFG_UTS_CONTAINER - ret = OsUnshareUtsContainer(flags, curr, newContainer); + ret = OsSetNsUtsContainer(flags, container, newContainer); if (ret != LOS_OK) { return ret; } #endif #ifdef LOSCFG_MNT_CONTAINER - ret = OsUnshareMntContainer(flags, curr, newContainer); + ret = OsSetNsMntContainer(flags, container, newContainer); if (ret != LOS_OK) { return ret; } #endif #ifdef LOSCFG_IPC_CONTAINER - ret = OsUnshareIpcContainer(flags, curr, newContainer); + ret = OsSetNsIpcContainer(flags, container, newContainer); if (ret != LOS_OK) { return ret; } #endif #ifdef LOSCFG_TIME_CONTAINER - ret = OsUnshareTimeContainer(flags, curr, newContainer); + ret = OsSetNsTimeContainer(flags, container, newContainer); if (ret != LOS_OK) { return ret; } #endif - return ret; + return LOS_OK; } -INT32 OsUnshare(UINT32 flags) +INT32 OsSetNs(INT32 fd, INT32 type) { - UINT32 ret; UINT32 intSave; + UINT32 typeMask = CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWPID | CLONE_NEWIPC | CLONE_NEWTIME; + UINT32 containerType = 0; + UINT32 flag = (UINT32)(type & typeMask); LosProcessCB *curr = OsCurrProcessGet(); - Container *oldContainer = curr->container; - UINT32 unshareFlags = CLONE_NEWPID | CLONE_NEWTIME | CLONE_NEWUTS | CLONE_NEWNS | CLONE_NEWIPC; - if (!(flags & unshareFlags) || ((flags & (~unshareFlags)) != 0)) { + if (((type & (~typeMask)) != 0)) { return -EINVAL; } @@ -334,21 +431,42 @@ INT32 OsUnshare(UINT32 flags) return -ENOMEM; } - ret = CreateNewContainers(flags, curr, newContainer); + LosProcessCB *processCB = (LosProcessCB *)ProcfsContainerGet(fd, &containerType); + if (processCB == NULL) { + (VOID)LOS_MemFree(m_aucSysMem1, newContainer); + return -EBADF; + } + + SCHEDULER_LOCK(intSave); + Container *targetContainer = processCB->container; + if (targetContainer == NULL) { + SCHEDULER_UNLOCK(intSave); + return -EBADF; + } + + if (flag == 0) { + flag = SetNsGetFlagByContainerType(containerType); + } + + if ((flag == 0) || (flag != SetNsGetFlagByContainerType(containerType)) || (targetContainer == curr->container)) { + SCHEDULER_UNLOCK(intSave); + return -EBADF; + } + + UINT32 ret = SetNsCreateNewContainers(flag, newContainer, targetContainer); if (ret != LOS_OK) { + SCHEDULER_UNLOCK(intSave); goto EXIT; } - SCHEDULER_LOCK(intSave); - oldContainer = curr->container; + Container *oldContainer = curr->container; curr->container = newContainer; SCHEDULER_UNLOCK(intSave); - - UnshareDeInitContainer(flags, oldContainer); + DeInitContainers(flag, oldContainer, NULL); return LOS_OK; EXIT: - UnshareDeInitContainer(flags, newContainer); - return -ret; + DeInitContainers(flag, newContainer, curr); + return ret; } #endif diff --git a/kernel/base/container/los_ipc_container.c b/kernel/base/container/los_ipc_container.c index 9acc08f8992389b6233618a8c320ddfdd631c929..826a75615c574ea251295ed0df40bae4b114c5ff 100644 --- a/kernel/base/container/los_ipc_container.c +++ b/kernel/base/container/los_ipc_container.c @@ -132,6 +132,7 @@ UINT32 OsUnshareIpcContainer(UINTPTR flags, LosProcessCB *curr, Container *newCo if (!(flags & CLONE_NEWIPC)) { SCHEDULER_LOCK(intSave); newContainer->ipcContainer = parentContainer; + LOS_AtomicInc(&parentContainer->rc); SCHEDULER_UNLOCK(intSave); return LOS_OK; } @@ -148,6 +149,19 @@ UINT32 OsUnshareIpcContainer(UINTPTR flags, LosProcessCB *curr, Container *newCo return LOS_OK; } +UINT32 OsSetNsIpcContainer(UINT32 flags, Container *container, Container *newContainer) +{ + if (flags & CLONE_NEWIPC) { + newContainer->ipcContainer = container->ipcContainer; + LOS_AtomicInc(&container->ipcContainer->rc); + return LOS_OK; + } + + newContainer->ipcContainer = OsCurrProcessGet()->container->ipcContainer; + LOS_AtomicInc(&newContainer->ipcContainer->rc); + return LOS_OK; +} + VOID OsIpcContainerDestroy(Container *container) { UINT32 intSave; @@ -169,9 +183,11 @@ VOID OsIpcContainerDestroy(Container *container) } g_currentIpcContainerNum--; - SCHEDULER_UNLOCK(intSave); - ShmDeinit(); container->ipcContainer = NULL; + SCHEDULER_UNLOCK(intSave); + OsShmCBDestroy(ipcContainer->shmSegs, &ipcContainer->shmInfo, &ipcContainer->sysvShmMux); + ipcContainer->shmSegs = NULL; + OsMqueueCBDestroy(ipcContainer->queueTable); (VOID)LOS_MemFree(m_aucSysMem1, ipcContainer->allQueue); (VOID)LOS_MemFree(m_aucSysMem1, ipcContainer); return; diff --git a/kernel/base/container/los_mnt_container.c b/kernel/base/container/los_mnt_container.c index 6b09e0832bc62d2b5fdc00fc313aea410e5700b9..ed6032b6ccbed84c51e747a6ff8178ad15d657fa 100644 --- a/kernel/base/container/los_mnt_container.c +++ b/kernel/base/container/los_mnt_container.c @@ -141,6 +141,7 @@ UINT32 OsUnshareMntContainer(UINTPTR flags, LosProcessCB *curr, Container *newCo if (!(flags & CLONE_NEWNS)) { SCHEDULER_LOCK(intSave); newContainer->mntContainer = parentContainer; + LOS_AtomicInc(&parentContainer->rc); SCHEDULER_UNLOCK(intSave); return LOS_OK; } @@ -163,6 +164,19 @@ UINT32 OsUnshareMntContainer(UINTPTR flags, LosProcessCB *curr, Container *newCo return LOS_OK; } +UINT32 OsSetNsMntContainer(UINT32 flags, Container *container, Container *newContainer) +{ + if (flags & CLONE_NEWNS) { + newContainer->mntContainer = container->mntContainer; + LOS_AtomicInc(&container->mntContainer->rc); + return LOS_OK; + } + + newContainer->mntContainer = OsCurrProcessGet()->container->mntContainer; + LOS_AtomicInc(&newContainer->mntContainer->rc); + return LOS_OK; +} + STATIC VOID FreeMountList(LIST_HEAD *mountList) { struct Mount *mnt = NULL; diff --git a/kernel/base/container/los_pid_container.c b/kernel/base/container/los_pid_container.c index 9b33500502d63b10e1dcf9a9cfea20f62474afc8..2fe6dcbc3a5d3090bf2a016b8500003cc266e489 100644 --- a/kernel/base/container/los_pid_container.c +++ b/kernel/base/container/los_pid_container.c @@ -67,9 +67,9 @@ STATIC ProcessVid *OsGetFreeVpid(PidContainer *pidContainer) return vpid; } -UINT32 OsAllocSpecifiedVpidUnsafe(UINT32 vpid, LosProcessCB *processCB, LosProcessCB *parent) +UINT32 OsAllocSpecifiedVpidUnsafe(UINT32 vpid, PidContainer *pidContainer, + LosProcessCB *processCB, LosProcessCB *parent) { - PidContainer *pidContainer = processCB->container->pidContainer; if ((pidContainer == NULL) || OS_PID_CHECK_INVALID(vpid)) { return OS_INVALID_VALUE; } @@ -84,14 +84,21 @@ UINT32 OsAllocSpecifiedVpidUnsafe(UINT32 vpid, LosProcessCB *processCB, LosProce } processVid->cb = (UINTPTR)processCB; + processVid->realParent = parent; processCB->processID = vpid; LOS_ListDelete(&processVid->node); LOS_AtomicInc(&pidContainer->rc); - if ((vpid == OS_USER_ROOT_PROCESS_ID) && (parent != NULL)) { - ProcessVid *vppidItem = &pidContainer->pidArray[0]; - LOS_ListDelete(&vppidItem->node); - vppidItem->cb = (UINTPTR)parent; + if (vpid == OS_USER_ROOT_PROCESS_ID) { + if (parent != NULL) { + ProcessVid *vppidItem = &pidContainer->pidArray[0]; + LOS_ListDelete(&vppidItem->node); + vppidItem->cb = (UINTPTR)parent; + } + + if (OsCreateProcessGroup(processCB) == NULL) { + return OS_INVALID_VALUE; + } } pidContainer = pidContainer->parent; @@ -110,7 +117,7 @@ UINT32 OsAllocSpecifiedVpidUnsafe(UINT32 vpid, LosProcessCB *processCB, LosProce return processCB->processID; } -STATIC UINT32 OsAllocVpid(LosProcessCB *processCB) +STATIC UINT32 OsAllocVpid(LosProcessCB *processCB, LosProcessCB *parent) { ProcessVid *oldProcessVid = NULL; PidContainer *pidContainer = processCB->container->pidContainer; @@ -127,6 +134,7 @@ STATIC UINT32 OsAllocVpid(LosProcessCB *processCB) vpid->cb = (UINTPTR)processCB; if (processCB->processID == OS_INVALID_VALUE) { processCB->processID = vpid->vid; + vpid->realParent = parent; } else { oldProcessVid->vpid = vpid->vid; } @@ -158,6 +166,7 @@ VOID OsFreeVtid(LosTaskCB *taskCB) item->cb = (UINTPTR)g_defaultTaskCB; vtid = item->vpid; item->vpid = OS_INVALID_VALUE; + item->realParent = NULL; LOS_ListTailInsert(&pidContainer->tidFreeList, &item->node); pidContainer = pidContainer->parent; } @@ -272,36 +281,41 @@ STATIC PidContainer *CreateNewPidContainer(PidContainer *parent) return newPidContainer; } -VOID OsPidContainerDestroy(LosProcessCB *curr) +VOID OsPidContainerDestroy(Container *container, LosProcessCB *processCB) { - if (curr->container == NULL) { + if (container == NULL) { return; } - PidContainer *pidContainer = curr->container->pidContainer; + PidContainer *pidContainer = container->pidContainer; if (pidContainer == NULL) { return; } - FreeVpid(curr); + if (processCB != NULL) { + FreeVpid(processCB); + } - if (pidContainer != curr->container->pidForChildContainer) { - LOS_AtomicDec(&curr->container->pidForChildContainer->rc); - if (LOS_AtomicRead(&curr->container->pidForChildContainer->rc) <= 0) { + if ((container->pidForChildContainer != NULL) && (pidContainer != container->pidForChildContainer)) { + LOS_AtomicDec(&container->pidForChildContainer->rc); + if (LOS_AtomicRead(&container->pidForChildContainer->rc) <= 0) { g_currentPidContainerNum--; - (VOID)LOS_MemFree(m_aucSysMem1, curr->container->pidForChildContainer); - curr->container->pidForChildContainer = NULL; + (VOID)LOS_MemFree(m_aucSysMem1, container->pidForChildContainer); + container->pidForChildContainer = NULL; } } if (LOS_AtomicRead(&pidContainer->rc) <= 0) { g_currentPidContainerNum--; - curr->container->pidContainer = NULL; - curr->container->pidForChildContainer = NULL; + container->pidContainer = NULL; + container->pidForChildContainer = NULL; + (VOID)LOS_MemFree(m_aucSysMem1, pidContainer->rootPGroup); (VOID)LOS_MemFree(m_aucSysMem1, pidContainer); } - OsContainerFree(curr); + if (processCB != NULL) { + OsContainerFree(processCB); + } } STATIC UINT32 CreatePidContainer(LosProcessCB *child, LosProcessCB *parent) @@ -326,7 +340,7 @@ STATIC UINT32 CreatePidContainer(LosProcessCB *child, LosProcessCB *parent) newPidContainer->referenced = TRUE; child->container->pidContainer = newPidContainer; child->container->pidForChildContainer = newPidContainer; - ret = OsAllocSpecifiedVpidUnsafe(OS_USER_ROOT_PROCESS_ID, child, parent); + ret = OsAllocSpecifiedVpidUnsafe(OS_USER_ROOT_PROCESS_ID, newPidContainer, child, parent); if (ret == OS_INVALID_VALUE) { g_currentPidContainerNum--; FreeVpid(child); @@ -340,20 +354,34 @@ STATIC UINT32 CreatePidContainer(LosProcessCB *child, LosProcessCB *parent) return LOS_OK; } -STATIC UINT32 UnshareCreatePidContainer(LosProcessCB *child, LosProcessCB *parent) +STATIC UINT32 AllocVpidFormPidForChildContainer(LosProcessCB *child, LosProcessCB *parent) { UINT32 ret; + PidContainer *pidContainer = parent->container->pidForChildContainer; + child->container->pidContainer = pidContainer; + child->container->pidForChildContainer = pidContainer; + + if (!pidContainer->referenced) { + pidContainer->referenced = TRUE; + ret = OsAllocSpecifiedVpidUnsafe(OS_USER_ROOT_PROCESS_ID, pidContainer, child, parent); + } else { + ret = OsAllocVpid(child, parent); + if (ret != OS_INVALID_VALUE) { + LosProcessCB *parentProcessCB = (LosProcessCB *)pidContainer->pidArray[OS_USER_ROOT_PROCESS_ID].cb; + child->parentProcess = parentProcessCB; + LOS_ListTailInsert(&parentProcessCB->childrenList, &child->siblingList); + child->pgroup = parentProcessCB->pgroup; + LOS_ListTailInsert(&parentProcessCB->pgroup->processList, &child->subordinateGroupList); + } + } - parent->container->pidForChildContainer->referenced = TRUE; - child->container->pidContainer = parent->container->pidForChildContainer; - child->container->pidForChildContainer = parent->container->pidForChildContainer; - ret = OsAllocSpecifiedVpidUnsafe(OS_USER_ROOT_PROCESS_ID, child, parent); if (ret == OS_INVALID_VALUE) { FreeVpid(child); child->container->pidContainer = NULL; child->container->pidForChildContainer = NULL; return ENOSPC; } + return LOS_OK; } @@ -365,12 +393,12 @@ UINT32 OsCopyPidContainer(UINTPTR flags, LosProcessCB *child, LosProcessCB *pare SCHEDULER_LOCK(intSave); PidContainer *parentPidContainer = parent->container->pidContainer; PidContainer *parentPidContainerForChild = parent->container->pidForChildContainer; - if ((parentPidContainer == parentPidContainerForChild) || (parentPidContainerForChild->referenced == TRUE)) { + if (parentPidContainer == parentPidContainerForChild) { /* The current process is not executing unshare */ if (!(flags & CLONE_NEWPID)) { child->container->pidContainer = parentPidContainer; child->container->pidForChildContainer = parentPidContainer; - ret = OsAllocVpid(child); + ret = OsAllocVpid(child, parent); SCHEDULER_UNLOCK(intSave); if (ret == OS_INVALID_VALUE) { PRINT_ERR("[%s] alloc vpid failed\n", __FUNCTION__); @@ -387,7 +415,7 @@ UINT32 OsCopyPidContainer(UINTPTR flags, LosProcessCB *child, LosProcessCB *pare } } else { /* Create the first process after unshare */ - ret = UnshareCreatePidContainer(child, parent); + ret = AllocVpidFormPidForChildContainer(child, parent); SCHEDULER_UNLOCK(intSave); if (ret != LOS_OK) { return ret; @@ -403,28 +431,6 @@ UINT32 OsCopyPidContainer(UINTPTR flags, LosProcessCB *child, LosProcessCB *pare return LOS_OK; } -VOID UnshareDeInitPidContainer(Container *container) -{ - UINT32 intSave; - PidContainer *pidForChildContainer = NULL; - if (container == NULL) { - return; - } - - SCHEDULER_LOCK(intSave); - if ((container->pidForChildContainer != NULL) && (container->pidContainer != container->pidForChildContainer)) { - LOS_AtomicDec(&container->pidForChildContainer->rc); - if (LOS_AtomicRead(&container->pidForChildContainer->rc) <= 0) { - g_currentPidContainerNum--; - pidForChildContainer = container->pidForChildContainer; - container->pidForChildContainer = NULL; - container->pidContainer = NULL; - } - } - SCHEDULER_UNLOCK(intSave); - (VOID)LOS_MemFree(m_aucSysMem1, pidForChildContainer); -} - UINT32 OsUnsharePidContainer(UINTPTR flags, LosProcessCB *curr, Container *newContainer) { UINT32 intSave; @@ -465,6 +471,25 @@ UINT32 OsUnsharePidContainer(UINTPTR flags, LosProcessCB *curr, Container *newCo return LOS_OK; } +UINT32 OsSetNsPidContainer(UINT32 flags, Container *container, Container *newContainer) +{ + UINT32 ret = LOS_OK; + LosProcessCB *curr = OsCurrProcessGet(); + newContainer->pidContainer = curr->container->pidContainer; + + if (flags & CLONE_NEWPID) { + newContainer->pidForChildContainer = container->pidContainer; + LOS_AtomicInc(&container->pidContainer->rc); + return ret; + } + + newContainer->pidForChildContainer = curr->container->pidForChildContainer; + if (newContainer->pidContainer != newContainer->pidForChildContainer) { + LOS_AtomicInc(&newContainer->pidForChildContainer->rc); + } + return LOS_OK; +} + UINT32 OsInitRootPidContainer(PidContainer **pidContainer) { UINT32 intSave; @@ -549,6 +574,20 @@ LosTaskCB *OsGetTCBFromVtid(UINT32 vtid) return (LosTaskCB *)taskVid->cb; } +BOOL OsPidContainerProcessParentIsRealParent(const LosProcessCB *processCB, const LosProcessCB *curr) +{ + if (curr == processCB->parentProcess) { + return FALSE; + } + + PidContainer *pidContainer = processCB->container->pidContainer; + ProcessVid *processVid = &pidContainer->pidArray[processCB->processID]; + if (processVid->realParent == curr) { + return TRUE; + } + return FALSE; +} + UINT32 OsGetPidContainerID(PidContainer *pidContainer) { if (pidContainer == NULL) { diff --git a/kernel/base/container/los_time_container.c b/kernel/base/container/los_time_container.c index cbbeccb17df344ea369077ae1ee9b69e96c9684b..5ec69c7294414cf011ea7fc6b62fe51f8bb6a3cf 100644 --- a/kernel/base/container/los_time_container.c +++ b/kernel/base/container/los_time_container.c @@ -106,6 +106,7 @@ UINT32 OsUnshareTimeContainer(UINTPTR flags, LosProcessCB *curr, Container *newC SCHEDULER_LOCK(intSave); newContainer->timeContainer = curr->container->timeContainer; newContainer->timeForChildContainer = curr->container->timeForChildContainer; + LOS_AtomicInc(&newContainer->timeContainer->rc); if (newContainer->timeContainer != newContainer->timeForChildContainer) { LOS_AtomicInc(&newContainer->timeForChildContainer->rc); } @@ -128,65 +129,64 @@ UINT32 OsUnshareTimeContainer(UINTPTR flags, LosProcessCB *curr, Container *newC (VOID)memcpy_s(&timeForChild->monotonic, sizeof(struct timespec64), &curr->container->timeContainer->monotonic, sizeof(struct timespec64)); newContainer->timeContainer = curr->container->timeContainer; + LOS_AtomicInc(&newContainer->timeContainer->rc); newContainer->timeForChildContainer = timeForChild; g_currentTimeContainerNum++; SCHEDULER_UNLOCK(intSave); return LOS_OK; } -VOID UnshareDeInitTimeContainer(Container *container) +UINT32 OsSetNsTimeContainer(UINT32 flags, Container *container, Container *newContainer) { - UINT32 intSave; - TimeContainer *timeForChildContainer = NULL; - if (container == NULL) { - return; + LosProcessCB *curr = OsCurrProcessGet(); + if (flags & CLONE_NEWTIME) { + container->timeContainer->frozenOffsets = TRUE; + newContainer->timeContainer = container->timeContainer; + newContainer->timeForChildContainer = container->timeContainer; + LOS_AtomicInc(&container->timeContainer->rc); + return LOS_OK; } - SCHEDULER_LOCK(intSave); - if ((container->timeForChildContainer != NULL) && (container->timeForChildContainer != container->timeContainer)) { - LOS_AtomicDec(&container->timeForChildContainer->rc); - if (LOS_AtomicRead(&container->timeForChildContainer->rc) <= 0) { - g_currentTimeContainerNum--; - timeForChildContainer = container->timeForChildContainer; - container->timeForChildContainer = NULL; - container->timeContainer = NULL; - } + newContainer->timeContainer = curr->container->timeContainer; + LOS_AtomicInc(&curr->container->timeContainer->rc); + newContainer->timeForChildContainer = curr->container->timeForChildContainer; + if (curr->container->timeContainer != curr->container->timeForChildContainer) { + LOS_AtomicInc(&curr->container->timeForChildContainer->rc); } - SCHEDULER_UNLOCK(intSave); - (VOID)LOS_MemFree(m_aucSysMem1, timeForChildContainer); + return LOS_OK; } -VOID OsTimeContainerDestroy(LosProcessCB *curr) +VOID OsTimeContainerDestroy(Container *container) { UINT32 intSave; TimeContainer *timeContainer = NULL; TimeContainer *timeForChild = NULL; - if (curr->container == NULL) { + if (container == NULL) { return; } SCHEDULER_LOCK(intSave); - if (curr->container->timeContainer == NULL) { + if (container->timeContainer == NULL) { SCHEDULER_UNLOCK(intSave); return; } - if (curr->container->timeContainer != curr->container->timeForChildContainer) { - LOS_AtomicDec(&curr->container->timeForChildContainer->rc); - if (LOS_AtomicRead(&curr->container->timeForChildContainer->rc) <= 0) { + if ((container->timeForChildContainer != NULL) && (container->timeContainer != container->timeForChildContainer)) { + LOS_AtomicDec(&container->timeForChildContainer->rc); + if (LOS_AtomicRead(&container->timeForChildContainer->rc) <= 0) { g_currentTimeContainerNum--; - timeForChild = curr->container->timeForChildContainer; - curr->container->timeForChildContainer = NULL; + timeForChild = container->timeForChildContainer; + container->timeForChildContainer = NULL; } } - LOS_AtomicDec(&curr->container->timeContainer->rc); - if (LOS_AtomicRead(&curr->container->timeContainer->rc) <= 0) { + LOS_AtomicDec(&container->timeContainer->rc); + if (LOS_AtomicRead(&container->timeContainer->rc) <= 0) { g_currentTimeContainerNum--; - timeContainer = curr->container->timeContainer; - curr->container->timeContainer = NULL; - curr->container->timeForChildContainer = NULL; + timeContainer = container->timeContainer; + container->timeContainer = NULL; + container->timeForChildContainer = NULL; } SCHEDULER_UNLOCK(intSave); (VOID)LOS_MemFree(m_aucSysMem1, timeForChild); diff --git a/kernel/base/container/los_uts_container.c b/kernel/base/container/los_uts_container.c index 5b4aba1589fd80cdb12b33d3a9794a12838864eb..f5d6a501e118f9faacf41a0dde164419c5bc5fd7 100644 --- a/kernel/base/container/los_uts_container.c +++ b/kernel/base/container/los_uts_container.c @@ -146,6 +146,7 @@ UINT32 OsUnshareUtsContainer(UINTPTR flags, LosProcessCB *curr, Container *newCo if (!(flags & CLONE_NEWUTS)) { SCHEDULER_LOCK(intSave); newContainer->utsContainer = parentContainer; + LOS_AtomicInc(&parentContainer->rc); SCHEDULER_UNLOCK(intSave); return LOS_OK; } @@ -164,6 +165,19 @@ UINT32 OsUnshareUtsContainer(UINTPTR flags, LosProcessCB *curr, Container *newCo return LOS_OK; } +UINT32 OsSetNsUtsContainer(UINT32 flags, Container *container, Container *newContainer) +{ + if (flags & CLONE_NEWUTS) { + newContainer->utsContainer = container->utsContainer; + LOS_AtomicInc(&container->utsContainer->rc); + return LOS_OK; + } + + newContainer->utsContainer = OsCurrProcessGet()->container->utsContainer; + LOS_AtomicInc(&newContainer->utsContainer->rc); + return LOS_OK; +} + VOID OsUtsContainerDestroy(Container *container) { UINT32 intSave; diff --git a/kernel/base/core/los_process.c b/kernel/base/core/los_process.c index e425a969a590c1d8773ec41b8e6b90ed95f8dc8a..016da59284396e24f376069ca2fe89f57a577e27 100644 --- a/kernel/base/core/los_process.c +++ b/kernel/base/core/los_process.c @@ -71,7 +71,7 @@ LITE_OS_SEC_BSS ProcessGroup *g_processGroup = NULL; STATIC INLINE VOID OsInsertPCBToFreeList(LosProcessCB *processCB) { #ifdef LOSCFG_PID_CONTAINER - OsPidContainerDestroy(processCB); + OsPidContainerDestroy(processCB->container, processCB); #endif UINT32 pid = processCB->processID; (VOID)memset_s(processCB, sizeof(LosProcessCB), 0, sizeof(LosProcessCB)); @@ -133,7 +133,7 @@ UINT32 OsProcessAddNewTask(UINTPTR processID, LosTaskCB *taskCB, SchedParam *par return LOS_OK; } -STATIC ProcessGroup *CreateProcessGroup(LosProcessCB *processCB) +ProcessGroup *OsCreateProcessGroup(LosProcessCB *processCB) { ProcessGroup *pgroup = LOS_MemAlloc(m_aucSysMem1, sizeof(ProcessGroup)); if (pgroup == NULL) { @@ -163,9 +163,15 @@ STATIC VOID ExitProcessGroup(LosProcessCB *processCB, ProcessGroup **pgroup) LosProcessCB *pgroupCB = OS_GET_PGROUP_LEADER(processCB->pgroup); LOS_ListDelete(&processCB->subordinateGroupList); if (LOS_ListEmpty(&processCB->pgroup->processList) && LOS_ListEmpty(&processCB->pgroup->exitProcessList)) { - LOS_ListDelete(&processCB->pgroup->groupList); +#ifdef LOSCFG_PID_CONTAINER + if (processCB->pgroup != OS_ROOT_PGRP(processCB)) { +#endif + LOS_ListDelete(&processCB->pgroup->groupList); + *pgroup = processCB->pgroup; +#ifdef LOSCFG_PID_CONTAINER + } +#endif pgroupCB->processStatus &= ~OS_PROCESS_FLAG_GROUP_LEADER; - *pgroup = processCB->pgroup; if (OsProcessIsUnused(pgroupCB) && !(pgroupCB->processStatus & OS_PROCESS_FLAG_EXIT)) { LOS_ListDelete(&pgroupCB->pendList); OsInsertPCBToFreeList(pgroupCB); @@ -855,7 +861,7 @@ STATIC UINT32 OsSystemProcessInit(LosProcessCB *processCB, UINT32 flags, const C } #endif - ProcessGroup *pgroup = CreateProcessGroup(processCB); + ProcessGroup *pgroup = OsCreateProcessGroup(processCB); if (pgroup == NULL) { ret = LOS_ENOMEM; goto EXIT; @@ -1090,32 +1096,53 @@ STATIC VOID OsWaitInsertWaitListInOrder(LosTaskCB *runTask, LosProcessCB *proces return; } +STATIC UINT32 WaitFindSpecifiedProcess(UINT32 pid, LosTaskCB *runTask, + const LosProcessCB *processCB, LosProcessCB **childCB) +{ + if (OS_PID_CHECK_INVALID((UINT32)pid)) { + return LOS_ECHILD; + } + + LosProcessCB *waitProcess = OS_PCB_FROM_PID(pid); + if (OsProcessIsUnused(waitProcess)) { + return LOS_ECHILD; + } + +#ifdef LOSCFG_PID_CONTAINER + if (OsPidContainerProcessParentIsRealParent(waitProcess, processCB)) { + *childCB = (LosProcessCB *)processCB; + return LOS_OK; + } +#endif + /* Wait for the child process whose process number is pid. */ + *childCB = OsFindExitChildProcess(processCB, waitProcess); + if (*childCB != NULL) { + return LOS_OK; + } + + if (OsFindChildProcess(processCB, waitProcess) != LOS_OK) { + return LOS_ECHILD; + } + + runTask->waitFlag = OS_PROCESS_WAIT_PRO; + runTask->waitID = (UINTPTR)waitProcess; + return LOS_OK; +} + STATIC UINT32 OsWaitSetFlag(const LosProcessCB *processCB, INT32 pid, LosProcessCB **child) { + UINT32 ret; LosProcessCB *childCB = NULL; LosTaskCB *runTask = OsCurrTaskGet(); if (pid > 0) { - if (OS_PID_CHECK_INVALID((UINT32)pid)) { - return LOS_ECHILD; - } - - LosProcessCB *waitProcess = OS_PCB_FROM_PID(pid); - if (OsProcessIsUnused(waitProcess)) { - return LOS_ECHILD; + ret = WaitFindSpecifiedProcess((UINT32)pid, runTask, processCB, &childCB); + if (ret != LOS_OK) { + return ret; } - - /* Wait for the child process whose process number is pid. */ - childCB = OsFindExitChildProcess(processCB, waitProcess); if (childCB != NULL) { goto WAIT_BACK; } - - if (OsFindChildProcess(processCB, waitProcess) != LOS_OK) { - return LOS_ECHILD; - } - runTask->waitFlag = OS_PROCESS_WAIT_PRO; - runTask->waitID = (UINTPTR)waitProcess; } else if (pid == 0) { /* Wait for any child process in the same process group */ childCB = OsFindGroupExitProcess(processCB->pgroup, OS_INVALID_VALUE); @@ -1254,6 +1281,15 @@ STATIC INT32 OsWait(INT32 pid, USER INT32 *status, USER siginfo_t *info, UINT32 } if (childCB != NULL) { +#ifdef LOSCFG_PID_CONTAINER + if (childCB == processCB) { + SCHEDULER_UNLOCK(intSave); + if (status != NULL) { + (VOID)LOS_ArchCopyToUser((VOID *)status, (const VOID *)(&ret), sizeof(INT32)); + } + return pid; + } +#endif return (INT32)OsWaitRecycleChildProcess(childCB, intSave, status, info); } @@ -1419,7 +1455,7 @@ STATIC UINT32 OsSetProcessGroupIDUnsafe(UINT32 pid, UINT32 gid, ProcessGroup **p return LOS_OK; } - newPGroup = CreateProcessGroup(pgroupCB); + newPGroup = OsCreateProcessGroup(pgroupCB); if (newPGroup == NULL) { LOS_ListTailInsert(&oldPGroup->processList, &processCB->subordinateGroupList); processCB->pgroup = oldPGroup; @@ -1850,30 +1886,26 @@ STATIC UINT32 OsCopyTask(UINT32 flags, LosProcessCB *childProcessCB, const CHAR STATIC UINT32 OsCopyParent(UINT32 flags, LosProcessCB *childProcessCB, LosProcessCB *runProcessCB) { - UINT32 ret; UINT32 intSave; LosProcessCB *parentProcessCB = NULL; SCHEDULER_LOCK(intSave); - if (flags & CLONE_PARENT) { - parentProcessCB = runProcessCB->parentProcess; - } else { - parentProcessCB = runProcessCB; + if (childProcessCB->parentProcess == NULL) { + if (flags & CLONE_PARENT) { + parentProcessCB = runProcessCB->parentProcess; + } else { + parentProcessCB = runProcessCB; + } + childProcessCB->parentProcess = parentProcessCB; + LOS_ListTailInsert(&parentProcessCB->childrenList, &childProcessCB->siblingList); } - childProcessCB->parentProcess = parentProcessCB; - LOS_ListTailInsert(&parentProcessCB->childrenList, &childProcessCB->siblingList); - if (!(flags & CLONE_NEWPID)) { + + if (childProcessCB->pgroup == NULL) { childProcessCB->pgroup = parentProcessCB->pgroup; LOS_ListTailInsert(&parentProcessCB->pgroup->processList, &childProcessCB->subordinateGroupList); - } else { - if (CreateProcessGroup(childProcessCB) == NULL) { - SCHEDULER_UNLOCK(intSave); - return LOS_ENOMEM; - } } - ret = OsCopyUser(childProcessCB, parentProcessCB); SCHEDULER_UNLOCK(intSave); - return ret; + return LOS_OK; } STATIC UINT32 OsCopyMM(UINT32 flags, LosProcessCB *childProcessCB, LosProcessCB *runProcessCB) @@ -1939,11 +1971,6 @@ STATIC UINT32 OsForkInitPCB(UINT32 flags, LosProcessCB *child, const CHAR *name, UINT32 ret; LosProcessCB *run = OsCurrProcessGet(); - ret = OsInitPCB(child, run->processMode, name); - if (ret != LOS_OK) { - return ret; - } - ret = OsCopyParent(flags, child, run); if (ret != LOS_OK) { return ret; @@ -1980,6 +2007,11 @@ STATIC UINT32 OsCopyProcessResources(UINT32 flags, LosProcessCB *child, LosProce { UINT32 ret; + ret = OsCopyUser(child, run); + if (ret != LOS_OK) { + return ret; + } + ret = OsCopyMM(flags, child, run); if (ret != LOS_OK) { return ret; @@ -2016,6 +2048,11 @@ STATIC INT32 OsCopyProcess(UINT32 flags, const CHAR *name, UINTPTR sp, UINT32 si } processID = child->processID; + ret = OsInitPCB(child, run->processMode, name); + if (ret != LOS_OK) { + goto ERROR_INIT; + } + #ifdef LOSCFG_KERNEL_CONTAINER ret = OsCopyContainers(flags, child, run, &processID); if (ret != LOS_OK) { @@ -2058,10 +2095,18 @@ LITE_OS_SEC_TEXT INT32 OsClone(UINT32 flags, UINTPTR sp, UINT32 size) #ifdef LOSCFG_KERNEL_CONTAINER #ifdef LOSCFG_PID_CONTAINER cloneFlag |= CLONE_NEWPID; - + LosProcessCB *curr = OsCurrProcessGet(); if (((flags & CLONE_NEWPID) != 0) && ((flags & (CLONE_PARENT | CLONE_THREAD)) != 0)) { return -LOS_EINVAL; } + + if (OS_PROCESS_PID_FOR_CONTAINER_CHECK(curr) && ((flags & CLONE_NEWPID) != 0)) { + return -LOS_EINVAL; + } + + if (OS_PROCESS_PID_FOR_CONTAINER_CHECK(curr) && ((flags & (CLONE_PARENT | CLONE_THREAD)) != 0)) { + return -LOS_EINVAL; + } #endif #ifdef LOSCFG_UTS_CONTAINER cloneFlag |= CLONE_NEWUTS; diff --git a/kernel/base/include/los_container_pri.h b/kernel/base/include/los_container_pri.h index 3870bcefcb823e2dbcc0052a1ec390e019a438a1..68e166f181bda0728eb67c26c8cd337eed1bf34d 100644 --- a/kernel/base/include/los_container_pri.h +++ b/kernel/base/include/los_container_pri.h @@ -58,6 +58,7 @@ typedef enum { IPC_CONTAINER, TIME_CONTAINER, TIME_CHILD_CONTAINER, + CONTAINER_MAX, } ContainerType; typedef struct Container { @@ -97,5 +98,7 @@ UINT32 OsGetContainerID(Container *container, ContainerType type); INT32 OsUnshare(UINT32 flags); +INT32 OsSetNs(INT32 fd, INT32 type); + #endif #endif /* _LOS_CONTAINER_PRI_H */ diff --git a/kernel/base/include/los_ipc_container_pri.h b/kernel/base/include/los_ipc_container_pri.h index df33098fe362abe1e5ccd483320d207378b47327..01593d4dfdb8e4fccb1fd73b18d4ae4b20b860e9 100644 --- a/kernel/base/include/los_ipc_container_pri.h +++ b/kernel/base/include/los_ipc_container_pri.h @@ -64,6 +64,8 @@ UINT32 OsCopyIpcContainer(UINTPTR flags, LosProcessCB *child, LosProcessCB *pare UINT32 OsUnshareIpcContainer(UINTPTR flags, LosProcessCB *curr, struct Container *newContainer); +UINT32 OsSetNsIpcContainer(UINT32 flags, struct Container *container, struct Container *newContainer); + VOID OsIpcContainerDestroy(struct Container *container); UINT32 OsGetIpcContainerID(IpcContainer *ipcContainer); diff --git a/kernel/base/include/los_mnt_container_pri.h b/kernel/base/include/los_mnt_container_pri.h index b226daee89c96c28120f5041c392ffb2e87fd182..c2cb7dc56ece8851d2f42e97c1e5e6c7f8ef2255 100644 --- a/kernel/base/include/los_mnt_container_pri.h +++ b/kernel/base/include/los_mnt_container_pri.h @@ -55,6 +55,8 @@ UINT32 OsCopyMntContainer(UINTPTR flags, LosProcessCB *child, LosProcessCB *pare UINT32 OsUnshareMntContainer(UINTPTR flags, LosProcessCB *curr, struct Container *newContainer); +UINT32 OsSetNsMntContainer(UINT32 flags, struct Container *container, struct Container *newContainer); + VOID OsMntContainerDestroy(struct Container *container); UINT32 OsGetMntContainerID(MntContainer *mntContainer); diff --git a/kernel/base/include/los_pid_container_pri.h b/kernel/base/include/los_pid_container_pri.h index e8c7301e5a9321b4879403c64183e4895a69198b..bad7994d236dd699746a0a70972edbfc8fb366e6 100644 --- a/kernel/base/include/los_pid_container_pri.h +++ b/kernel/base/include/los_pid_container_pri.h @@ -43,6 +43,7 @@ typedef struct { UINT32 vid; /* Virtual ID */ UINT32 vpid; /* Virtual parent ID */ UINTPTR cb; /* Control block */ + LosProcessCB *realParent; /* process real parent */ LOS_DL_LIST node; } ProcessVid; @@ -69,17 +70,22 @@ typedef struct PidContainer { #define OS_PROCESS_CONTAINER_CHECK(processCB, currProcessCB) \ ((processCB)->container->pidContainer != (currProcessCB)->container->pidContainer) -UINT32 OsAllocSpecifiedVpidUnsafe(UINT32 vpid, LosProcessCB *processCB, LosProcessCB *parent); +#define OS_PROCESS_PID_FOR_CONTAINER_CHECK(processCB) \ + (((processCB)->container->pidContainer != (processCB)->container->pidForChildContainer) && \ + ((processCB)->container->pidForChildContainer->referenced == FALSE)) + +UINT32 OsAllocSpecifiedVpidUnsafe(UINT32 vpid, PidContainer *pidContainer, + LosProcessCB *processCB, LosProcessCB *parent); VOID OsPidContainerDestroyAllProcess(LosProcessCB *processCB); -VOID OsPidContainerDestroy(LosProcessCB *curr); +VOID OsPidContainerDestroy(struct Container *container, LosProcessCB *processCB); UINT32 OsCopyPidContainer(UINTPTR flags, LosProcessCB *child, LosProcessCB *parent, UINT32 *processID); UINT32 OsUnsharePidContainer(UINTPTR flags, LosProcessCB *curr, struct Container *newContainer); -VOID UnshareDeInitPidContainer(struct Container *container); +UINT32 OsSetNsPidContainer(UINT32 flags, struct Container *container, struct Container *newContainer); UINT32 OsInitRootPidContainer(PidContainer **pidContainer); @@ -99,4 +105,5 @@ UINT32 OsAllocVtid(LosTaskCB *taskCB, const LosProcessCB *processCB); UINT32 OsGetPidContainerID(PidContainer *pidContainer); +BOOL OsPidContainerProcessParentIsRealParent(const LosProcessCB *processCB, const LosProcessCB *curr); #endif /* _LOS_PID_CONTAINER_PRI_H */ diff --git a/kernel/base/include/los_process_pri.h b/kernel/base/include/los_process_pri.h index 9272a54a9ba647026fd7ac345bad4e7a54b9b98d..ecf2d049bebc5618e6627d7a55d3a2ae45bcf6cb 100644 --- a/kernel/base/include/los_process_pri.h +++ b/kernel/base/include/los_process_pri.h @@ -541,6 +541,7 @@ extern VOID OsDeleteTaskFromProcess(LosTaskCB *taskCB); extern VOID OsProcessThreadGroupDestroy(VOID); extern UINT32 OsGetProcessGroupCB(UINT32 pid, UINTPTR *ppgroupLeader); extern LosProcessCB *OsGetDefaultProcessCB(VOID); +extern ProcessGroup *OsCreateProcessGroup(LosProcessCB *processCB); #ifdef __cplusplus #if __cplusplus } diff --git a/kernel/base/include/los_time_container_pri.h b/kernel/base/include/los_time_container_pri.h index 8b233eb59db9726396e0f31863d836b936b58e26..f96fe2c6c2a864f1c37c103cdcd6ba5407523b5e 100644 --- a/kernel/base/include/los_time_container_pri.h +++ b/kernel/base/include/los_time_container_pri.h @@ -50,9 +50,9 @@ UINT32 OsCopyTimeContainer(UINTPTR flags, LosProcessCB *child, LosProcessCB *par UINT32 OsUnshareTimeContainer(UINTPTR flags, LosProcessCB *curr, struct Container *newContainer); -VOID UnshareDeInitTimeContainer(struct Container *container); +UINT32 OsSetNsTimeContainer(UINT32 flags, struct Container *container, struct Container *newContainer); -VOID OsTimeContainerDestroy(LosProcessCB *curr); +VOID OsTimeContainerDestroy(struct Container *container); UINT32 OsGetTimeContainerID(TimeContainer *timeContainer); diff --git a/kernel/base/include/los_uts_container_pri.h b/kernel/base/include/los_uts_container_pri.h index 1ef4870aa77e502fcd8945291918771f79325912..f21f2092a8a5b1f106cafd32c895e50725f7dbe5 100644 --- a/kernel/base/include/los_uts_container_pri.h +++ b/kernel/base/include/los_uts_container_pri.h @@ -52,10 +52,13 @@ UINT32 OsCopyUtsContainer(UINTPTR flags, LosProcessCB *child, LosProcessCB *pare UINT32 OsUnshareUtsContainer(UINTPTR flags, LosProcessCB *curr, struct Container *newContainer); +UINT32 OsSetNsUtsContainer(UINT32 flags, struct Container *container, struct Container *newContainer); + VOID OsUtsContainerDestroy(struct Container *container); struct utsname *OsGetCurrUtsName(VOID); UINT32 OsGetUtsContainerID(UtsContainer *utsContainer); + #endif #endif /* _LOS_UTS_CONTAINER_PRI_H */ diff --git a/kernel/base/include/los_vm_shm_pri.h b/kernel/base/include/los_vm_shm_pri.h index 24df894f6416ddc600d23ef74562f6b4064fb04c..21c7c30885f5511bed0fb341e157b7fdd7d05d76 100644 --- a/kernel/base/include/los_vm_shm_pri.h +++ b/kernel/base/include/los_vm_shm_pri.h @@ -63,6 +63,7 @@ VOID OsShmFork(LosVmSpace *space, LosVmMapRegion *oldRegion, LosVmMapRegion *new VOID OsShmRegionFree(LosVmSpace *space, LosVmMapRegion *region); BOOL OsIsShmRegion(LosVmMapRegion *region); struct shmIDSource *OsShmCBInit(LosMux *sysvShmMux, struct shminfo *shmInfo, UINT32 *shmUsedPageCount); +VOID OsShmCBDestroy(struct shmIDSource *shmSegs, struct shminfo *shmInfo, LosMux *sysvShmMux); #ifdef __cplusplus #if __cplusplus } diff --git a/kernel/base/vm/shm.c b/kernel/base/vm/shm.c index 03b1e26d727bcbdeebb32df8d87b618c0029e850..5a9d5965497848c45f382f64bd34f3e37792a688 100644 --- a/kernel/base/vm/shm.c +++ b/kernel/base/vm/shm.c @@ -204,6 +204,7 @@ STATIC INT32 ShmAllocSeg(key_t key, size_t size, INT32 shmflg) (size > IPC_SHM_INFO.shmmax)) { return -EINVAL; } + size = LOS_Align(size, PAGE_SIZE); if ((IPC_SHM_USED_PAGE_COUNT + (size >> PAGE_SHIFT)) > IPC_SHM_INFO.shmall) { return -ENOMEM; @@ -228,6 +229,7 @@ STATIC INT32 ShmAllocSeg(key_t key, size_t size, INT32 shmflg) seg->status = SHM_SEG_FREE; return -ENOMEM; } + ShmSetSharedFlag(seg); IPC_SHM_USED_PAGE_COUNT += size >> PAGE_SHIFT; @@ -252,7 +254,7 @@ STATIC INT32 ShmAllocSeg(key_t key, size_t size, INT32 shmflg) return segNum; } -STATIC INLINE VOID ShmFreeSeg(struct shmIDSource *seg) +STATIC INLINE VOID ShmFreeSeg(struct shmIDSource *seg, UINT32 *shmUsedPageCount) { UINT32 count; @@ -262,7 +264,9 @@ 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; } - IPC_SHM_USED_PAGE_COUNT -= seg->ds.shm_segsz >> PAGE_SHIFT; + if (shmUsedPageCount != NULL) { + (*shmUsedPageCount) -= seg->ds.shm_segsz >> PAGE_SHIFT; + } seg->status = SHM_SEG_FREE; LOS_ListInit(&seg->node); } @@ -369,7 +373,7 @@ VOID OsShmRegionFree(LosVmSpace *space, LosVmMapRegion *region) ShmPagesRefDec(seg); seg->ds.shm_nattch--; if (seg->ds.shm_nattch <= 0 && (seg->status & SHM_SEG_REMOVE)) { - ShmFreeSeg(seg); + ShmFreeSeg(seg, &IPC_SHM_USED_PAGE_COUNT); } else { seg->ds.shm_dtime = time(NULL); seg->ds.shm_lpid = LOS_GetCurrProcessID(); /* may not be the space's PID. */ @@ -677,7 +681,7 @@ INT32 ShmCtl(INT32 shmid, INT32 cmd, struct shmid_ds *buf) seg->status |= SHM_SEG_REMOVE; if (seg->ds.shm_nattch <= 0) { - ShmFreeSeg(seg); + ShmFreeSeg(seg, &IPC_SHM_USED_PAGE_COUNT); } break; case IPC_INFO: @@ -763,7 +767,7 @@ INT32 ShmDt(const VOID *shmaddr) seg->ds.shm_nattch--; if ((seg->ds.shm_nattch <= 0) && (seg->status & SHM_SEG_REMOVE)) { - ShmFreeSeg(seg); + ShmFreeSeg(seg, &IPC_SHM_USED_PAGE_COUNT); } else { seg->ds.shm_dtime = time(NULL); seg->ds.shm_lpid = LOS_GetCurrProcessID(); @@ -780,6 +784,27 @@ ERROR: return -1; } +VOID OsShmCBDestroy(struct shmIDSource *shmSegs, struct shminfo *shmInfo, LosMux *sysvShmMux) +{ + if ((shmSegs == NULL) || (shmInfo == NULL) || (sysvShmMux == NULL)) { + return; + } + + for (UINT32 index = 0; index < shmInfo->shmmni; index++) { + struct shmIDSource *seg = &shmSegs[index]; + if (seg->status == SHM_SEG_FREE) { + continue; + } + + (VOID)LOS_MuxLock(sysvShmMux, LOS_WAIT_FOREVER); + ShmFreeSeg(seg, NULL); + (VOID)LOS_MuxUnlock(sysvShmMux); + } + + (VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, shmSegs); + (VOID)LOS_MuxDestroy(sysvShmMux); +} + #ifdef LOSCFG_SHELL STATIC VOID OsShmInfoCmd(VOID) { @@ -819,7 +844,7 @@ STATIC VOID OsShmDeleteCmd(INT32 shmid) } if (seg->ds.shm_nattch <= 0) { - ShmFreeSeg(seg); + ShmFreeSeg(seg, &IPC_SHM_USED_PAGE_COUNT); } SYSV_SHM_UNLOCK(); } diff --git a/syscall/los_syscall.h b/syscall/los_syscall.h index e9863ffcec1fd049699106810b7101397612f30a..e45fa9a1fbca06a67f26e9d05d508c3dbafe14ae 100644 --- a/syscall/los_syscall.h +++ b/syscall/los_syscall.h @@ -86,6 +86,7 @@ extern int SysFork(void); extern int SysVfork(void); extern int SysClone(int flags, void *stack, int *parentTid, unsigned long tls, int *childTid); extern int SysUnshare(int flags); +extern int SysSetns(int fd, int type); extern unsigned int SysGetPID(void); extern unsigned int SysGetPPID(void); extern int SysSetGroupID(unsigned int gid); diff --git a/syscall/process_syscall.c b/syscall/process_syscall.c index 74386be77e5185b07eeb3b14eb84e8bcac9461b1..af7c73fd5551a9fc2d47682e037a1aa9f940c72e 100644 --- a/syscall/process_syscall.c +++ b/syscall/process_syscall.c @@ -378,6 +378,15 @@ int SysUnshare(int flags) #endif } +int SysSetns(int fd, int type) +{ +#ifdef LOSCFG_KERNEL_CONTAINER + return OsSetNs(fd, type); +#else + return -ENOSYS; +#endif +} + unsigned int SysGetPPID(void) { #ifdef LOSCFG_PID_CONTAINER diff --git a/syscall/syscall_lookup.h b/syscall/syscall_lookup.h index bdb69e67ee4bdf3df4d0100a953e90d8044abc12..53282ffa95779784a4b180ae52fa3522f8a32fb6 100644 --- a/syscall/syscall_lookup.h +++ b/syscall/syscall_lookup.h @@ -141,6 +141,7 @@ SYSCALL_HAND_DEF(__NR_fork, SysFork, int, ARG_NUM_0) SYSCALL_HAND_DEF(__NR_vfork, SysVfork, int, ARG_NUM_0) SYSCALL_HAND_DEF(__NR_clone, SysClone, int, ARG_NUM_5) SYSCALL_HAND_DEF(__NR_unshare, SysUnshare, int, ARG_NUM_1) +SYSCALL_HAND_DEF(__NR_setns, SysSetns, int, ARG_NUM_2) SYSCALL_HAND_DEF(__NR_getpid, SysGetPID, unsigned int, ARG_NUM_0) SYSCALL_HAND_DEF(__NR_pause, SysPause, int, ARG_NUM_0) diff --git a/testsuites/unittest/container/It_container_test.cpp b/testsuites/unittest/container/It_container_test.cpp index bc81fe8aff236c82cb269b7f50a603a8d65e167d..c0af945351d04bbdad778180c68aaf07a75e3309 100644 --- a/testsuites/unittest/container/It_container_test.cpp +++ b/testsuites/unittest/container/It_container_test.cpp @@ -65,6 +65,29 @@ pid_t CloneWrapper(int (*func)(void *), int flag, void *args) return pid; } +int WaitChild(pid_t pid, int *status, int errNo1, int errNo2) +{ + int ret = waitpid(pid, status, 0); + if (ret != pid) { + printf("[ERR] WaitChild pid=%d return pid=%d\n", pid, ret); + return errNo1; + } + if (status == nullptr) { + return 0; + } + ret = WIFEXITED(*status); + if (ret == 0) { + printf("[ERR] WaitChild pid=%d WIFEXITED(status)=%d\n", pid, WIFEXITED(*status)); + return errNo2; + } + ret = WEXITSTATUS(*status); + if (ret != 0) { + printf("[ERR] WaitChild pid=%d WEXITSTATUS(status)=%d\n", pid, WEXITSTATUS(*status)); + return errNo2; + } + return 0; +} + std::string GenContainerLinkPath(int pid, const std::string& containerType) { std::ostringstream buf; @@ -186,6 +209,18 @@ HWTEST_F(ContainerTest, ItPidContainer030, TestSize.Level0) { ItPidContainer030(); } + +/** +* @tc.name: Container_Pid_Test_031 +* @tc.desc: pid container function test case +* @tc.type: FUNC +* @tc.require: issueI6D9Y0 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItPidContainer031, TestSize.Level0) +{ + ItPidContainer031(); +} #endif #if defined(LOSCFG_USER_TEST_UTS_CONTAINER) /** @@ -223,6 +258,30 @@ HWTEST_F(ContainerTest, ItUtsContainer004, TestSize.Level0) { ItUtsContainer004(); } + +/** +* @tc.name: Container_UTS_Test_005 +* @tc.desc: uts container function test case +* @tc.type: FUNC +* @tc.require: issueI6D9Y0 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItUtsContainer005, TestSize.Level0) +{ + ItUtsContainer005(); +} + +/** +* @tc.name: Container_UTS_Test_006 +* @tc.desc: uts container function test case +* @tc.type: FUNC +* @tc.require: issueI6D9Y0 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItUtsContainer006, TestSize.Level0) +{ + ItUtsContainer006(); +} #endif #if defined(LOSCFG_USER_TEST_MNT_CONTAINER) @@ -310,6 +369,18 @@ HWTEST_F(ContainerTest, ItMntContainer007, TestSize.Level0) ItMntContainer007(); } +/** +* @tc.name: Container_MNT_Test_008 +* @tc.desc: mnt container function test case +* @tc.type: FUNC +* @tc.require: issueI6D9Y0 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItMntContainer008, TestSize.Level0) +{ + ItMntContainer008(); +} + /** * @tc.name: chroot_Test_001 * @tc.desc: chroot function test case @@ -348,6 +419,18 @@ HWTEST_F(ContainerTest, ItIpcContainer001, TestSize.Level0) ItIpcContainer001(); } +/** +* @tc.name: Container_IPC_Test_002 +* @tc.desc: ipc container function test case +* @tc.type: FUNC +* @tc.require: issueI6D9Y0 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItIpcContainer002, TestSize.Level0) +{ + ItIpcContainer002(); +} + /** * @tc.name: Container_IPC_Test_003 * @tc.desc: ipc container function test case @@ -383,6 +466,18 @@ HWTEST_F(ContainerTest, ItIpcContainer005, TestSize.Level0) { ItIpcContainer005(); } + +/** +* @tc.name: Container_IPC_Test_006 +* @tc.desc: ipc container function test case +* @tc.type: FUNC +* @tc.require: issueI6D9Y0 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItIpcContainer006, TestSize.Level0) +{ + ItIpcContainer006(); +} #endif #if defined(LOSCFG_USER_TEST_TIME_CONTAINER) @@ -410,6 +505,18 @@ HWTEST_F(ContainerTest, ItTimeContainer002, TestSize.Level0) ItTimeContainer002(); } +/** +* @tc.name: Container_TIME_Test_003 +* @tc.desc: time container function test case +* @tc.type: FUNC +* @tc.require: issueI6D9Y0 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItTimeContainer003, TestSize.Level0) +{ + ItTimeContainer003(); +} + /** * @tc.name: Container_TIME_Test_004 * @tc.desc: time container function test case diff --git a/testsuites/unittest/container/It_container_test.h b/testsuites/unittest/container/It_container_test.h index 33cd7fc912e34d5e4992957463320dcb78c060d8..526bbc8dcc0986a71e68ae6447650e493045e598 100644 --- a/testsuites/unittest/container/It_container_test.h +++ b/testsuites/unittest/container/It_container_test.h @@ -95,6 +95,8 @@ int ChildFunction(void *args); pid_t CloneWrapper(int (*func)(void *), int flag, void *args); +int WaitChild(pid_t pid, int *status, int errNo1, int errNo2); + std::string GenContainerLinkPath(int pid, const std::string& containerType); extern std::string ReadlinkContainer(int pid, const std::string& containerType); @@ -147,11 +149,14 @@ void ItPidContainer027(void); void ItPidContainer028(void); void ItPidContainer029(void); void ItPidContainer030(void); +void ItPidContainer031(void); #endif #if defined(LOSCFG_USER_TEST_UTS_CONTAINER) void ItUtsContainer001(void); void ItUtsContainer002(void); void ItUtsContainer004(void); +void ItUtsContainer005(void); +void ItUtsContainer006(void); #endif #if defined(LOSCFG_USER_TEST_MNT_CONTAINER) void ItMntContainer001(void); diff --git a/testsuites/unittest/container/config.gni b/testsuites/unittest/container/config.gni index 310a35525a559e37a39a0451a4569eedcc5b1960..a43f6dce78b67159a6bbf2ddaec973b3a6ceb1a1 100644 --- a/testsuites/unittest/container/config.gni +++ b/testsuites/unittest/container/config.gni @@ -49,6 +49,7 @@ if (defined(LOSCFG_USER_TEST_PID_CONTAINER)) { "$TEST_UNITTEST_DIR/container/smoke/It_pid_container_028.cpp", "$TEST_UNITTEST_DIR/container/smoke/It_pid_container_029.cpp", "$TEST_UNITTEST_DIR/container/smoke/It_pid_container_030.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_pid_container_031.cpp", ] sources_full += [ "$TEST_UNITTEST_DIR/container/full/It_pid_container_001.cpp", @@ -81,6 +82,8 @@ if (defined(LOSCFG_USER_TEST_UTS_CONTAINER)) { "$TEST_UNITTEST_DIR/container/smoke/It_uts_container_001.cpp", "$TEST_UNITTEST_DIR/container/smoke/It_uts_container_002.cpp", "$TEST_UNITTEST_DIR/container/smoke/It_uts_container_004.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_uts_container_005.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_uts_container_006.cpp", ] sources_full += [ "$TEST_UNITTEST_DIR/container/full/It_uts_container_003.cpp" ] diff --git a/testsuites/unittest/container/full/It_pid_container_010.cpp b/testsuites/unittest/container/full/It_pid_container_010.cpp index e3a0093b633f135296d78c8071e58d1f221ab63d..f947796f7a24ece21803b4b034619fa66307d984 100644 --- a/testsuites/unittest/container/full/It_pid_container_010.cpp +++ b/testsuites/unittest/container/full/It_pid_container_010.cpp @@ -35,6 +35,7 @@ static int ChildFun(void *p) int ret; int currGid = getpgrp(); if (currGid != CONTAINER_FIRST_PID) { + printf("ChildFun pid %d currGid %d\n", getpid(), currGid); return EXIT_CODE_ERRNO_1; } diff --git a/testsuites/unittest/container/smoke/It_ipc_container_002.cpp b/testsuites/unittest/container/smoke/It_ipc_container_002.cpp index 612089fcc787452f59da3c132c8aa528cd163b27..38f6655e8f5b022ed6be361074ec4d84b094fc52 100644 --- a/testsuites/unittest/container/smoke/It_ipc_container_002.cpp +++ b/testsuites/unittest/container/smoke/It_ipc_container_002.cpp @@ -118,6 +118,12 @@ void ItIpcContainer002(void) ret = mq_send(mqueue, msgptr, strlen(msgptr), 0); ASSERT_EQ(ret, 0); + ret = mq_close(mqueue); + ASSERT_EQ(ret, 0); + + ret = mq_unlink(mqname); + ASSERT_EQ(ret, 0); + childPid = clone(childFunc, stackTop, CLONE_NEWIPC | SIGCHLD, &arg); ASSERT_NE(childPid, -1); diff --git a/testsuites/unittest/container/smoke/It_pid_container_028.cpp b/testsuites/unittest/container/smoke/It_pid_container_028.cpp index 878207f60c8be218e02ab39dee9335284ce1c5ee..846996c2a7c527383200ea3d787beed16992a3c9 100644 --- a/testsuites/unittest/container/smoke/It_pid_container_028.cpp +++ b/testsuites/unittest/container/smoke/It_pid_container_028.cpp @@ -100,7 +100,7 @@ static int ChildFunClone1(void *p) if (pstk == NULL) { return EXIT_CODE_ERRNO_4; } - int childPid = clone(ChildFunClone2, (char *)pstk + STACK_SIZE, CLONE_NEWPID | SIGCHLD, NULL); + int childPid = clone(ChildFunClone2, (char *)pstk + STACK_SIZE, SIGCHLD, NULL); free(pstk); if (childPid == -1) { return EXIT_CODE_ERRNO_5; diff --git a/testsuites/unittest/container/smoke/It_pid_container_029.cpp b/testsuites/unittest/container/smoke/It_pid_container_029.cpp index a61d57c7835d4a777b79e2710c687db8d424ca32..e1ff97ac5d746ebabd786a70eaa2aeaf30170828 100644 --- a/testsuites/unittest/container/smoke/It_pid_container_029.cpp +++ b/testsuites/unittest/container/smoke/It_pid_container_029.cpp @@ -79,12 +79,12 @@ static int ChildFunClone1(void *p) return EXIT_CODE_ERRNO_4; } int childPid = clone(ChildFunClone2, (char *)pstk + STACK_SIZE, CLONE_NEWPID | SIGCHLD, NULL); - if (childPid == -1) { + if (childPid != -1) { free(pstk); return EXIT_CODE_ERRNO_5; } - int childPid1 = clone(ChildFunClone3, (char *)pstk + STACK_SIZE, CLONE_NEWPID | SIGCHLD, NULL); + int childPid1 = clone(ChildFunClone3, (char *)pstk + STACK_SIZE, SIGCHLD, NULL); free(pstk); if (childPid1 == -1) { return EXIT_CODE_ERRNO_6; @@ -95,18 +95,6 @@ static int ChildFunClone1(void *p) return EXIT_CODE_ERRNO_7; } - ret = waitpid(childPid, &status, 0); - if (ret != childPid) { - return EXIT_CODE_ERRNO_8; - } - ret = WIFEXITED(status); - if (ret == 0) { - return EXIT_CODE_ERRNO_9; - } - ret = WEXITSTATUS(status); - if (ret != 0) { - return EXIT_CODE_ERRNO_10; - } ret = waitpid(childPid1, &status, 0); if (ret != childPid1) { return EXIT_CODE_ERRNO_11; diff --git a/testsuites/unittest/container/smoke/It_pid_container_030.cpp b/testsuites/unittest/container/smoke/It_pid_container_030.cpp index 8eb8294607d0bdad7403bd5cbf94ad891413a1d9..04fb973872da2f922819281cd280d833b4e3b167 100644 --- a/testsuites/unittest/container/smoke/It_pid_container_030.cpp +++ b/testsuites/unittest/container/smoke/It_pid_container_030.cpp @@ -33,9 +33,10 @@ static int ChildFunClone3(void *p) { (void)p; auto pid = getpid(); - if (pid == CONTAINER_SECOND_PID) { + if (pid != CONTAINER_SECOND_PID) { return EXIT_CODE_ERRNO_1; } + sleep(2); /* dealy 2s */ return 0; } @@ -46,14 +47,14 @@ static int ChildFunClone2(void *p) if (pid != CONTAINER_FIRST_PID) { return EXIT_CODE_ERRNO_1; } + sleep(2); /* dealy 2s */ return 0; } static int ChildFunClone1(void *p) { (void)p; - int ret; - int status; + int ret, status; const char *containerType = "pid"; const char *containerType1 = "pid_for_children"; @@ -78,46 +79,39 @@ static int ChildFunClone1(void *p) if (pstk == NULL) { return EXIT_CODE_ERRNO_4; } - int childPid = clone(ChildFunClone2, (char *)pstk + STACK_SIZE, CLONE_NEWPID | SIGCHLD, NULL); + int childPid = clone(ChildFunClone2, (char *)pstk + STACK_SIZE, SIGCHLD, NULL); if (childPid == -1) { free(pstk); return EXIT_CODE_ERRNO_5; } + auto linkBuffer2 = ReadlinkContainer(childPid, containerType); + int childPid1 = clone(ChildFunClone3, (char *)pstk + STACK_SIZE, SIGCHLD, NULL); free(pstk); if (childPid1 == -1) { return EXIT_CODE_ERRNO_6; } - ret = unshare(CLONE_NEWPID); - if (ret != -1) { + auto linkBuffer3 = ReadlinkContainer(childPid1, containerType); + ret = linkBuffer3.compare(linkBuffer2); + if (ret != 0) { return EXIT_CODE_ERRNO_7; } - ret = waitpid(childPid, &status, 0); - if (ret != childPid) { + ret = unshare(CLONE_NEWPID); + if (ret != -1) { return EXIT_CODE_ERRNO_8; } - ret = WIFEXITED(status); - if (ret == 0) { - return EXIT_CODE_ERRNO_9; - } - ret = WEXITSTATUS(status); + + ret = WaitChild(childPid1, &status, EXIT_CODE_ERRNO_9, EXIT_CODE_ERRNO_10); if (ret != 0) { - return EXIT_CODE_ERRNO_10; + return ret; } - ret = waitpid(childPid1, &status, 0); - if (ret != childPid1) { - return EXIT_CODE_ERRNO_11; - } - ret = WIFEXITED(status); - if (ret == 0) { - return EXIT_CODE_ERRNO_12; - } - ret = WEXITSTATUS(status); + + ret = WaitChild(childPid, &status, EXIT_CODE_ERRNO_11, EXIT_CODE_ERRNO_12); if (ret != 0) { - return EXIT_CODE_ERRNO_13; + return ret; } return 0; } diff --git a/testsuites/unittest/container/smoke/It_pid_container_031.cpp b/testsuites/unittest/container/smoke/It_pid_container_031.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4bbbbc6116552f19a1b168185c8823476d0e9ea8 --- /dev/null +++ b/testsuites/unittest/container/smoke/It_pid_container_031.cpp @@ -0,0 +1,146 @@ +/* + * 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" + +static const int BUF_SIZE = 100; + +static int ChildFun2(void *p) +{ + (void)p; + sleep(3); /* 3: delay 3s */ + return 0; +} + +static int ChildFun1(void *p) +{ + (void)p; + sleep(6); /* 6: delay 6s */ + return 0; +} + +static int ChildFun(void *p) +{ + (void)p; + int status, ret; + const char *containerType = "pid"; + const char *containerType1 = "pid_for_children"; + char targetpath[BUF_SIZE] = {0}; + auto linkBuffer1 = ReadlinkContainer(getpid(), containerType); + + int childPid = clone(ChildFun1, NULL, CLONE_NEWPID | SIGCHLD, NULL); + if (childPid == -1) { + return EXIT_CODE_ERRNO_1; + } + auto linkBuffer2 = ReadlinkContainer(childPid, containerType); + ret = linkBuffer2.compare(linkBuffer1); + if (ret == 0) { + return EXIT_CODE_ERRNO_2; + } + + ret = sprintf_s(targetpath, BUF_SIZE, "/proc/%d/container/pid", childPid); + if (ret < 0) { + return EXIT_CODE_ERRNO_16; + } + int fd = open(targetpath, O_RDONLY | O_CLOEXEC); + if (fd == -1) { + return EXIT_CODE_ERRNO_3; + } + + ret = setns(fd, CLONE_NEWPID); + if (ret != 0) { + close(fd); + return EXIT_CODE_ERRNO_4; + } + + close(fd); + + auto linkBuffer6 = ReadlinkContainer(getpid(), containerType); + ret = linkBuffer6.compare(linkBuffer1); + if (ret != 0) { + return EXIT_CODE_ERRNO_17; + } + + auto linkBuffer3 = ReadlinkContainer(getpid(), containerType1); + ret = linkBuffer3.compare(linkBuffer2); + if (ret != 0) { + return EXIT_CODE_ERRNO_5; + } + + int childPid1 = clone(ChildFun2, NULL, SIGCHLD, NULL); + if (childPid1 == -1) { + return EXIT_CODE_ERRNO_6; + } + + auto linkBuffer4 = ReadlinkContainer(childPid1, containerType); + ret = linkBuffer4.compare(linkBuffer3); + if (ret != 0) { + return EXIT_CODE_ERRNO_7; + } + + int childPid2 = clone(ChildFun2, NULL, CLONE_NEWUTS | SIGCHLD, NULL); + if (childPid2 == -1) { + return EXIT_CODE_ERRNO_8; + } + + auto linkBuffer5 = ReadlinkContainer(childPid2, containerType); + ret = linkBuffer5.compare(linkBuffer4); + if (ret != 0) { + return EXIT_CODE_ERRNO_9; + } + + ret = WaitChild(childPid2, &status, EXIT_CODE_ERRNO_10, EXIT_CODE_ERRNO_11); + if (ret != 0) { + return ret; + } + + ret = WaitChild(childPid1, &status, EXIT_CODE_ERRNO_12, EXIT_CODE_ERRNO_13); + if (ret != 0) { + return ret; + } + ret = WaitChild(childPid, &status, EXIT_CODE_ERRNO_14, EXIT_CODE_ERRNO_15); + if (ret != 0) { + return ret; + } + return 0; +} + +void ItPidContainer031(void) +{ + int status; + int childPid = clone(ChildFun, NULL, CLONE_NEWPID | SIGCHLD, NULL); + ASSERT_NE(childPid, -1); + + int ret = waitpid(childPid, &status, 0); + ASSERT_EQ(ret, childPid); + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, 0); +} diff --git a/testsuites/unittest/container/smoke/It_uts_container_005.cpp b/testsuites/unittest/container/smoke/It_uts_container_005.cpp new file mode 100644 index 0000000000000000000000000000000000000000..537a9f2edc6016c9c51bc93f0be13b8f7b220787 --- /dev/null +++ b/testsuites/unittest/container/smoke/It_uts_container_005.cpp @@ -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. + */ +#include "It_container_test.h" + +const int TIMER_INTERVAL_3S = 2; + +static int ChildFun(void *p) +{ + (void)p; + sleep(TIMER_INTERVAL_3S); + return EXIT_CODE_ERRNO_3; +} + +void ItUtsContainer005(void) +{ + pid_t callerPid; + int childPid; + int fd = -1; + int ret; + int status; + int setFlag; + char targetpath[100]; + char old_uts_link[100]; + char new_uts_link[100]; + const char *containerType = "uts"; + + callerPid = getpid(); + childPid = clone(ChildFun, NULL, CLONE_NEWUTS | SIGCHLD, NULL); + ASSERT_NE(childPid, -1); + + auto linkBuffer = ReadlinkContainer(callerPid, containerType); + ASSERT_TRUE(linkBuffer.c_str() != NULL); + ret = sprintf_s(old_uts_link, sizeof(old_uts_link), "%s", linkBuffer.c_str()); + ASSERT_NE(ret, -1); + + ret = sprintf_s(targetpath, sizeof(targetpath), "/proc/%d/container/uts", childPid); + ASSERT_NE(ret, -1); + fd = open(targetpath, O_RDONLY | O_CLOEXEC); + ASSERT_NE(fd, -1); + + setFlag = CLONE_NEWUTS; + ret = setns(fd, setFlag); + ASSERT_NE(ret, -1); + + /* NOTE: close fd, otherwise test fail */ + ret = close(fd); + fd = -1; + ASSERT_NE(ret, -1); + + linkBuffer = ReadlinkContainer(callerPid, containerType); + + ret = sprintf_s(new_uts_link, sizeof(new_uts_link), "%s", linkBuffer.c_str()); + ASSERT_NE(ret, -1); + ASSERT_STRNE(old_uts_link, new_uts_link); + + ret = waitpid(childPid, &status, 0); + ASSERT_EQ(ret, childPid); + + int exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, EXIT_CODE_ERRNO_3); + + ret = setns(fd, setFlag); + ASSERT_EQ(ret, -1); +} diff --git a/testsuites/unittest/container/smoke/It_uts_container_006.cpp b/testsuites/unittest/container/smoke/It_uts_container_006.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d5f3b8e5606932019cfa50957aa84b60288d2bf3 --- /dev/null +++ b/testsuites/unittest/container/smoke/It_uts_container_006.cpp @@ -0,0 +1,64 @@ +/* + * 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" + +void ItUtsContainer006(void) +{ + std::string containerType = "uts"; + + int parentPid = getpid(); + auto parentlink = ReadlinkContainer(parentPid, containerType); + + int childsPid = CloneWrapper(ChildFunction, CLONE_NEWUTS, NULL); + ASSERT_NE(childsPid, -1); + auto childlink = ReadlinkContainer(childsPid, containerType); + + std::string filePath = GenContainerLinkPath(childsPid, containerType); + int fd = open(filePath.c_str(), O_RDONLY); + ASSERT_NE(fd, -1); + + int ret = setns(fd, CLONE_NEWUTS); + ASSERT_NE(ret, -1); + (void)close(fd); + + auto parentlink1 = ReadlinkContainer(parentPid, containerType); + + ret = parentlink.compare(parentlink1); + ASSERT_NE(ret, 0); + ret = parentlink1.compare(childlink); + ASSERT_EQ(ret, 0); + + int status; + ret = waitpid(childsPid, &status, 0); + ASSERT_EQ(ret, childsPid); + + int exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, 0); +} diff --git a/testsuites/unittest/fuzz/main.cpp b/testsuites/unittest/fuzz/main.cpp index 2f372b55870eb0d10d295ad3c801152a7489b473..3a231efeb0f9fb99fe7fafeef8a132426540f4df 100644 --- a/testsuites/unittest/fuzz/main.cpp +++ b/testsuites/unittest/fuzz/main.cpp @@ -87,5 +87,6 @@ int main() TestClone(); TestUnshare(); TestChroot(); + TestSetns(); return 0; }