未验证 提交 c0f5d437 编写于 作者: O openharmony_ci 提交者: Gitee

!1112 feat: 支持setns接口

Merge pull request !1112 from zhushengle/setns
......@@ -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
......
......@@ -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
......@@ -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
}
......
......@@ -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
}
......
......@@ -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);
}
......
......@@ -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)
......
......@@ -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();
......
......@@ -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_ */
......@@ -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()
{
......
......@@ -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
......@@ -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;
......
......@@ -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;
......
......@@ -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) {
......
......@@ -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);
......
......@@ -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;
......
......@@ -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;
......
......@@ -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 */
......@@ -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);
......
......@@ -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);
......
......@@ -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 */
......@@ -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
}
......
......@@ -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);
......
......@@ -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 */
......@@ -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
}
......
......@@ -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();
}
......
......@@ -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);
......
......@@ -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
......
......@@ -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)
......
......@@ -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
......
......@@ -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);
......
......@@ -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" ]
......
......@@ -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;
}
......
......@@ -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);
......
......@@ -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;
......
......@@ -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;
......
......@@ -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;
}
......
/*
* 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);
}
/*
* 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);
}
/*
* 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);
}
......@@ -87,5 +87,6 @@ int main()
TestClone();
TestUnshare();
TestChroot();
TestSetns();
return 0;
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册