1 /*
2 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3 * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this list of
9 * conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 * of conditions and the following disclaimer in the documentation and/or other materials
13 * provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16 * to endorse or promote products derived from this software without specific prior written
17 * permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include <sys/statfs.h>
33 #include <sys/mount.h>
34 #include "proc_fs.h"
35 #include "internal.h"
36 #include "los_process_pri.h"
37 #include "user_copy.h"
38 #include "los_memory.h"
39
40 #ifdef LOSCFG_PROC_PROCESS_DIR
41 #include "los_vm_dump.h"
42
43 typedef enum {
44 PROC_PID,
45 PROC_PID_MEM,
46 #ifdef LOSCFG_KERNEL_CPUP
47 PROC_PID_CPUP,
48 #endif
49 #ifdef LOSCFG_USER_CONTAINER
50 PROC_UID_MAP,
51 PROC_GID_MAP,
52 #endif
53 PROC_P_TYPE_MAX,
54 } ProcessDataType;
55
56 struct ProcProcess {
57 char *name;
58 mode_t mode;
59 int type;
60 const struct ProcFileOperations *fileOps;
61 };
62
63 struct ProcessData {
64 uintptr_t process;
65 unsigned int type;
66 };
67
ProcGetProcessCB(struct ProcessData * data)68 static LosProcessCB *ProcGetProcessCB(struct ProcessData *data)
69 {
70 if (data->process != 0) {
71 return (LosProcessCB *)data->process;
72 }
73 return OsCurrProcessGet();
74 }
75
76 #define PROC_PID_PRIVILEGE 7
77 #define PROC_PID_DIR_LEN 100
78 #ifdef LOSCFG_KERNEL_CONTAINER
ProcessContainerLink(unsigned int containerID,ContainerType type,char * buffer,size_t bufLen)79 static ssize_t ProcessContainerLink(unsigned int containerID, ContainerType type, char *buffer, size_t bufLen)
80 {
81 ssize_t count = -1;
82 if ((type == PID_CONTAINER) || (type == PID_CHILD_CONTAINER)) {
83 count = snprintf_s(buffer, bufLen, bufLen - 1, "'pid:[%u]'", containerID);
84 } else if (type == UTS_CONTAINER) {
85 count = snprintf_s(buffer, bufLen, bufLen - 1, "'uts:[%u]'", containerID);
86 } else if (type == MNT_CONTAINER) {
87 count = snprintf_s(buffer, bufLen, bufLen - 1, "'mnt:[%u]'", containerID);
88 } else if (type == IPC_CONTAINER) {
89 count = snprintf_s(buffer, bufLen, bufLen - 1, "'ipc:[%u]'", containerID);
90 } else if ((type == TIME_CONTAINER) || (type == TIME_CHILD_CONTAINER)) {
91 count = snprintf_s(buffer, bufLen, bufLen - 1, "'time:[%u]'", containerID);
92 } else if (type == USER_CONTAINER) {
93 count = snprintf_s(buffer, bufLen, bufLen - 1, "'user:[%u]'", containerID);
94 } else if (type == NET_CONTAINER) {
95 count = snprintf_s(buffer, bufLen, bufLen - 1, "'net:[%u]'", containerID);
96 }
97
98 if (count < 0) {
99 return -EBADF;
100 }
101 return count;
102 }
103
ProcessContainerReadLink(struct ProcDirEntry * entry,char * buffer,size_t bufLen)104 static ssize_t ProcessContainerReadLink(struct ProcDirEntry *entry, char *buffer, size_t bufLen)
105 {
106 char *freeBuf = NULL;
107 char *buf = buffer;
108 ssize_t count;
109 unsigned int intSave;
110 if (entry == NULL) {
111 return -EINVAL;
112 }
113 struct ProcessData *data = (struct ProcessData *)entry->data;
114 if (data == NULL) {
115 return -EINVAL;
116 }
117
118 if (LOS_IsUserAddressRange((VADDR_T)(UINTPTR)buffer, bufLen)) {
119 buf = LOS_MemAlloc(m_aucSysMem1, bufLen);
120 if (buf == NULL) {
121 return -ENOMEM;
122 }
123 (void)memset_s(buf, bufLen, 0, bufLen);
124 freeBuf = buf;
125 }
126
127 LosProcessCB *processCB = ProcGetProcessCB(data);
128 SCHEDULER_LOCK(intSave);
129 UINT32 containerID = OsGetContainerID(processCB, (ContainerType)data->type);
130 SCHEDULER_UNLOCK(intSave);
131 if (containerID != OS_INVALID_VALUE) {
132 count = ProcessContainerLink(containerID, (ContainerType)data->type, buf, bufLen);
133 } else {
134 count = strlen("(unknown)");
135 if (memcpy_s(buf, bufLen, "(unknown)", count + 1) != EOK) {
136 (void)LOS_MemFree(m_aucSysMem1, freeBuf);
137 return -EBADF;
138 }
139 }
140 if (count < 0) {
141 (void)LOS_MemFree(m_aucSysMem1, freeBuf);
142 return count;
143 }
144
145 if (LOS_IsUserAddressRange((VADDR_T)(UINTPTR)buffer, bufLen)) {
146 if (LOS_ArchCopyToUser(buffer, buf, bufLen) != 0) {
147 (void)LOS_MemFree(m_aucSysMem1, freeBuf);
148 return -EFAULT;
149 }
150 }
151 (void)LOS_MemFree(m_aucSysMem1, freeBuf);
152 return count;
153 }
154
155 static const struct ProcFileOperations PID_CONTAINER_FOPS = {
156 .readLink = ProcessContainerReadLink,
157 };
158
ProcfsContainerGet(int fd,unsigned int * containerType)159 void *ProcfsContainerGet(int fd, unsigned int *containerType)
160 {
161 if ((fd <= 0) || (containerType == NULL)) {
162 return NULL;
163 }
164
165 VnodeHold();
166 struct Vnode *vnode = VnodeFind(fd);
167 if (vnode == NULL) {
168 VnodeDrop();
169 return NULL;
170 }
171
172 struct ProcDirEntry *entry = VnodeToEntry(vnode);
173 if (entry == NULL) {
174 VnodeDrop();
175 return NULL;
176 }
177
178 struct ProcessData *data = (struct ProcessData *)entry->data;
179 if (data == NULL) {
180 VnodeDrop();
181 return NULL;
182 }
183
184 void *processCB = (void *)ProcGetProcessCB(data);
185 *containerType = data->type;
186 VnodeDrop();
187 return processCB;
188 }
189
190 #endif /* LOSCFG_KERNEL_CONTAINER */
191
ProcessMemInfoRead(struct SeqBuf * seqBuf,LosProcessCB * pcb)192 static int ProcessMemInfoRead(struct SeqBuf *seqBuf, LosProcessCB *pcb)
193 {
194 unsigned int intSave;
195 unsigned int size = sizeof(LosVmSpace) + sizeof(LosVmMapRegion);
196 LosVmSpace *vmSpace = (LosVmSpace *)LOS_MemAlloc(m_aucSysMem1, size);
197 if (vmSpace == NULL) {
198 return -ENOMEM;
199 }
200 (void)memset_s(vmSpace, size, 0, size);
201 LosVmMapRegion *heap = (LosVmMapRegion *)((char *)vmSpace + sizeof(LosVmSpace));
202
203 SCHEDULER_LOCK(intSave);
204 if (OsProcessIsInactive(pcb)) {
205 SCHEDULER_UNLOCK(intSave);
206 (void)LOS_MemFree(m_aucSysMem1, vmSpace);
207 return -EINVAL;
208 }
209 (void)memcpy_s(vmSpace, sizeof(LosVmSpace), pcb->vmSpace, sizeof(LosVmSpace));
210 (void)memcpy_s(heap, sizeof(LosVmMapRegion), pcb->vmSpace->heap, sizeof(LosVmMapRegion));
211 SCHEDULER_UNLOCK(intSave);
212
213 (void)LosBufPrintf(seqBuf, "\nVMSpaceSize: %u byte\n", vmSpace->size);
214 (void)LosBufPrintf(seqBuf, "VMSpaceMapSize: %u byte\n", vmSpace->mapSize);
215 (void)LosBufPrintf(seqBuf, "VM TLB Asid: %u\n", vmSpace->archMmu.asid);
216 (void)LosBufPrintf(seqBuf, "VMHeapSize: %u byte\n", heap->range.size);
217 (void)LosBufPrintf(seqBuf, "VMHeapRegionName: %s\n", OsGetRegionNameOrFilePath(heap));
218 (void)LosBufPrintf(seqBuf, "VMHeapRegionType: 0x%x\n", heap->regionType);
219 (void)LOS_MemFree(m_aucSysMem1, vmSpace);
220 return 0;
221 }
222
223 #ifdef LOSCFG_KERNEL_CPUP
224 #define TIME_CYCLE_TO_US(time) ((((UINT64)time) * OS_NS_PER_CYCLE) / OS_SYS_NS_PER_US)
ProcessCpupRead(struct SeqBuf * seqBuf,LosProcessCB * pcb)225 static int ProcessCpupRead(struct SeqBuf *seqBuf, LosProcessCB *pcb)
226 {
227 unsigned int intSave;
228 OsCpupBase *processCpup = (OsCpupBase *)LOS_MemAlloc(m_aucSysMem1, sizeof(OsCpupBase));
229 if (processCpup == NULL) {
230 return -ENOMEM;
231 }
232 (void)memset_s(processCpup, sizeof(OsCpupBase), 0, sizeof(OsCpupBase));
233
234 SCHEDULER_LOCK(intSave);
235 if (OsProcessIsInactive(pcb)) {
236 SCHEDULER_UNLOCK(intSave);
237 (VOID)LOS_MemFree(m_aucSysMem1, processCpup);
238 return -EINVAL;
239 }
240 (void)memcpy_s(processCpup, sizeof(OsCpupBase), pcb->processCpup, sizeof(OsCpupBase));
241 SCHEDULER_UNLOCK(intSave);
242
243 (void)LosBufPrintf(seqBuf, "\nTotalRunningTime: %lu us\n", TIME_CYCLE_TO_US(processCpup->allTime));
244 (void)LosBufPrintf(seqBuf, "HistoricalRunningTime:(us) ");
245 for (UINT32 i = 0; i < OS_CPUP_HISTORY_RECORD_NUM + 1; i++) {
246 (void)LosBufPrintf(seqBuf, "%lu ", TIME_CYCLE_TO_US(processCpup->historyTime[i]));
247 }
248 (void)LosBufPrintf(seqBuf, "\n");
249 (void)LOS_MemFree(m_aucSysMem1, processCpup);
250 return 0;
251 }
252 #endif
253
254 #ifdef LOSCFG_TIME_CONTAINER
255 static const CHAR *g_monotonic = "monotonic";
256 #define DECIMAL_BASE 10
257
ProcTimeContainerRead(struct SeqBuf * m,void * v)258 static int ProcTimeContainerRead(struct SeqBuf *m, void *v)
259 {
260 int ret;
261 unsigned int intSave;
262 struct timespec64 offsets = {0};
263
264 if ((m == NULL) || (v == NULL)) {
265 return -EINVAL;
266 }
267
268 struct ProcessData *data = (struct ProcessData *)v;
269 SCHEDULER_LOCK(intSave);
270 LosProcessCB *processCB = ProcGetProcessCB(data);
271 ret = OsGetTimeContainerMonotonic(processCB, &offsets);
272 SCHEDULER_UNLOCK(intSave);
273 if (ret != LOS_OK) {
274 return -ret;
275 }
276
277 LosBufPrintf(m, "monotonic %lld %ld\n", offsets.tv_sec, offsets.tv_nsec);
278 return 0;
279 }
280
ProcSetTimensOffset(const char * buf,LosProcessCB * processCB)281 static int ProcSetTimensOffset(const char *buf, LosProcessCB *processCB)
282 {
283 unsigned int intSave;
284 struct timespec64 offsets;
285 char *endptr = NULL;
286
287 offsets.tv_sec = strtoll(buf, &endptr, DECIMAL_BASE);
288 offsets.tv_nsec = strtoll(endptr, NULL, DECIMAL_BASE);
289 if (offsets.tv_nsec >= OS_SYS_NS_PER_SECOND) {
290 return -EACCES;
291 }
292
293 SCHEDULER_LOCK(intSave);
294 unsigned int ret = OsSetTimeContainerMonotonic(processCB, &offsets);
295 SCHEDULER_UNLOCK(intSave);
296 if (ret != LOS_OK) {
297 return -ret;
298 }
299 return 0;
300 }
301
ProcTimeContainerWrite(struct ProcFile * pf,const char * buf,size_t count,loff_t * ppos)302 static int ProcTimeContainerWrite(struct ProcFile *pf, const char *buf, size_t count, loff_t *ppos)
303 {
304 (void)ppos;
305 char *kbuf = NULL;
306 int ret;
307
308 if ((pf == NULL) || (count <= 0)) {
309 return -EINVAL;
310 }
311
312 struct ProcDirEntry *entry = pf->pPDE;
313 if (entry == NULL) {
314 return -EINVAL;
315 }
316
317 struct ProcessData *data = (struct ProcessData *)entry->data;
318 if (data == NULL) {
319 return -EINVAL;
320 }
321
322 if (LOS_IsUserAddressRange((VADDR_T)(UINTPTR)buf, count)) {
323 kbuf = LOS_MemAlloc(m_aucSysMem1, count + 1);
324 if (kbuf == NULL) {
325 return -ENOMEM;
326 }
327
328 if (LOS_ArchCopyFromUser(kbuf, buf, count) != 0) {
329 (VOID)LOS_MemFree(m_aucSysMem1, kbuf);
330 return -EFAULT;
331 }
332 kbuf[count] = '\0';
333 buf = kbuf;
334 }
335
336 ret = strncmp(buf, g_monotonic, strlen(g_monotonic));
337 if (ret != 0) {
338 (VOID)LOS_MemFree(m_aucSysMem1, kbuf);
339 return -EINVAL;
340 }
341
342 buf += strlen(g_monotonic);
343 ret = ProcSetTimensOffset(buf, ProcGetProcessCB(data));
344 if (ret < 0) {
345 (VOID)LOS_MemFree(m_aucSysMem1, kbuf);
346 return ret;
347 }
348 (VOID)LOS_MemFree(m_aucSysMem1, kbuf);
349 return count;
350 }
351
352 static const struct ProcFileOperations TIME_CONTAINER_FOPS = {
353 .read = ProcTimeContainerRead,
354 .write = ProcTimeContainerWrite,
355 };
356 #endif
357
358 #ifdef LOSCFG_USER_CONTAINER
359
MemdupUserNul(const void * src,size_t len)360 static void *MemdupUserNul(const void *src, size_t len)
361 {
362 char *des = NULL;
363 if (len <= 0) {
364 return NULL;
365 }
366 des = LOS_MemAlloc(OS_SYS_MEM_ADDR, len + 1);
367 if (des == NULL) {
368 return NULL;
369 }
370
371 if (LOS_ArchCopyFromUser(des, src, len) != 0) {
372 (VOID)LOS_MemFree(OS_SYS_MEM_ADDR, des);
373 return NULL;
374 }
375
376 des[len] = '\0';
377 return des;
378 }
379
ProcUidGidMapWriteCheck(struct ProcFile * pf,const char * buf,size_t size,char ** kbuf,ProcessDataType * type)380 static LosProcessCB *ProcUidGidMapWriteCheck(struct ProcFile *pf, const char *buf, size_t size,
381 char **kbuf, ProcessDataType *type)
382 {
383 if ((pf == NULL) || (size <= 0) || (size >= PAGE_SIZE)) {
384 return NULL;
385 }
386
387 struct ProcDirEntry *entry = pf->pPDE;
388 if (entry == NULL) {
389 return NULL;
390 }
391
392 struct ProcessData *data = (struct ProcessData *)entry->data;
393 if (data == NULL) {
394 return NULL;
395 }
396
397 *kbuf = MemdupUserNul(buf, size);
398 if (*kbuf == NULL) {
399 return NULL;
400 }
401 *type = (ProcessDataType)data->type;
402 return ProcGetProcessCB(data);
403 }
404
ProcIDMapWrite(struct ProcFile * file,const char * buf,size_t size,loff_t * ppos)405 static ssize_t ProcIDMapWrite(struct ProcFile *file, const char *buf, size_t size, loff_t *ppos)
406 {
407 (void)ppos;
408 char *kbuf = NULL;
409 int ret;
410 unsigned int intSave;
411 ProcessDataType type = PROC_P_TYPE_MAX;
412 LosProcessCB *processCB = ProcUidGidMapWriteCheck(file, buf, size, &kbuf, &type);
413 if (processCB == NULL) {
414 return -EINVAL;
415 }
416
417 SCHEDULER_LOCK(intSave);
418 if ((processCB->credentials == NULL) || (processCB->credentials->userContainer == NULL)) {
419 SCHEDULER_UNLOCK(intSave);
420 (void)LOS_MemFree(m_aucSysMem1, kbuf);
421 return -EINVAL;
422 }
423 UserContainer *userContainer = processCB->credentials->userContainer;
424 if (userContainer->parent == NULL) {
425 SCHEDULER_UNLOCK(intSave);
426 (void)LOS_MemFree(m_aucSysMem1, kbuf);
427 return -EPERM;
428 }
429 if (type == PROC_UID_MAP) {
430 ret = OsUserContainerMapWrite(file, kbuf, size, CAP_SETUID,
431 &userContainer->uidMap, &userContainer->parent->uidMap);
432 } else {
433 ret = OsUserContainerMapWrite(file, kbuf, size, CAP_SETGID,
434 &userContainer->gidMap, &userContainer->parent->gidMap);
435 }
436 SCHEDULER_UNLOCK(intSave);
437 (void)LOS_MemFree(m_aucSysMem1, kbuf);
438 return ret;
439 }
440
ProcIDMapRead(struct SeqBuf * seqBuf,void * v)441 static int ProcIDMapRead(struct SeqBuf *seqBuf, void *v)
442 {
443 unsigned int intSave;
444 if ((seqBuf == NULL) || (v == NULL)) {
445 return -EINVAL;
446 }
447 struct ProcessData *data = (struct ProcessData *)v;
448 LosProcessCB *processCB = ProcGetProcessCB(data);
449
450 SCHEDULER_LOCK(intSave);
451 if ((processCB->credentials == NULL) || (processCB->credentials->userContainer == NULL)) {
452 SCHEDULER_UNLOCK(intSave);
453 return -EINVAL;
454 }
455 UserContainer *userContainer = processCB->credentials->userContainer;
456 if ((userContainer != NULL) && (userContainer->parent == NULL)) {
457 UidGidExtent uidGidExtent = userContainer->uidMap.extent[0];
458 SCHEDULER_UNLOCK(intSave);
459 (void)LosBufPrintf(seqBuf, "%d %d %u\n", uidGidExtent.first, uidGidExtent.lowerFirst,
460 uidGidExtent.count);
461 return 0;
462 }
463 SCHEDULER_LOCK(intSave);
464 return 0;
465 }
466
467 static const struct ProcFileOperations UID_GID_MAP_FOPS = {
468 .read = ProcIDMapRead,
469 .write = ProcIDMapWrite,
470 };
471 #endif
472
ProcProcessRead(struct SeqBuf * m,void * v)473 static int ProcProcessRead(struct SeqBuf *m, void *v)
474 {
475 if ((m == NULL) || (v == NULL)) {
476 return -EINVAL;
477 }
478 struct ProcessData *data = (struct ProcessData *)v;
479 switch (data->type) {
480 case PROC_PID_MEM:
481 return ProcessMemInfoRead(m, ProcGetProcessCB(data));
482 #ifdef LOSCFG_KERNEL_CPUP
483 case PROC_PID_CPUP:
484 return ProcessCpupRead(m, ProcGetProcessCB(data));
485 #endif
486 default:
487 break;
488 }
489 return -EINVAL;
490 }
491
492 static const struct ProcFileOperations PID_FOPS = {
493 .read = ProcProcessRead,
494 };
495
496 static struct ProcProcess g_procProcess[] = {
497 {
498 .name = NULL,
499 .mode = S_IFDIR | S_IRWXU | S_IRWXG | S_IROTH,
500 .type = PROC_PID,
501 .fileOps = &PID_FOPS
502
503 },
504 {
505 .name = "meminfo",
506 .mode = 0,
507 .type = PROC_PID_MEM,
508 .fileOps = &PID_FOPS
509 },
510 #ifdef LOSCFG_KERNEL_CPUP
511 {
512 .name = "cpup",
513 .mode = 0,
514 .type = PROC_PID_CPUP,
515 .fileOps = &PID_FOPS
516
517 },
518 #endif
519 #ifdef LOSCFG_KERNEL_CONTAINER
520 {
521 .name = "container",
522 .mode = S_IFDIR | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH,
523 .type = CONTAINER,
524 .fileOps = &PID_CONTAINER_FOPS
525
526 },
527 #ifdef LOSCFG_PID_CONTAINER
528 {
529 .name = "container/pid",
530 .mode = S_IFLNK,
531 .type = PID_CONTAINER,
532 .fileOps = &PID_CONTAINER_FOPS
533 },
534 {
535 .name = "container/pid_for_children",
536 .mode = S_IFLNK,
537 .type = PID_CHILD_CONTAINER,
538 .fileOps = &PID_CONTAINER_FOPS
539 },
540 #endif
541 #ifdef LOSCFG_UTS_CONTAINER
542 {
543 .name = "container/uts",
544 .mode = S_IFLNK,
545 .type = UTS_CONTAINER,
546 .fileOps = &PID_CONTAINER_FOPS
547 },
548 #endif
549 #ifdef LOSCFG_MNT_CONTAINER
550 {
551 .name = "container/mnt",
552 .mode = S_IFLNK,
553 .type = MNT_CONTAINER,
554 .fileOps = &PID_CONTAINER_FOPS
555 },
556 #endif
557 #ifdef LOSCFG_IPC_CONTAINER
558 {
559 .name = "container/ipc",
560 .mode = S_IFLNK,
561 .type = IPC_CONTAINER,
562 .fileOps = &PID_CONTAINER_FOPS
563 },
564 #endif
565 #ifdef LOSCFG_TIME_CONTAINER
566 {
567 .name = "container/time",
568 .mode = S_IFLNK,
569 .type = TIME_CONTAINER,
570 .fileOps = &PID_CONTAINER_FOPS
571 },
572 {
573 .name = "container/time_for_children",
574 .mode = S_IFLNK,
575 .type = TIME_CHILD_CONTAINER,
576 .fileOps = &PID_CONTAINER_FOPS
577 },
578 {
579 .name = "time_offsets",
580 .mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH,
581 .type = TIME_CONTAINER,
582 .fileOps = &TIME_CONTAINER_FOPS
583 },
584 #endif
585 #ifdef LOSCFG_IPC_CONTAINER
586 {
587 .name = "container/user",
588 .mode = S_IFLNK,
589 .type = USER_CONTAINER,
590 .fileOps = &PID_CONTAINER_FOPS
591 },
592 {
593 .name = "uid_map",
594 .mode = 0,
595 .type = PROC_UID_MAP,
596 .fileOps = &UID_GID_MAP_FOPS
597 },
598 {
599 .name = "gid_map",
600 .mode = 0,
601 .type = PROC_GID_MAP,
602 .fileOps = &UID_GID_MAP_FOPS
603 },
604 #endif
605 #ifdef LOSCFG_IPC_CONTAINER
606 {
607 .name = "container/net",
608 .mode = S_IFLNK,
609 .type = NET_CONTAINER,
610 .fileOps = &PID_CONTAINER_FOPS
611 },
612 #endif
613 #endif
614 };
615
ProcFreeProcessDir(struct ProcDirEntry * processDir)616 void ProcFreeProcessDir(struct ProcDirEntry *processDir)
617 {
618 if (processDir == NULL) {
619 return;
620 }
621 RemoveProcEntry(processDir->name, NULL);
622 }
623
ProcCreatePorcess(UINT32 pid,struct ProcProcess * porcess,uintptr_t processCB)624 static struct ProcDirEntry *ProcCreatePorcess(UINT32 pid, struct ProcProcess *porcess, uintptr_t processCB)
625 {
626 int ret;
627 struct ProcDataParm dataParm;
628 char pidName[PROC_PID_DIR_LEN] = {0};
629 struct ProcessData *data = (struct ProcessData *)malloc(sizeof(struct ProcessData));
630 if (data == NULL) {
631 return NULL;
632 }
633 if (pid != OS_INVALID_VALUE) {
634 if (porcess->name != NULL) {
635 ret = snprintf_s(pidName, PROC_PID_DIR_LEN, PROC_PID_DIR_LEN - 1, "%u/%s", pid, porcess->name);
636 } else {
637 ret = snprintf_s(pidName, PROC_PID_DIR_LEN, PROC_PID_DIR_LEN - 1, "%u", pid);
638 }
639 } else {
640 if (porcess->name != NULL) {
641 ret = snprintf_s(pidName, PROC_PID_DIR_LEN, PROC_PID_DIR_LEN - 1, "%s/%s", "self", porcess->name);
642 } else {
643 ret = snprintf_s(pidName, PROC_PID_DIR_LEN, PROC_PID_DIR_LEN - 1, "%s", "self");
644 }
645 }
646 if (ret < 0) {
647 free(data);
648 return NULL;
649 }
650
651 data->process = processCB;
652 data->type = porcess->type;
653 dataParm.data = data;
654 dataParm.dataType = PROC_DATA_FREE;
655 struct ProcDirEntry *container = ProcCreateData(pidName, porcess->mode, NULL, porcess->fileOps, &dataParm);
656 if (container == NULL) {
657 free(data);
658 PRINT_ERR("create /proc/%s error!\n", pidName);
659 return NULL;
660 }
661 return container;
662 }
663
ProcCreateProcessDir(UINT32 pid,uintptr_t process)664 int ProcCreateProcessDir(UINT32 pid, uintptr_t process)
665 {
666 unsigned int intSave;
667 struct ProcDirEntry *pidDir = NULL;
668 for (int index = 0; index < (sizeof(g_procProcess) / sizeof(struct ProcProcess)); index++) {
669 struct ProcProcess *procProcess = &g_procProcess[index];
670 struct ProcDirEntry *dir = ProcCreatePorcess(pid, procProcess, process);
671 if (dir == NULL) {
672 PRINT_ERR("create /proc/%s error!\n", procProcess->name);
673 goto CREATE_ERROR;
674 }
675 if (index == 0) {
676 pidDir = dir;
677 }
678 }
679
680 if (process != 0) {
681 SCHEDULER_LOCK(intSave);
682 ((LosProcessCB *)process)->procDir = pidDir;
683 SCHEDULER_UNLOCK(intSave);
684 }
685
686 return 0;
687
688 CREATE_ERROR:
689 if (pidDir != NULL) {
690 RemoveProcEntry(pidDir->name, NULL);
691 }
692 return -1;
693 }
694 #endif /* LOSCFG_PROC_PROCESS_DIR */
695
ProcessProcFill(struct SeqBuf * m,void * v)696 static int ProcessProcFill(struct SeqBuf *m, void *v)
697 {
698 (void)v;
699 (void)OsShellCmdTskInfoGet(OS_ALL_TASK_MASK, m, OS_PROCESS_INFO_ALL);
700 return 0;
701 }
702
703 static const struct ProcFileOperations PROCESS_PROC_FOPS = {
704 .read = ProcessProcFill,
705 };
706
ProcProcessInit(void)707 void ProcProcessInit(void)
708 {
709 struct ProcDirEntry *pde = CreateProcEntry("process", 0, NULL);
710 if (pde == NULL) {
711 PRINT_ERR("create /proc/process error!\n");
712 return;
713 }
714 pde->procFileOps = &PROCESS_PROC_FOPS;
715
716 #ifdef LOSCFG_PROC_PROCESS_DIR
717 int ret = ProcCreateProcessDir(OS_INVALID_VALUE, 0);
718 if (ret < 0) {
719 PRINT_ERR("Create proc process self dir failed!\n");
720 }
721
722 ret = ProcCreateProcessDir(OS_USER_ROOT_PROCESS_ID, (uintptr_t)OsGetUserInitProcess());
723 if (ret < 0) {
724 PRINT_ERR("Create proc process %d dir failed!\n", OS_USER_ROOT_PROCESS_ID);
725 }
726 #endif
727 return;
728 }
729