• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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