• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2022 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_UTS_CONTAINER
32 #include "internal.h"
33 #include "los_uts_container_pri.h"
34 #include "los_process_pri.h"
35 
36 STATIC UINT32 g_currentUtsContainerNum;
37 
InitUtsContainer(struct utsname * name)38 STATIC UINT32 InitUtsContainer(struct utsname *name)
39 {
40     INT32 ret = sprintf_s(name->sysname, sizeof(name->sysname), "%s", KERNEL_NAME);
41     if (ret < 0) {
42         return LOS_NOK;
43     }
44     ret = sprintf_s(name->nodename, sizeof(name->nodename), "%s", KERNEL_NODE_NAME);
45     if (ret < 0) {
46         return LOS_NOK;
47     }
48     ret = sprintf_s(name->version, sizeof(name->version), "%s %u.%u.%u.%u %s %s",
49         KERNEL_NAME, KERNEL_MAJOR, KERNEL_MINOR, KERNEL_PATCH, KERNEL_ITRE, __DATE__, __TIME__);
50     if (ret < 0) {
51         return LOS_NOK;
52     }
53     const char *cpuInfo = LOS_CpuInfo();
54     ret = sprintf_s(name->machine, sizeof(name->machine), "%s", cpuInfo);
55     if (ret < 0) {
56         return LOS_NOK;
57     }
58     ret = sprintf_s(name->release, sizeof(name->release), "%u.%u.%u.%u",
59         KERNEL_MAJOR, KERNEL_MINOR, KERNEL_PATCH, KERNEL_ITRE);
60     if (ret < 0) {
61         return LOS_NOK;
62     }
63     name->domainname[0] = '\0';
64     return LOS_OK;
65 }
66 
CreateNewUtsContainer(UtsContainer * parent)67 STATIC UtsContainer *CreateNewUtsContainer(UtsContainer *parent)
68 {
69     UINT32 ret;
70     UINT32 size = sizeof(UtsContainer);
71     UtsContainer *utsContainer = (UtsContainer *)LOS_MemAlloc(m_aucSysMem1, size);
72     if (utsContainer == NULL) {
73         return NULL;
74     }
75     (VOID)memset_s(utsContainer, sizeof(UtsContainer), 0, sizeof(UtsContainer));
76 
77     utsContainer->containerID = OsAllocContainerID();
78     if (parent != NULL) {
79         LOS_AtomicSet(&utsContainer->rc, 1);
80         return utsContainer;
81     }
82     LOS_AtomicSet(&utsContainer->rc, 3); /* 3: Three system processes */
83     ret = InitUtsContainer(&utsContainer->utsName);
84     if (ret != LOS_OK) {
85         (VOID)LOS_MemFree(m_aucSysMem1, utsContainer);
86         return NULL;
87     }
88     return utsContainer;
89 }
90 
CreateUtsContainer(LosProcessCB * child,LosProcessCB * parent)91 STATIC UINT32 CreateUtsContainer(LosProcessCB *child, LosProcessCB *parent)
92 {
93     UINT32 intSave;
94     UtsContainer *parentContainer = parent->container->utsContainer;
95     UtsContainer *newUtsContainer = CreateNewUtsContainer(parentContainer);
96     if (newUtsContainer == NULL) {
97         return ENOMEM;
98     }
99 
100     SCHEDULER_LOCK(intSave);
101     g_currentUtsContainerNum++;
102     (VOID)memcpy_s(&newUtsContainer->utsName, sizeof(newUtsContainer->utsName),
103                    &parentContainer->utsName, sizeof(parentContainer->utsName));
104     child->container->utsContainer = newUtsContainer;
105     SCHEDULER_UNLOCK(intSave);
106     return LOS_OK;
107 }
108 
OsInitRootUtsContainer(UtsContainer ** utsContainer)109 UINT32 OsInitRootUtsContainer(UtsContainer **utsContainer)
110 {
111     UINT32 intSave;
112     UtsContainer *newUtsContainer = CreateNewUtsContainer(NULL);
113     if (newUtsContainer == NULL) {
114         return ENOMEM;
115     }
116 
117     SCHEDULER_LOCK(intSave);
118     g_currentUtsContainerNum++;
119     *utsContainer = newUtsContainer;
120     SCHEDULER_UNLOCK(intSave);
121     return LOS_OK;
122 }
123 
OsCopyUtsContainer(UINTPTR flags,LosProcessCB * child,LosProcessCB * parent)124 UINT32 OsCopyUtsContainer(UINTPTR flags, LosProcessCB *child, LosProcessCB *parent)
125 {
126     UINT32 intSave;
127     UtsContainer *currUtsContainer = parent->container->utsContainer;
128 
129     if (!(flags & CLONE_NEWUTS)) {
130         SCHEDULER_LOCK(intSave);
131         LOS_AtomicInc(&currUtsContainer->rc);
132         child->container->utsContainer = currUtsContainer;
133         SCHEDULER_UNLOCK(intSave);
134         return LOS_OK;
135     }
136 
137     if (OsContainerLimitCheck(UTS_CONTAINER, &g_currentUtsContainerNum) != LOS_OK) {
138         return EPERM;
139     }
140 
141     return CreateUtsContainer(child, parent);
142 }
143 
OsUnshareUtsContainer(UINTPTR flags,LosProcessCB * curr,Container * newContainer)144 UINT32 OsUnshareUtsContainer(UINTPTR flags, LosProcessCB *curr, Container *newContainer)
145 {
146     UINT32 intSave;
147     UtsContainer *parentContainer = curr->container->utsContainer;
148 
149     if (!(flags & CLONE_NEWUTS)) {
150         SCHEDULER_LOCK(intSave);
151         newContainer->utsContainer = parentContainer;
152         LOS_AtomicInc(&parentContainer->rc);
153         SCHEDULER_UNLOCK(intSave);
154         return LOS_OK;
155     }
156 
157     if (OsContainerLimitCheck(UTS_CONTAINER, &g_currentUtsContainerNum) != LOS_OK) {
158         return EPERM;
159     }
160 
161     UtsContainer *utsContainer = CreateNewUtsContainer(parentContainer);
162     if (utsContainer == NULL) {
163         return ENOMEM;
164     }
165 
166     SCHEDULER_LOCK(intSave);
167     newContainer->utsContainer = utsContainer;
168     g_currentUtsContainerNum++;
169     (VOID)memcpy_s(&utsContainer->utsName, sizeof(utsContainer->utsName),
170                    &parentContainer->utsName, sizeof(parentContainer->utsName));
171     SCHEDULER_UNLOCK(intSave);
172     return LOS_OK;
173 }
174 
OsSetNsUtsContainer(UINT32 flags,Container * container,Container * newContainer)175 UINT32 OsSetNsUtsContainer(UINT32 flags, Container *container, Container *newContainer)
176 {
177     if (flags & CLONE_NEWUTS) {
178         newContainer->utsContainer = container->utsContainer;
179         LOS_AtomicInc(&container->utsContainer->rc);
180         return LOS_OK;
181     }
182 
183     newContainer->utsContainer = OsCurrProcessGet()->container->utsContainer;
184     LOS_AtomicInc(&newContainer->utsContainer->rc);
185     return LOS_OK;
186 }
187 
OsUtsContainerDestroy(Container * container)188 VOID OsUtsContainerDestroy(Container *container)
189 {
190     UINT32 intSave;
191     if (container == NULL) {
192         return;
193     }
194 
195     SCHEDULER_LOCK(intSave);
196     UtsContainer *utsContainer = container->utsContainer;
197     if (utsContainer == NULL) {
198         SCHEDULER_UNLOCK(intSave);
199         return;
200     }
201 
202     LOS_AtomicDec(&utsContainer->rc);
203     if (LOS_AtomicRead(&utsContainer->rc) > 0) {
204         SCHEDULER_UNLOCK(intSave);
205         return;
206     }
207     g_currentUtsContainerNum--;
208     container->utsContainer = NULL;
209     SCHEDULER_UNLOCK(intSave);
210     (VOID)LOS_MemFree(m_aucSysMem1, utsContainer);
211     return;
212 }
213 
OsGetCurrUtsName(VOID)214 struct utsname *OsGetCurrUtsName(VOID)
215 {
216     Container *container = OsCurrProcessGet()->container;
217     if (container == NULL) {
218         return NULL;
219     }
220     UtsContainer *utsContainer = container->utsContainer;
221     if (utsContainer == NULL) {
222         return NULL;
223     }
224     return &utsContainer->utsName;
225 }
226 
OsGetUtsContainerID(UtsContainer * utsContainer)227 UINT32 OsGetUtsContainerID(UtsContainer *utsContainer)
228 {
229     if (utsContainer == NULL) {
230         return OS_INVALID_VALUE;
231     }
232 
233     return utsContainer->containerID;
234 }
235 
OsGetUtsContainerCount(VOID)236 UINT32 OsGetUtsContainerCount(VOID)
237 {
238     return g_currentUtsContainerNum;
239 }
240 #endif
241