• 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 
31 #ifdef LOSCFG_MNT_CONTAINER
32 #include <unistd.h>
33 #include "los_mnt_container_pri.h"
34 #include "los_container_pri.h"
35 #include "los_process_pri.h"
36 #include "sys/mount.h"
37 #include "vnode.h"
38 #include "internal.h"
39 
40 STATIC UINT32 g_currentMntContainerNum;
41 
GetContainerMntList(VOID)42 LIST_HEAD *GetContainerMntList(VOID)
43 {
44     return &OsCurrProcessGet()->container->mntContainer->mountList;
45 }
46 
CreateNewMntContainer(MntContainer * parent)47 STATIC MntContainer *CreateNewMntContainer(MntContainer *parent)
48 {
49     MntContainer *mntContainer = (MntContainer *)LOS_MemAlloc(m_aucSysMem1, sizeof(MntContainer));
50     if (mntContainer == NULL) {
51         return NULL;
52     }
53     mntContainer->containerID = OsAllocContainerID();
54     LOS_ListInit(&mntContainer->mountList);
55 
56     if (parent != NULL) {
57         LOS_AtomicSet(&mntContainer->rc, 1);
58     } else {
59         LOS_AtomicSet(&mntContainer->rc, 3); /* 3: Three system processes */
60     }
61     return mntContainer;
62 }
63 
CreateMntContainer(LosProcessCB * child,LosProcessCB * parent)64 STATIC UINT32 CreateMntContainer(LosProcessCB *child, LosProcessCB *parent)
65 {
66     UINT32 intSave;
67     MntContainer *parentContainer = parent->container->mntContainer;
68     MntContainer *newMntContainer = CreateNewMntContainer(parentContainer);
69     if (newMntContainer == NULL) {
70         return ENOMEM;
71     }
72 
73     SCHEDULER_LOCK(intSave);
74     g_currentMntContainerNum++;
75     child->container->mntContainer = newMntContainer;
76     SCHEDULER_UNLOCK(intSave);
77     return LOS_OK;
78 }
79 
OsInitRootMntContainer(MntContainer ** mntContainer)80 UINT32 OsInitRootMntContainer(MntContainer **mntContainer)
81 {
82     UINT32 intSave;
83     MntContainer *newMntContainer = CreateNewMntContainer(NULL);
84     if (newMntContainer == NULL) {
85         return ENOMEM;
86     }
87 
88     SCHEDULER_LOCK(intSave);
89     g_currentMntContainerNum++;
90     *mntContainer = newMntContainer;
91     SCHEDULER_UNLOCK(intSave);
92     return LOS_OK;
93 }
94 
CopyMountList(MntContainer * parentContainer,MntContainer * newContainer)95 STATIC UINT32 CopyMountList(MntContainer *parentContainer, MntContainer *newContainer)
96 {
97     struct Mount *mnt = NULL;
98     VnodeHold();
99     LOS_DL_LIST_FOR_EACH_ENTRY(mnt, &parentContainer->mountList, struct Mount, mountList) {
100         struct Mount *newMnt = (struct Mount *)zalloc(sizeof(struct Mount));
101         if (newMnt == NULL) {
102             VnodeDrop();
103             return ENOMEM;
104         }
105         *newMnt = *mnt;
106         LOS_ListTailInsert(&newContainer->mountList, &newMnt->mountList);
107         newMnt->vnodeCovered->mntCount++;
108     }
109     VnodeDrop();
110     return LOS_OK;
111 }
112 
OsCopyMntContainer(UINTPTR flags,LosProcessCB * child,LosProcessCB * parent)113 UINT32 OsCopyMntContainer(UINTPTR flags, LosProcessCB *child, LosProcessCB *parent)
114 {
115     UINT32 ret;
116     UINT32 intSave;
117     MntContainer *currMntContainer = parent->container->mntContainer;
118 
119     if (!(flags & CLONE_NEWNS)) {
120         SCHEDULER_LOCK(intSave);
121         LOS_AtomicInc(&currMntContainer->rc);
122         child->container->mntContainer = currMntContainer;
123         SCHEDULER_UNLOCK(intSave);
124         return LOS_OK;
125     }
126 
127     if (OsContainerLimitCheck(MNT_CONTAINER, &g_currentMntContainerNum) != LOS_OK) {
128         return EPERM;
129     }
130 
131     ret = CreateMntContainer(child, parent);
132     if (ret != LOS_OK) {
133         return ret;
134     }
135 
136     return CopyMountList(currMntContainer, child->container->mntContainer);
137 }
138 
OsUnshareMntContainer(UINTPTR flags,LosProcessCB * curr,Container * newContainer)139 UINT32 OsUnshareMntContainer(UINTPTR flags, LosProcessCB *curr, Container *newContainer)
140 {
141     UINT32 intSave;
142     UINT32 ret;
143     MntContainer *parentContainer = curr->container->mntContainer;
144 
145     if (!(flags & CLONE_NEWNS)) {
146         SCHEDULER_LOCK(intSave);
147         newContainer->mntContainer = parentContainer;
148         LOS_AtomicInc(&parentContainer->rc);
149         SCHEDULER_UNLOCK(intSave);
150         return LOS_OK;
151     }
152 
153     if (OsContainerLimitCheck(MNT_CONTAINER, &g_currentMntContainerNum) != LOS_OK) {
154         return EPERM;
155     }
156 
157     MntContainer *mntContainer = CreateNewMntContainer(parentContainer);
158     if (mntContainer == NULL) {
159         return ENOMEM;
160     }
161 
162     ret = CopyMountList(parentContainer, mntContainer);
163     if (ret != LOS_OK) {
164         (VOID)LOS_MemFree(m_aucSysMem1, mntContainer);
165         return ret;
166     }
167 
168     SCHEDULER_LOCK(intSave);
169     newContainer->mntContainer = mntContainer;
170     g_currentMntContainerNum++;
171     SCHEDULER_UNLOCK(intSave);
172     return LOS_OK;
173 }
174 
OsSetNsMntContainer(UINT32 flags,Container * container,Container * newContainer)175 UINT32 OsSetNsMntContainer(UINT32 flags, Container *container, Container *newContainer)
176 {
177     if (flags & CLONE_NEWNS) {
178         newContainer->mntContainer = container->mntContainer;
179         LOS_AtomicInc(&container->mntContainer->rc);
180         return LOS_OK;
181     }
182 
183     newContainer->mntContainer = OsCurrProcessGet()->container->mntContainer;
184     LOS_AtomicInc(&newContainer->mntContainer->rc);
185     return LOS_OK;
186 }
187 
FreeMountList(LIST_HEAD * mountList)188 STATIC VOID FreeMountList(LIST_HEAD *mountList)
189 {
190     struct Mount *mnt = NULL;
191     struct Mount *nextMnt = NULL;
192 
193     VnodeHold();
194     if (LOS_ListEmpty(mountList)) {
195         VnodeDrop();
196         return;
197     }
198 
199     LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(mnt, nextMnt, mountList, struct Mount, mountList) {
200         if (mnt->vnodeCovered->mntCount > 0) {
201             mnt->vnodeCovered->mntCount--;
202             LOS_ListDelete(&mnt->mountList);
203             free(mnt);
204         } else {
205             umount(mnt->pathName);
206         }
207     }
208     VnodeDrop();
209     return;
210 }
211 
OsMntContainerDestroy(Container * container)212 VOID OsMntContainerDestroy(Container *container)
213 {
214     UINT32 intSave;
215     if (container == NULL) {
216         return;
217     }
218 
219     SCHEDULER_LOCK(intSave);
220     MntContainer *mntContainer = container->mntContainer;
221     if (mntContainer == NULL) {
222         SCHEDULER_UNLOCK(intSave);
223         return;
224     }
225 
226     LOS_AtomicDec(&mntContainer->rc);
227     if (LOS_AtomicRead(&mntContainer->rc) > 0) {
228         SCHEDULER_UNLOCK(intSave);
229         return;
230     }
231 
232     g_currentMntContainerNum--;
233     SCHEDULER_UNLOCK(intSave);
234     FreeMountList(&mntContainer->mountList);
235     container->mntContainer = NULL;
236     (VOID)LOS_MemFree(m_aucSysMem1, mntContainer);
237     return;
238 }
239 
OsGetMntContainerID(MntContainer * mntContainer)240 UINT32 OsGetMntContainerID(MntContainer *mntContainer)
241 {
242     if (mntContainer == NULL) {
243         return OS_INVALID_VALUE;
244     }
245 
246     return mntContainer->containerID;
247 }
248 
OsGetMntContainerCount(VOID)249 UINT32 OsGetMntContainerCount(VOID)
250 {
251     return g_currentMntContainerNum;
252 }
253 #endif
254