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