feat: 支持网络容器
BREAKING CHANGE: 支持网络容器对外变更: 1.支持网络容器 2.setns, clone, unshare接口支持CLONE_NEWNET Close #I6HPH2 Signed-off-by: zhushengle <zhushengle@huawei.com> Change-Id: Ibaa11056982d465d4006680c8d3fa4ae2b9f25b5
This commit is contained in:
@@ -108,6 +108,11 @@ config USER_CONTAINER
|
||||
default n
|
||||
depends on KERNEL_CONTAINER
|
||||
|
||||
config NET_CONTAINER
|
||||
bool "Enable net container"
|
||||
default n
|
||||
depends on KERNEL_CONTAINER
|
||||
|
||||
######################### config options of extended #####################
|
||||
source "kernel/extended/Kconfig"
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ kernel_module(module_name) {
|
||||
"container/los_credentials.c",
|
||||
"container/los_ipc_container.c",
|
||||
"container/los_mnt_container.c",
|
||||
"container/los_net_container.c",
|
||||
"container/los_pid_container.c",
|
||||
"container/los_time_container.c",
|
||||
"container/los_user_container.c",
|
||||
|
||||
@@ -85,6 +85,10 @@ UINT32 OsGetContainerLimit(ContainerType type)
|
||||
case TIME_CONTAINER:
|
||||
case TIME_CHILD_CONTAINER:
|
||||
return g_containerLimit.timeLimit;
|
||||
#endif
|
||||
#ifdef LOSCFG_NET_CONTAINER
|
||||
case NET_CONTAINER:
|
||||
return g_containerLimit.netLimit;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
@@ -145,6 +149,11 @@ UINT32 OsSetContainerLimit(ContainerType type, UINT32 value)
|
||||
case TIME_CHILD_CONTAINER:
|
||||
g_containerLimit.timeLimit = value;
|
||||
break;
|
||||
#endif
|
||||
#ifdef LOSCFG_NET_CONTAINER
|
||||
case NET_CONTAINER:
|
||||
g_containerLimit.netLimit = value;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
@@ -182,6 +191,10 @@ UINT32 OsGetContainerCount(ContainerType type)
|
||||
case TIME_CONTAINER:
|
||||
case TIME_CHILD_CONTAINER:
|
||||
return OsGetTimeContainerCount();
|
||||
#endif
|
||||
#ifdef LOSCFG_NET_CONTAINER
|
||||
case NET_CONTAINER:
|
||||
return OsGetNetContainerCount();
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
@@ -216,6 +229,10 @@ VOID OsInitRootContainer(VOID)
|
||||
g_containerLimit.timeLimit = LOSCFG_KERNEL_CONTAINER_DEFAULT_LIMIT;
|
||||
(VOID)OsInitRootTimeContainer(&g_rootContainer.timeContainer);
|
||||
g_rootContainer.timeForChildContainer = g_rootContainer.timeContainer;
|
||||
#endif
|
||||
#ifdef LOSCFG_NET_CONTAINER
|
||||
g_containerLimit.netLimit = LOSCFG_KERNEL_CONTAINER_DEFAULT_LIMIT;
|
||||
(VOID)OsInitRootNetContainer(&g_rootContainer.netContainer);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
@@ -272,10 +289,43 @@ STATIC UINT32 CopyContainers(UINTPTR flags, LosProcessCB *child, LosProcessCB *p
|
||||
if (ret != LOS_OK) {
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
#ifdef LOSCFG_NET_CONTAINER
|
||||
ret = OsCopyNetContainer(flags, child, parent);
|
||||
if (ret != LOS_OK) {
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
STATIC INLINE UINT32 GetContainerFlagsMask(VOID)
|
||||
{
|
||||
UINT32 mask = 0;
|
||||
#ifdef LOSCFG_PID_CONTAINER
|
||||
mask |= CLONE_NEWPID;
|
||||
#endif
|
||||
#ifdef LOSCFG_MNT_CONTAINER
|
||||
mask |= CLONE_NEWNS;
|
||||
#endif
|
||||
#ifdef LOSCFG_IPC_CONTAINER
|
||||
mask |= CLONE_NEWIPC;
|
||||
#endif
|
||||
#ifdef LOSCFG_USER_CONTAINER
|
||||
mask |= CLONE_NEWUSER;
|
||||
#endif
|
||||
#ifdef LOSCFG_TIME_CONTAINER
|
||||
mask |= CLONE_NEWTIME;
|
||||
#endif
|
||||
#ifdef LOSCFG_NET_CONTAINER
|
||||
mask |= CLONE_NEWNET;
|
||||
#endif
|
||||
#ifdef LOSCFG_UTS_CONTAINER
|
||||
mask |= CLONE_NEWUTS;
|
||||
#endif
|
||||
return mask;
|
||||
}
|
||||
|
||||
/*
|
||||
* called from clone. This now handles copy for Container and all
|
||||
* namespaces therein.
|
||||
@@ -288,7 +338,7 @@ UINT32 OsCopyContainers(UINTPTR flags, LosProcessCB *child, LosProcessCB *parent
|
||||
flags &= ~CLONE_NEWTIME;
|
||||
#endif
|
||||
|
||||
if (!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC | CLONE_NEWPID | CLONE_NEWNET | CLONE_NEWTIME))) {
|
||||
if (!(flags & GetContainerFlagsMask())) {
|
||||
#ifdef LOSCFG_PID_CONTAINER
|
||||
if (parent->container->pidContainer != parent->container->pidForChildContainer) {
|
||||
goto CREATE_CONTAINER;
|
||||
@@ -327,7 +377,7 @@ VOID OsContainerFree(LosProcessCB *processCB)
|
||||
}
|
||||
}
|
||||
|
||||
VOID OsContainersDestroy(LosProcessCB *processCB)
|
||||
VOID OsOsContainersDestroyEarly(LosProcessCB *processCB)
|
||||
{
|
||||
/* All processes in the container must be destroyed before the container is destroyed. */
|
||||
#ifdef LOSCFG_PID_CONTAINER
|
||||
@@ -336,6 +386,13 @@ VOID OsContainersDestroy(LosProcessCB *processCB)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef LOSCFG_MNT_CONTAINER
|
||||
OsMntContainerDestroy(processCB->container);
|
||||
#endif
|
||||
}
|
||||
|
||||
VOID OsContainersDestroy(LosProcessCB *processCB)
|
||||
{
|
||||
#ifdef LOSCFG_USER_CONTAINER
|
||||
OsUserContainerDestroy(processCB);
|
||||
#endif
|
||||
@@ -344,10 +401,6 @@ VOID OsContainersDestroy(LosProcessCB *processCB)
|
||||
OsUtsContainerDestroy(processCB->container);
|
||||
#endif
|
||||
|
||||
#ifdef LOSCFG_MNT_CONTAINER
|
||||
OsMntContainerDestroy(processCB->container);
|
||||
#endif
|
||||
|
||||
#ifdef LOSCFG_IPC_CONTAINER
|
||||
OsIpcContainerDestroy(processCB->container);
|
||||
#endif
|
||||
@@ -356,6 +409,10 @@ VOID OsContainersDestroy(LosProcessCB *processCB)
|
||||
OsTimeContainerDestroy(processCB->container);
|
||||
#endif
|
||||
|
||||
#ifdef LOSCFG_NET_CONTAINER
|
||||
OsNetContainerDestroy(processCB->container);
|
||||
#endif
|
||||
|
||||
#ifndef LOSCFG_PID_CONTAINER
|
||||
UINT32 intSave;
|
||||
SCHEDULER_LOCK(intSave);
|
||||
@@ -395,6 +452,10 @@ STATIC VOID DeInitContainers(UINT32 flags, Container *container, LosProcessCB *p
|
||||
OsTimeContainerDestroy(container);
|
||||
#endif
|
||||
|
||||
#ifdef LOSCFG_NET_CONTAINER
|
||||
OsNetContainerDestroy(container);
|
||||
#endif
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
LOS_AtomicDec(&container->rc);
|
||||
if (LOS_AtomicRead(&container->rc) == 0) {
|
||||
@@ -438,6 +499,10 @@ UINT32 OsGetContainerID(LosProcessCB *processCB, ContainerType type)
|
||||
return OsGetTimeContainerID(container->timeContainer);
|
||||
case TIME_CHILD_CONTAINER:
|
||||
return OsGetTimeContainerID(container->timeForChildContainer);
|
||||
#endif
|
||||
#ifdef LOSCFG_NET_CONTAINER
|
||||
case NET_CONTAINER:
|
||||
return OsGetNetContainerID(container->netContainer);
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
@@ -477,6 +542,12 @@ STATIC UINT32 UnshareCreateNewContainers(UINT32 flags, LosProcessCB *curr, Conta
|
||||
if (ret != LOS_OK) {
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
#ifdef LOSCFG_NET_CONTAINER
|
||||
ret = OsUnshareNetContainer(flags, curr, newContainer);
|
||||
if (ret != LOS_OK) {
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
@@ -487,8 +558,7 @@ INT32 OsUnshare(UINT32 flags)
|
||||
UINT32 intSave;
|
||||
LosProcessCB *curr = OsCurrProcessGet();
|
||||
Container *oldContainer = curr->container;
|
||||
UINT32 unshareFlags = CLONE_NEWPID | CLONE_NEWTIME | CLONE_NEWUTS | CLONE_NEWNS | CLONE_NEWIPC | CLONE_NEWUSER;
|
||||
|
||||
UINT32 unshareFlags = GetContainerFlagsMask();
|
||||
if (!(flags & unshareFlags) || ((flags & (~unshareFlags)) != 0)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -547,6 +617,8 @@ STATIC UINT32 SetNsGetFlagByContainerType(UINT32 containerType)
|
||||
case TIME_CONTAINER:
|
||||
case TIME_CHILD_CONTAINER:
|
||||
return CLONE_NEWTIME;
|
||||
case NET_CONTAINER:
|
||||
return CLONE_NEWNET;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -585,13 +657,19 @@ STATIC UINT32 SetNsCreateNewContainers(UINT32 flags, Container *newContainer, Co
|
||||
if (ret != LOS_OK) {
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
#ifdef LOSCFG_NET_CONTAINER
|
||||
ret = OsSetNsNetContainer(flags, container, newContainer);
|
||||
if (ret != LOS_OK) {
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
STATIC UINT32 SetNsParamCheck(INT32 fd, INT32 type, UINT32 *flag, LosProcessCB **target)
|
||||
{
|
||||
UINT32 typeMask = CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWPID | CLONE_NEWIPC | CLONE_NEWTIME | CLONE_NEWUSER;
|
||||
UINT32 typeMask = GetContainerFlagsMask();
|
||||
*flag = (UINT32)(type & typeMask);
|
||||
UINT32 containerType = 0;
|
||||
|
||||
|
||||
343
kernel/base/container/los_net_container.c
Normal file
343
kernel/base/container/los_net_container.c
Normal file
@@ -0,0 +1,343 @@
|
||||
/*
|
||||
* 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 <sched.h>
|
||||
#include "los_net_container_pri.h"
|
||||
#include "los_config.h"
|
||||
#include "los_memory.h"
|
||||
#include "los_process_pri.h"
|
||||
|
||||
#ifdef LOSCFG_NET_CONTAINER
|
||||
STATIC UINT32 g_currentNetContainerNum = 0;
|
||||
STATIC NetContainer *g_rootNetContainer = NULL;
|
||||
|
||||
STATIC struct netif *NetifAlloc(VOID)
|
||||
{
|
||||
UINT32 size = sizeof(struct netif);
|
||||
struct netif *netif = LOS_MemAlloc(m_aucSysMem1, size);
|
||||
if (netif == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
(VOID)memset_s(netif, size, 0, size);
|
||||
|
||||
return netif;
|
||||
}
|
||||
|
||||
STATIC VOID FreeNetif(struct netif *netif)
|
||||
{
|
||||
if (netif != NULL) {
|
||||
if (netif->peer != NULL) {
|
||||
netif_remove(netif->peer);
|
||||
(VOID)LOS_MemFree(m_aucSysMem1, netif->peer);
|
||||
}
|
||||
netif_remove(netif);
|
||||
(VOID)LOS_MemFree(m_aucSysMem1, netif);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC UINT32 CreateVethNetif(NetContainer *netContainer, struct netif **veth)
|
||||
{
|
||||
struct netif *netif = NetifAlloc();
|
||||
if (netif == NULL) {
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
veth_init(netif, netContainer->group);
|
||||
|
||||
*veth = netif;
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
STATIC UINT32 InitVethPair(NetContainer *netContainer)
|
||||
{
|
||||
struct netif *vethOfNetContainer = NULL;
|
||||
struct netif *vethOfRootNetContainer = NULL;
|
||||
|
||||
UINT32 ret = CreateVethNetif(netContainer, &vethOfNetContainer);
|
||||
if (ret != LOS_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = CreateVethNetif(g_rootNetContainer, &vethOfRootNetContainer);
|
||||
if (ret != LOS_OK) {
|
||||
FreeNetif(vethOfNetContainer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
vethOfNetContainer->peer = vethOfRootNetContainer;
|
||||
vethOfRootNetContainer->peer = vethOfNetContainer;
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
STATIC UINT32 InitLoopNetif(NetContainer *netContainer)
|
||||
{
|
||||
struct netif *loop_netif = NetifAlloc();
|
||||
if (loop_netif == NULL) {
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
netContainer->group->loop_netif = loop_netif;
|
||||
netif_init(netContainer->group);
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
STATIC UINT32 InitContainerNetifs(NetContainer *netContainer)
|
||||
{
|
||||
UINT32 ret = InitLoopNetif(netContainer);
|
||||
if (ret != LOS_OK) {
|
||||
return ret;
|
||||
}
|
||||
return InitVethPair(netContainer);
|
||||
}
|
||||
|
||||
STATIC UINT32 InitNetGroup(NetContainer *netContainer)
|
||||
{
|
||||
UINT32 size = sizeof(struct net_group);
|
||||
struct net_group *group = LOS_MemAlloc(m_aucSysMem1, size);
|
||||
if (group == NULL) {
|
||||
return ENOMEM;
|
||||
}
|
||||
(VOID)memset_s(group, size, 0, size);
|
||||
|
||||
netContainer->group = group;
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
STATIC VOID FreeNetContainerGroup(struct net_group *group)
|
||||
{
|
||||
if (group == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct netif *freeNetif = group->netif_list;
|
||||
struct netif *nextNetif = NULL;
|
||||
|
||||
while (freeNetif != NULL) {
|
||||
nextNetif = freeNetif->next;
|
||||
FreeNetif(freeNetif);
|
||||
freeNetif = nextNetif;
|
||||
}
|
||||
}
|
||||
|
||||
VOID OsNetContainerDestroy(Container *container)
|
||||
{
|
||||
UINT32 intSave;
|
||||
if (container == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
NetContainer *netContainer = container->netContainer;
|
||||
if (netContainer == NULL) {
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return;
|
||||
}
|
||||
|
||||
LOS_AtomicDec(&netContainer->rc);
|
||||
if (LOS_AtomicRead(&netContainer->rc) > 0) {
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return;
|
||||
}
|
||||
|
||||
g_currentNetContainerNum--;
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
FreeNetContainerGroup(netContainer->group);
|
||||
container->netContainer = NULL;
|
||||
(VOID)LOS_MemFree(m_aucSysMem1, netContainer->group);
|
||||
(VOID)LOS_MemFree(m_aucSysMem1, netContainer);
|
||||
return;
|
||||
}
|
||||
|
||||
STATIC NetContainer *CreateNewNetContainer(NetContainer *parent)
|
||||
{
|
||||
NetContainer *netContainer = LOS_MemAlloc(m_aucSysMem1, sizeof(NetContainer));
|
||||
if (netContainer == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
(VOID)memset_s(netContainer, sizeof(NetContainer), 0, sizeof(NetContainer));
|
||||
|
||||
netContainer->containerID = OsAllocContainerID();
|
||||
|
||||
if (parent != NULL) {
|
||||
LOS_AtomicSet(&netContainer->rc, 1);
|
||||
} else {
|
||||
LOS_AtomicSet(&netContainer->rc, 3); /* 3: Three system processes */
|
||||
}
|
||||
return netContainer;
|
||||
}
|
||||
|
||||
STATIC UINT32 CreateNetContainer(Container *container, NetContainer *parentContainer)
|
||||
{
|
||||
UINT32 intSave, ret;
|
||||
NetContainer *newNetContainer = CreateNewNetContainer(parentContainer);
|
||||
if (newNetContainer == NULL) {
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
ret = InitNetGroup(newNetContainer);
|
||||
if (ret != LOS_OK) {
|
||||
(VOID)LOS_MemFree(m_aucSysMem1, newNetContainer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = InitContainerNetifs(newNetContainer);
|
||||
if (ret != LOS_OK) {
|
||||
(VOID)LOS_MemFree(m_aucSysMem1, newNetContainer->group);
|
||||
(VOID)LOS_MemFree(m_aucSysMem1, newNetContainer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
g_currentNetContainerNum++;
|
||||
container->netContainer = newNetContainer;
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
UINT32 OsCopyNetContainer(UINTPTR flags, LosProcessCB *child, LosProcessCB *parent)
|
||||
{
|
||||
UINT32 intSave;
|
||||
NetContainer *currNetContainer = parent->container->netContainer;
|
||||
|
||||
if (!(flags & CLONE_NEWNET)) {
|
||||
SCHEDULER_LOCK(intSave);
|
||||
LOS_AtomicInc(&currNetContainer->rc);
|
||||
child->container->netContainer = currNetContainer;
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
if (OsContainerLimitCheck(NET_CONTAINER, &g_currentNetContainerNum) != LOS_OK) {
|
||||
return EPERM;
|
||||
}
|
||||
|
||||
return CreateNetContainer(child->container, currNetContainer);
|
||||
}
|
||||
|
||||
UINT32 OsUnshareNetContainer(UINTPTR flags, LosProcessCB *curr, Container *newContainer)
|
||||
{
|
||||
UINT32 intSave;
|
||||
NetContainer *parentContainer = curr->container->netContainer;
|
||||
|
||||
if (!(flags & CLONE_NEWNET)) {
|
||||
SCHEDULER_LOCK(intSave);
|
||||
newContainer->netContainer = parentContainer;
|
||||
LOS_AtomicInc(&parentContainer->rc);
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
if (OsContainerLimitCheck(NET_CONTAINER, &g_currentNetContainerNum) != LOS_OK) {
|
||||
return EPERM;
|
||||
}
|
||||
|
||||
return CreateNetContainer(newContainer, parentContainer);
|
||||
}
|
||||
|
||||
UINT32 OsSetNsNetContainer(UINT32 flags, Container *container, Container *newContainer)
|
||||
{
|
||||
if (flags & CLONE_NEWNET) {
|
||||
newContainer->netContainer = container->netContainer;
|
||||
LOS_AtomicInc(&container->netContainer->rc);
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
newContainer->netContainer = OsCurrProcessGet()->container->netContainer;
|
||||
LOS_AtomicInc(&newContainer->netContainer->rc);
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
UINT32 OsGetNetContainerID(NetContainer *netContainer)
|
||||
{
|
||||
if (netContainer == NULL) {
|
||||
return OS_INVALID_VALUE;
|
||||
}
|
||||
|
||||
return netContainer->containerID;
|
||||
}
|
||||
|
||||
STATIC struct net_group *DoGetNetGroupFromCurrProcess(VOID)
|
||||
{
|
||||
LosProcessCB *processCB = OsCurrProcessGet();
|
||||
NetContainer *netContainer = processCB->container->netContainer;
|
||||
return netContainer->group;
|
||||
}
|
||||
|
||||
STATIC VOID DoSetNetifNetGroup(struct netif *netif, struct net_group *group)
|
||||
{
|
||||
netif->group = group;
|
||||
}
|
||||
|
||||
STATIC struct net_group *DoGetNetGroupFromNetif(struct netif *netif)
|
||||
{
|
||||
return netif != NULL ? netif->group : NULL;
|
||||
}
|
||||
|
||||
STATIC VOID DoSetIppcbNetGroup(struct ip_pcb *pcb, struct net_group *group)
|
||||
{
|
||||
pcb->group = group;
|
||||
}
|
||||
|
||||
STATIC struct net_group *DoGetNetGroupFromIppcb(struct ip_pcb *pcb)
|
||||
{
|
||||
return pcb != NULL ? pcb->group : NULL;
|
||||
}
|
||||
|
||||
struct net_group_ops netGroupOps = {
|
||||
.get_curr_process_net_group = DoGetNetGroupFromCurrProcess,
|
||||
.set_netif_net_group = DoSetNetifNetGroup,
|
||||
.get_net_group_from_netif = DoGetNetGroupFromNetif,
|
||||
.set_ippcb_net_group = DoSetIppcbNetGroup,
|
||||
.get_net_group_from_ippcb = DoGetNetGroupFromIppcb,
|
||||
};
|
||||
|
||||
UINT32 OsInitRootNetContainer(NetContainer **netContainer)
|
||||
{
|
||||
UINT32 intSave;
|
||||
NetContainer *newNetContainer = CreateNewNetContainer(NULL);
|
||||
if (newNetContainer == NULL) {
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
newNetContainer->group = get_root_net_group();
|
||||
set_default_net_group_ops(&netGroupOps);
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
g_currentNetContainerNum++;
|
||||
*netContainer = newNetContainer;
|
||||
g_rootNetContainer = newNetContainer;
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
UINT32 OsGetNetContainerCount(VOID)
|
||||
{
|
||||
return g_currentNetContainerNum;
|
||||
}
|
||||
#endif
|
||||
@@ -442,7 +442,7 @@ LITE_OS_SEC_TEXT VOID OsProcessResourcesToFree(LosProcessCB *processCB)
|
||||
#endif
|
||||
|
||||
#ifdef LOSCFG_KERNEL_CONTAINER
|
||||
OsContainersDestroy(processCB);
|
||||
OsOsContainersDestroyEarly(processCB);
|
||||
#endif
|
||||
|
||||
#ifdef LOSCFG_FS_VFS
|
||||
@@ -451,6 +451,11 @@ LITE_OS_SEC_TEXT VOID OsProcessResourcesToFree(LosProcessCB *processCB)
|
||||
}
|
||||
processCB->files = NULL;
|
||||
#endif
|
||||
|
||||
#ifdef LOSCFG_KERNEL_CONTAINER
|
||||
OsContainersDestroy(processCB);
|
||||
#endif
|
||||
|
||||
#ifdef LOSCFG_KERNEL_PLIMITS
|
||||
OsPLimitsDeleteProcess(processCB);
|
||||
#endif
|
||||
@@ -2152,6 +2157,9 @@ LITE_OS_SEC_TEXT INT32 OsClone(UINT32 flags, UINTPTR sp, UINT32 size)
|
||||
#ifdef LOSCFG_USER_CONTAINER
|
||||
cloneFlag |= CLONE_NEWUSER;
|
||||
#endif
|
||||
#ifdef LOSCFG_NET_CONTAINER
|
||||
cloneFlag |= CLONE_NEWNET;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (flags & (~cloneFlag)) {
|
||||
|
||||
@@ -51,6 +51,9 @@
|
||||
#ifdef LOSCFG_TIME_CONTAINER
|
||||
#include "los_time_container_pri.h"
|
||||
#endif
|
||||
#ifdef LOSCFG_NET_CONTAINER
|
||||
#include "los_net_container_pri.h"
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
CONTAINER = 0,
|
||||
@@ -62,6 +65,7 @@ typedef enum {
|
||||
USER_CONTAINER,
|
||||
TIME_CONTAINER,
|
||||
TIME_CHILD_CONTAINER,
|
||||
NET_CONTAINER,
|
||||
CONTAINER_MAX,
|
||||
} ContainerType;
|
||||
|
||||
@@ -84,6 +88,9 @@ typedef struct Container {
|
||||
struct TimeContainer *timeContainer;
|
||||
struct TimeContainer *timeForChildContainer;
|
||||
#endif
|
||||
#ifdef LOSCFG_NET_CONTAINER
|
||||
struct NetContainer *netContainer;
|
||||
#endif
|
||||
} Container;
|
||||
|
||||
typedef struct TagContainerLimit {
|
||||
@@ -105,6 +112,9 @@ typedef struct TagContainerLimit {
|
||||
#ifdef LOSCFG_USER_CONTAINER
|
||||
UINT32 userLimit;
|
||||
#endif
|
||||
#ifdef LOSCFG_NET_CONTAINER
|
||||
UINT32 netLimit;
|
||||
#endif
|
||||
} ContainerLimit;
|
||||
|
||||
VOID OsContainerInitSystemProcess(LosProcessCB *processCB);
|
||||
@@ -113,6 +123,8 @@ VOID OsInitRootContainer(VOID);
|
||||
|
||||
UINT32 OsCopyContainers(UINTPTR flags, LosProcessCB *child, LosProcessCB *parent, UINT32 *processID);
|
||||
|
||||
VOID OsOsContainersDestroyEarly(LosProcessCB *processCB);
|
||||
|
||||
VOID OsContainersDestroy(LosProcessCB *processCB);
|
||||
|
||||
VOID OsContainerFree(LosProcessCB *processCB);
|
||||
|
||||
62
kernel/base/include/los_net_container_pri.h
Normal file
62
kernel/base/include/los_net_container_pri.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _LOS_NET_CONTAINER_PRI_H
|
||||
#define _LOS_NET_CONTAINER_PRI_H
|
||||
#include <lwip/net_group.h>
|
||||
#include <lwip/netif.h>
|
||||
#include <lwip/ip.h>
|
||||
#include "los_atomic.h"
|
||||
|
||||
#ifdef LOSCFG_NET_CONTAINER
|
||||
typedef struct ProcessCB LosProcessCB;
|
||||
struct Container;
|
||||
|
||||
typedef struct NetContainer {
|
||||
Atomic rc;
|
||||
struct net_group *group;
|
||||
UINT32 containerID;
|
||||
} NetContainer;
|
||||
|
||||
UINT32 OsInitRootNetContainer(NetContainer **ipcContainer);
|
||||
|
||||
UINT32 OsCopyNetContainer(UINTPTR flags, LosProcessCB *child, LosProcessCB *parent);
|
||||
|
||||
UINT32 OsUnshareNetContainer(UINTPTR flags, LosProcessCB *curr, struct Container *newContainer);
|
||||
|
||||
UINT32 OsSetNsNetContainer(UINT32 flags, struct Container *container, struct Container *newContainer);
|
||||
|
||||
VOID OsNetContainerDestroy(struct Container *container);
|
||||
|
||||
UINT32 OsGetNetContainerID(NetContainer *ipcContainer);
|
||||
|
||||
UINT32 OsGetNetContainerCount(VOID);
|
||||
#endif
|
||||
#endif /* _LOS_NET_CONTAINER_PRI_H */
|
||||
@@ -206,6 +206,12 @@ STATIC INT32 ShmAllocSegCheck(key_t key, size_t *size, INT32 *segNum)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
#ifdef LOSCFG_KERNEL_IPC_PLIMIT
|
||||
if (OsIPCLimitShmAlloc(*size) != LOS_OK) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = 0; i < IPC_SHM_INFO.shmmni; i++) {
|
||||
if (IPC_SHM_SEGS[i].status & SHM_SEG_FREE) {
|
||||
IPC_SHM_SEGS[i].status &= ~SHM_SEG_FREE;
|
||||
@@ -217,12 +223,6 @@ STATIC INT32 ShmAllocSegCheck(key_t key, size_t *size, INT32 *segNum)
|
||||
if (*segNum < 0) {
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
#ifdef LOSCFG_KERNEL_IPC_PLIMIT
|
||||
if (OsIPCLimitShmAlloc(*size) != LOS_OK) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ VOID OsDevLimitInit(UINTPTR limit)
|
||||
|
||||
VOID *OsDevLimitAlloc(VOID)
|
||||
{
|
||||
ProcDevLimit *plimit = (ProcDevLimit *)LOS_KernelMalloc(sizeof(ProcDevLimit));
|
||||
ProcDevLimit *plimit = (ProcDevLimit *)LOS_MemAlloc(m_aucSysMem1, sizeof(ProcDevLimit));
|
||||
if (plimit == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -67,7 +67,7 @@ STATIC VOID DevAccessListDelete(ProcDevLimit *devLimit)
|
||||
DevAccessItem *tmpItem = NULL;
|
||||
LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(delItem, tmpItem, &devLimit->accessList, DevAccessItem, list) {
|
||||
LOS_ListDelete(&delItem->list);
|
||||
LOS_KernelFree((VOID *)delItem);
|
||||
(VOID)LOS_MemFree(m_aucSysMem1, (VOID *)delItem);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ VOID OsDevLimitFree(UINTPTR limit)
|
||||
}
|
||||
|
||||
DevAccessListDelete(devLimit);
|
||||
LOS_KernelFree(devLimit);
|
||||
(VOID)LOS_MemFree(m_aucSysMem1, devLimit);
|
||||
}
|
||||
|
||||
STATIC UINT32 DevLimitCopyAccess(ProcDevLimit *devLimitDest, ProcDevLimit *devLimitSrc)
|
||||
@@ -88,7 +88,7 @@ STATIC UINT32 DevLimitCopyAccess(ProcDevLimit *devLimitDest, ProcDevLimit *devLi
|
||||
INT32 itemSize = sizeof(DevAccessItem);
|
||||
devLimitDest->behavior = devLimitSrc->behavior;
|
||||
LOS_DL_LIST_FOR_EACH_ENTRY(tmpItem, &devLimitSrc->accessList, DevAccessItem, list) {
|
||||
DevAccessItem *newItem = (DevAccessItem *)LOS_KernelMalloc(itemSize);
|
||||
DevAccessItem *newItem = (DevAccessItem *)LOS_MemAlloc(m_aucSysMem1, itemSize);
|
||||
if (newItem == NULL) {
|
||||
return ENOMEM;
|
||||
}
|
||||
@@ -326,7 +326,7 @@ STATIC VOID DevLimitAccessListRm(ProcDevLimit *devLimit, DevAccessItem *item)
|
||||
walk->access &= ~item->access;
|
||||
if (!walk->access) {
|
||||
LOS_ListDelete(&walk->list);
|
||||
LOS_KernelFree((VOID *)walk);
|
||||
(VOID)LOS_MemFree(m_aucSysMem1, (VOID *)walk);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -338,7 +338,7 @@ STATIC UINT32 DevLimitAccessListAdd(ProcDevLimit *devLimit, DevAccessItem *item)
|
||||
}
|
||||
|
||||
DevAccessItem *walk = NULL;
|
||||
DevAccessItem *newItem = (DevAccessItem *)LOS_KernelMalloc(sizeof(DevAccessItem));
|
||||
DevAccessItem *newItem = (DevAccessItem *)LOS_MemAlloc(m_aucSysMem1, sizeof(DevAccessItem));
|
||||
if (newItem == NULL) {
|
||||
return ENOMEM;
|
||||
}
|
||||
@@ -351,7 +351,7 @@ STATIC UINT32 DevLimitAccessListAdd(ProcDevLimit *devLimit, DevAccessItem *item)
|
||||
continue;
|
||||
}
|
||||
walk->access |= item->access;
|
||||
LOS_KernelFree((VOID *)newItem);
|
||||
(VOID)LOS_MemFree(m_aucSysMem1, (VOID *)newItem);
|
||||
newItem = NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
#ifdef LOSCFG_KERNEL_IPC_PLIMIT
|
||||
STATIC ProcIPCLimit *g_rootIPCLimit = NULL;
|
||||
#define PLIMIT_IPC_SHM_LIMIT_MAX 104857600
|
||||
#define PLIMIT_IPC_SHM_LIMIT_MAX 0xFFFFFFFF
|
||||
|
||||
VOID OsIPCLimitInit(UINTPTR limite)
|
||||
{
|
||||
@@ -45,7 +45,7 @@ VOID OsIPCLimitInit(UINTPTR limite)
|
||||
|
||||
VOID *OsIPCLimitAlloc(VOID)
|
||||
{
|
||||
ProcIPCLimit *plimite = (ProcIPCLimit *)LOS_KernelMalloc(sizeof(ProcIPCLimit));
|
||||
ProcIPCLimit *plimite = (ProcIPCLimit *)LOS_MemAlloc(m_aucSysMem1, sizeof(ProcIPCLimit));
|
||||
if (plimite == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -60,7 +60,7 @@ VOID OsIPCLimitFree(UINTPTR limite)
|
||||
return;
|
||||
}
|
||||
|
||||
LOS_KernelFree((VOID *)plimite);
|
||||
(VOID)LOS_MemFree(m_aucSysMem1, (VOID *)plimite);
|
||||
}
|
||||
|
||||
VOID OsIPCLimitCopy(UINTPTR dest, UINTPTR src)
|
||||
|
||||
@@ -46,7 +46,6 @@ typedef struct ProcIPCLimit {
|
||||
UINT32 shmSize;
|
||||
UINT32 shmFailedCount;
|
||||
UINT32 shmSizeLimit;
|
||||
UINT64 migrateTime;
|
||||
} ProcIPCLimit;
|
||||
|
||||
enum IPCStatType {
|
||||
|
||||
@@ -52,7 +52,7 @@ VOID OsMemLimitSetLimit(UINT32 limit)
|
||||
|
||||
VOID *OsMemLimiterAlloc(VOID)
|
||||
{
|
||||
ProcMemLimiter *plimite = (ProcMemLimiter *)LOS_KernelMalloc(sizeof(ProcMemLimiter));
|
||||
ProcMemLimiter *plimite = (ProcMemLimiter *)LOS_MemAlloc(m_aucSysMem1, sizeof(ProcMemLimiter));
|
||||
if (plimite == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -67,7 +67,7 @@ VOID OsMemLimiterFree(UINTPTR limite)
|
||||
return;
|
||||
}
|
||||
|
||||
LOS_KernelFree((VOID *)limite);
|
||||
(VOID)LOS_MemFree(m_aucSysMem1, (VOID *)limite);
|
||||
}
|
||||
|
||||
VOID OsMemLimiterCopy(UINTPTR dest, UINTPTR src)
|
||||
|
||||
@@ -121,7 +121,7 @@ ProcLimiterSet *OsRootPLimitsGet(VOID)
|
||||
|
||||
UINT32 OsProcLimiterSetInit(VOID)
|
||||
{
|
||||
g_rootPLimite = (ProcLimiterSet *)LOS_KernelMalloc(sizeof(ProcLimiterSet));
|
||||
g_rootPLimite = (ProcLimiterSet *)LOS_MemAlloc(m_aucSysMem1, sizeof(ProcLimiterSet));
|
||||
if (g_rootPLimite == NULL) {
|
||||
return ENOMEM;
|
||||
}
|
||||
@@ -145,6 +145,25 @@ UINT32 OsProcLimiterSetInit(VOID)
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
STATIC VOID PLimitsDeleteProcess(LosProcessCB *processCB)
|
||||
{
|
||||
if ((processCB == NULL) || (processCB->plimits == NULL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ProcLimiterSet *plimits = processCB->plimits;
|
||||
for (UINT32 limitsID = 0; limitsID < PROCESS_LIMITER_COUNT; limitsID++) {
|
||||
if (g_limiteOps[limitsID].LimiterDelProcess == NULL) {
|
||||
continue;
|
||||
}
|
||||
g_limiteOps[limitsID].LimiterDelProcess(plimits->limitsList[limitsID], (UINTPTR)processCB);
|
||||
}
|
||||
plimits->pidCount--;
|
||||
LOS_ListDelete(&processCB->plimitsList);
|
||||
processCB->plimits = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
STATIC UINT32 PLimitsAddProcess(ProcLimiterSet *plimits, LosProcessCB *processCB)
|
||||
{
|
||||
UINT32 limitsID;
|
||||
@@ -170,6 +189,8 @@ STATIC UINT32 PLimitsAddProcess(ProcLimiterSet *plimits, LosProcessCB *processCB
|
||||
}
|
||||
}
|
||||
|
||||
PLimitsDeleteProcess(processCB);
|
||||
|
||||
for (limitsID = 0; limitsID < PROCESS_LIMITER_COUNT; limitsID++) {
|
||||
if (g_limiteOps[limitsID].LimiterAddProcess == NULL) {
|
||||
continue;
|
||||
@@ -215,25 +236,6 @@ UINT32 OsPLimitsAddPid(ProcLimiterSet *plimits, UINT32 pid)
|
||||
return ret;
|
||||
}
|
||||
|
||||
STATIC VOID PLimitsDeleteProcess(LosProcessCB *processCB)
|
||||
{
|
||||
if ((processCB == NULL) || (processCB->plimits == NULL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ProcLimiterSet *plimits = processCB->plimits;
|
||||
for (UINT32 limitsID = 0; limitsID < PROCESS_LIMITER_COUNT; limitsID++) {
|
||||
if (g_limiteOps[limitsID].LimiterDelProcess == NULL) {
|
||||
continue;
|
||||
}
|
||||
g_limiteOps[limitsID].LimiterDelProcess(plimits->limitsList[limitsID], (UINTPTR)processCB);
|
||||
}
|
||||
plimits->pidCount--;
|
||||
LOS_ListDelete(&processCB->plimitsList);
|
||||
processCB->plimits = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
VOID OsPLimitsDeleteProcess(LosProcessCB *processCB)
|
||||
{
|
||||
UINT32 intSave;
|
||||
@@ -318,7 +320,7 @@ UINT32 OsPLimitsFree(ProcLimiterSet *currPLimits)
|
||||
g_limiteOps[limiteID].LimiterFree(procLimiter);
|
||||
}
|
||||
}
|
||||
LOS_KernelFree(currPLimits);
|
||||
(VOID)LOS_MemFree(m_aucSysMem1, currPLimits);
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ VOID PidLimiterInit(UINTPTR limit)
|
||||
|
||||
VOID *PidLimiterAlloc(VOID)
|
||||
{
|
||||
PidLimit *plimite = (PidLimit *)LOS_KernelMalloc(sizeof(PidLimit));
|
||||
PidLimit *plimite = (PidLimit *)LOS_MemAlloc(m_aucSysMem1, sizeof(PidLimit));
|
||||
if (plimite == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -67,7 +67,7 @@ VOID PidLimterFree(UINTPTR limit)
|
||||
return;
|
||||
}
|
||||
|
||||
LOS_KernelFree((VOID *)limit);
|
||||
(VOID)LOS_MemFree(m_aucSysMem1, (VOID *)limit);
|
||||
}
|
||||
|
||||
BOOL PidLimitMigrateCheck(UINTPTR curr, UINTPTR parent)
|
||||
|
||||
@@ -44,7 +44,7 @@ VOID OsSchedLimitInit(UINTPTR limit)
|
||||
|
||||
VOID *OsSchedLimitAlloc(VOID)
|
||||
{
|
||||
ProcSchedLimiter *plimit = (ProcSchedLimiter *)LOS_KernelMalloc(sizeof(ProcSchedLimiter));
|
||||
ProcSchedLimiter *plimit = (ProcSchedLimiter *)LOS_MemAlloc(m_aucSysMem1, sizeof(ProcSchedLimiter));
|
||||
if (plimit == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -59,7 +59,7 @@ VOID OsSchedLimitFree(UINTPTR limit)
|
||||
return;
|
||||
}
|
||||
|
||||
LOS_KernelFree((VOID *)limit);
|
||||
(VOID)LOS_MemFree(m_aucSysMem1, (VOID *)limit);
|
||||
}
|
||||
|
||||
VOID OsSchedLimitCopy(UINTPTR dest, UINTPTR src)
|
||||
|
||||
@@ -48,8 +48,6 @@ typedef struct ProcSchedLimiter {
|
||||
UINT64 period;
|
||||
UINT64 quota;
|
||||
UINT64 allRuntime;
|
||||
UINT64 overrunTime;
|
||||
UINT64 stat;
|
||||
} ProcSchedLimiter;
|
||||
|
||||
VOID OsSchedLimitInit(UINTPTR limit);
|
||||
|
||||
Reference in New Issue
Block a user