|
31 | 31 | ** -------------------------------------------------------------------------- |
32 | 32 | */ |
33 | 33 |
|
| 34 | +#define _GNU_SOURCE |
34 | 35 | #include <sys/types.h> |
35 | 36 | #include <sys/param.h> |
| 37 | +#include <sys/syscall.h> |
36 | 38 | #include <dirent.h> |
37 | 39 | #include <stdio.h> |
38 | 40 | #include <string.h> |
| 41 | +#include <fcntl.h> |
39 | 42 | #include <unistd.h> |
40 | 43 | #include <ctype.h> |
41 | 44 | #include <time.h> |
@@ -63,6 +66,7 @@ static int proccont(struct tstat *); |
63 | 66 | static void proccmd(struct tstat *); |
64 | 67 | static void procsmaps(struct tstat *); |
65 | 68 | static void procwchan(struct tstat *); |
| 69 | +static void procfd(struct tstat *); |
66 | 70 | static count_t procschedstat(struct tstat *); |
67 | 71 | static int proccgroupv2(struct tstat *); |
68 | 72 | static struct cgroupv2vals * |
@@ -218,6 +222,8 @@ photoproc(struct tstat *tasklist, int maxtask) |
218 | 222 | if (getwchan) |
219 | 223 | procwchan(curtask); |
220 | 224 |
|
| 225 | + procfd(curtask); |
| 226 | + |
221 | 227 | // read network stats from netatop |
222 | 228 | netatop_gettask(curtask->gen.tgid, 'g', curtask); |
223 | 229 |
|
@@ -959,6 +965,57 @@ procschedstat(struct tstat *curtask) |
959 | 965 | return curtask->cpu.rundelay; |
960 | 966 | } |
961 | 967 |
|
| 968 | +/* |
| 969 | +** get current number of opened file descriptors for process |
| 970 | +** to monitor if fd leaks. |
| 971 | +** Considering users may set the max number of open files to |
| 972 | +** a very large number, we use getdents[64] SYSCALL directly |
| 973 | +** instead of glibc's readdir() for performance consideration. |
| 974 | +** Also, define MAX_OPEN to be 1024 * 1024 for display. |
| 975 | +*/ |
| 976 | +struct linux_dirent64 { |
| 977 | + unsigned long d_ino; |
| 978 | + off_t d_off; |
| 979 | + unsigned short d_reclen; |
| 980 | + unsigned char d_type; |
| 981 | + char d_name[]; |
| 982 | +}; |
| 983 | + |
| 984 | +#define MAX_OPEN 1024 * 1024 |
| 985 | + |
| 986 | +static void |
| 987 | +procfd(struct tstat *curtask) |
| 988 | +{ |
| 989 | + int fd, nread, fd_num = 0; |
| 990 | + struct linux_dirent64 *buf, *d; |
| 991 | + unsigned int count = 0; |
| 992 | + |
| 993 | + if ( (fd = open("fd", O_RDONLY | O_DIRECTORY)) != -1) { |
| 994 | + count = MAX_OPEN * sizeof(struct linux_dirent64); |
| 995 | + buf = malloc(count); |
| 996 | + ptrverify(buf, "Malloc failed for process's opened files\n"); |
| 997 | + |
| 998 | + nread = syscall(SYS_getdents64, fd, buf, count); |
| 999 | + if (nread == -1) { |
| 1000 | + curtask->cpu.nropen = -1; |
| 1001 | + } else if (nread == 0) { |
| 1002 | + curtask->cpu.nropen = 0; |
| 1003 | + } else if (nread > 0) { |
| 1004 | + for (int bops = 0; bops < nread;) { |
| 1005 | + d = (struct linux_dirent64 *)((char *)buf + bops); |
| 1006 | + bops += d->d_reclen; |
| 1007 | + fd_num++; |
| 1008 | + } |
| 1009 | + curtask->cpu.nropen = fd_num - 2; |
| 1010 | + } |
| 1011 | + |
| 1012 | + close(fd); |
| 1013 | + free(buf); |
| 1014 | + } else { |
| 1015 | + curtask->cpu.nropen = 0; |
| 1016 | + } |
| 1017 | +} |
| 1018 | + |
962 | 1019 | /* |
963 | 1020 | ** CGROUP V2 specific items |
964 | 1021 | */ |
|
0 commit comments