• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without modification,
5  * are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright notice, this list of
8  *    conditions and the following disclaimer.
9  *
10  * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11  *    of conditions and the following disclaimer in the documentation and/or other materials
12  *    provided with the distribution.
13  *
14  * 3. Neither the name of the copyright holder nor the names of its contributors may be used
15  *    to endorse or promote products derived from this software without specific prior written
16  *    permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
22  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 #ifdef LOSCFG_IPC_CONTAINER
31 #include "los_ipc_container_pri.h"
32 #include "los_config.h"
33 #include "los_queue_pri.h"
34 #include "los_vm_shm_pri.h"
35 #include "los_process_pri.h"
36 #include "vnode.h"
37 #include "proc_fs.h"
38 #include "pthread.h"
39 
40 #define IPC_INIT_NUM 3
41 
42 STATIC UINT32 g_currentIpcContainerNum = 0;
43 
CreateNewIpcContainer(IpcContainer * parent)44 STATIC IpcContainer *CreateNewIpcContainer(IpcContainer *parent)
45 {
46     pthread_mutexattr_t attr;
47     UINT32 size = sizeof(IpcContainer);
48     IpcContainer *ipcContainer = (IpcContainer *)LOS_MemAlloc(m_aucSysMem1, size);
49     if (ipcContainer == NULL) {
50         return NULL;
51     }
52     (VOID)memset_s(ipcContainer, size, 0, size);
53 
54     ipcContainer->allQueue = OsAllQueueCBInit(&ipcContainer->freeQueueList);
55     if (ipcContainer->allQueue == NULL) {
56         (VOID)LOS_MemFree(m_aucSysMem1, ipcContainer);
57         return NULL;
58     }
59     pthread_mutexattr_init(&attr);
60     pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
61     pthread_mutex_init(&ipcContainer->mqueueMutex, &attr);
62 
63     ipcContainer->shmSegs = OsShmCBInit(&ipcContainer->sysvShmMux, &ipcContainer->shmInfo,
64                                         &ipcContainer->shmUsedPageCount);
65     if (ipcContainer->shmSegs == NULL) {
66         (VOID)LOS_MemFree(m_aucSysMem1, ipcContainer->allQueue);
67         (VOID)LOS_MemFree(m_aucSysMem1, ipcContainer);
68         return NULL;
69     }
70     ipcContainer->containerID = OsAllocContainerID();
71 
72     if (parent != NULL) {
73         LOS_AtomicSet(&ipcContainer->rc, 1);
74     } else {
75         LOS_AtomicSet(&ipcContainer->rc, 3); /* 3: Three system processes */
76     }
77     return ipcContainer;
78 }
79 
CreateIpcContainer(LosProcessCB * child,LosProcessCB * parent)80 STATIC UINT32 CreateIpcContainer(LosProcessCB *child, LosProcessCB *parent)
81 {
82     UINT32 intSave;
83     IpcContainer *parentContainer = parent->container->ipcContainer;
84     IpcContainer *newIpcContainer = CreateNewIpcContainer(parentContainer);
85     if (newIpcContainer == NULL) {
86         return ENOMEM;
87     }
88 
89     SCHEDULER_LOCK(intSave);
90     g_currentIpcContainerNum++;
91     child->container->ipcContainer = newIpcContainer;
92     SCHEDULER_UNLOCK(intSave);
93     return LOS_OK;
94 }
95 
OsInitRootIpcContainer(IpcContainer ** ipcContainer)96 UINT32 OsInitRootIpcContainer(IpcContainer **ipcContainer)
97 {
98     UINT32 intSave;
99     IpcContainer *newIpcContainer = CreateNewIpcContainer(NULL);
100     if (newIpcContainer == NULL) {
101         return ENOMEM;
102     }
103 
104     SCHEDULER_LOCK(intSave);
105     g_currentIpcContainerNum++;
106     *ipcContainer = newIpcContainer;
107     SCHEDULER_UNLOCK(intSave);
108     return LOS_OK;
109 }
110 
OsCopyIpcContainer(UINTPTR flags,LosProcessCB * child,LosProcessCB * parent)111 UINT32 OsCopyIpcContainer(UINTPTR flags, LosProcessCB *child, LosProcessCB *parent)
112 {
113     UINT32 intSave;
114     IpcContainer *currIpcContainer = parent->container->ipcContainer;
115 
116     if (!(flags & CLONE_NEWIPC)) {
117         SCHEDULER_LOCK(intSave);
118         LOS_AtomicInc(&currIpcContainer->rc);
119         child->container->ipcContainer = currIpcContainer;
120         SCHEDULER_UNLOCK(intSave);
121         return LOS_OK;
122     }
123 
124     if (OsContainerLimitCheck(IPC_CONTAINER, &g_currentIpcContainerNum) != LOS_OK) {
125         return EPERM;
126     }
127 
128     return CreateIpcContainer(child, parent);
129 }
130 
OsUnshareIpcContainer(UINTPTR flags,LosProcessCB * curr,Container * newContainer)131 UINT32 OsUnshareIpcContainer(UINTPTR flags, LosProcessCB *curr, Container *newContainer)
132 {
133     UINT32 intSave;
134     IpcContainer *parentContainer = curr->container->ipcContainer;
135 
136     if (!(flags & CLONE_NEWIPC)) {
137         SCHEDULER_LOCK(intSave);
138         newContainer->ipcContainer = parentContainer;
139         LOS_AtomicInc(&parentContainer->rc);
140         SCHEDULER_UNLOCK(intSave);
141         return LOS_OK;
142     }
143 
144     if (OsContainerLimitCheck(IPC_CONTAINER, &g_currentIpcContainerNum) != LOS_OK) {
145         return EPERM;
146     }
147 
148     IpcContainer *ipcContainer = CreateNewIpcContainer(parentContainer);
149     if (ipcContainer == NULL) {
150         return ENOMEM;
151     }
152 
153     SCHEDULER_LOCK(intSave);
154     newContainer->ipcContainer = ipcContainer;
155     g_currentIpcContainerNum++;
156     SCHEDULER_UNLOCK(intSave);
157     return LOS_OK;
158 }
159 
OsSetNsIpcContainer(UINT32 flags,Container * container,Container * newContainer)160 UINT32 OsSetNsIpcContainer(UINT32 flags, Container *container, Container *newContainer)
161 {
162     if (flags & CLONE_NEWIPC) {
163         newContainer->ipcContainer = container->ipcContainer;
164         LOS_AtomicInc(&container->ipcContainer->rc);
165         return LOS_OK;
166     }
167 
168     newContainer->ipcContainer = OsCurrProcessGet()->container->ipcContainer;
169     LOS_AtomicInc(&newContainer->ipcContainer->rc);
170     return LOS_OK;
171 }
172 
OsIpcContainerDestroy(Container * container)173 VOID OsIpcContainerDestroy(Container *container)
174 {
175     UINT32 intSave;
176     if (container == NULL) {
177         return;
178     }
179 
180     SCHEDULER_LOCK(intSave);
181     IpcContainer *ipcContainer = container->ipcContainer;
182     if (ipcContainer == NULL) {
183         SCHEDULER_UNLOCK(intSave);
184         return;
185     }
186 
187     LOS_AtomicDec(&ipcContainer->rc);
188     if (LOS_AtomicRead(&ipcContainer->rc) > 0) {
189         SCHEDULER_UNLOCK(intSave);
190         return;
191     }
192 
193     g_currentIpcContainerNum--;
194     container->ipcContainer = NULL;
195     SCHEDULER_UNLOCK(intSave);
196     OsShmCBDestroy(ipcContainer->shmSegs, &ipcContainer->shmInfo, &ipcContainer->sysvShmMux);
197     ipcContainer->shmSegs = NULL;
198     OsMqueueCBDestroy(ipcContainer->queueTable);
199     (VOID)LOS_MemFree(m_aucSysMem1, ipcContainer->allQueue);
200     (VOID)LOS_MemFree(m_aucSysMem1, ipcContainer);
201     return;
202 }
203 
OsGetIpcContainerID(IpcContainer * ipcContainer)204 UINT32 OsGetIpcContainerID(IpcContainer *ipcContainer)
205 {
206     if (ipcContainer == NULL) {
207         return OS_INVALID_VALUE;
208     }
209 
210     return ipcContainer->containerID;
211 }
212 
OsGetCurrIpcContainer(VOID)213 IpcContainer *OsGetCurrIpcContainer(VOID)
214 {
215     return OsCurrProcessGet()->container->ipcContainer;
216 }
217 
OsGetIpcContainerCount(VOID)218 UINT32 OsGetIpcContainerCount(VOID)
219 {
220     return g_currentIpcContainerNum;
221 }
222 #endif
223