Skip to content

Commit

Permalink
Collect nropen for each process to monitor if fd leaks
Browse files Browse the repository at this point in the history
This patch collects and displays the current number of opened file
descriptors for each process to monitor if fd leaks. As each thread
has the same fds with its process, there is no need to collect each
thread's fd numbers then.

Considering users may set the nr_open limit to a very large number,
we regard MAX_OPEN to be 10000 to avoid further performance
degradation.

Signed-off-by: Fei Li <lifei.shirley@bytedance.com>
  • Loading branch information
ShirleyFei committed Mar 15, 2023
1 parent eb158ef commit 8aca4f3
Show file tree
Hide file tree
Showing 9 changed files with 78 additions and 3 deletions.
1 change: 1 addition & 0 deletions deviate.c
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,7 @@ calcdiff(struct tstat *devstat, const struct tstat *curstat,
devstat->cpu.cgcpuweight = curstat->cpu.cgcpuweight;
devstat->cpu.cgcpumax = curstat->cpu.cgcpumax;
devstat->cpu.cgcpumaxr = curstat->cpu.cgcpumaxr;
devstat->cpu.nropen = curstat->cpu.nropen;

if (curstat->cpu.wchan[0])
strcpy(devstat->cpu.wchan, curstat->cpu.wchan);
Expand Down
2 changes: 2 additions & 0 deletions json.c
Original file line number Diff line number Diff line change
Expand Up @@ -1030,6 +1030,7 @@ static void json_print_PRC(char *hp, struct sstat *ss, struct tstat *ps, int nac
"\"blkdelay\": %lld, "
"\"nvcsw\": %llu, "
"\"nivcsw\": %llu, "
"\"nropen\": %d, "
"\"sleepavg\": %d}",
ps->gen.pid,
ps->cpu.utime,
Expand All @@ -1043,6 +1044,7 @@ static void json_print_PRC(char *hp, struct sstat *ss, struct tstat *ps, int nac
ps->cpu.blkdelay*1000/hertz,
ps->cpu.nvcsw,
ps->cpu.nivcsw,
ps->cpu.nropen,
ps->cpu.sleepavg);
}

Expand Down
5 changes: 5 additions & 0 deletions man/atop.1
Original file line number Diff line number Diff line change
Expand Up @@ -1661,6 +1661,11 @@ Time that the process has been finished. If the process is still running,
this field shows `active'.
.PP
.TP 9
.B NROPEN
Current number of opened file descriptors (fds) for each process, at least 0.
As each thread has the same fds with its process, this filed shows `-`.
.PP
.TP 9
.B ENVID
Virtual environment identified (OpenVZ only).
.PP
Expand Down
3 changes: 2 additions & 1 deletion parseable.c
Original file line number Diff line number Diff line change
Expand Up @@ -785,7 +785,7 @@ print_PRC(char *hp, struct sstat *ss, struct tstat *ps, int nact)
for (i=0; i < nact; i++, ps++)
{
printf("%s %d %s %c %u %lld %lld %d %d %d %d %d %d %d %c "
"%llu %s %llu %d %d %llu %llu\n",
"%llu %s %llu %d %d %d %llu %llu\n",
hp,
ps->gen.pid,
spaceformat(ps->gen.name, namout),
Expand All @@ -804,6 +804,7 @@ print_PRC(char *hp, struct sstat *ss, struct tstat *ps, int nact)
ps->cpu.rundelay,
spaceformat(ps->cpu.wchan, wchanout),
ps->cpu.blkdelay,
ps->cpu.nropen,
cgroupv2max(ps->gen.isproc, ps->cpu.cgcpumax),
cgroupv2max(ps->gen.isproc, ps->cpu.cgcpumaxr),
ps->cpu.nvcsw,
Expand Down
35 changes: 35 additions & 0 deletions photoproc.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ static int proccont(struct tstat *);
static void proccmd(struct tstat *);
static void procsmaps(struct tstat *);
static void procwchan(struct tstat *);
static void procfd(struct tstat *);
static count_t procschedstat(struct tstat *);
static int proccgroupv2(struct tstat *);
static struct cgroupv2vals *
Expand Down Expand Up @@ -218,6 +219,8 @@ photoproc(struct tstat *tasklist, int maxtask)
if (getwchan)
procwchan(curtask);

procfd(curtask);

// read network stats from netatop
netatop_gettask(curtask->gen.tgid, 'g', curtask);

Expand Down Expand Up @@ -981,6 +984,38 @@ procschedstat(struct tstat *curtask)
return curtask->cpu.rundelay;
}

/*
** get current number of opened file descriptors for process
** to monitor if fd leaks.
** Considering users may set the max number of open files to
** a very large number, we regard MAX_OPEN to be 10000.
*/
#define MAX_OPEN 10000

static void
procfd(struct tstat *curtask)
{
DIR *dirp;
struct dirent *dentry;
int fd_num = 0;

if ( (dirp = opendir("fd")) )
{
while ( (dentry = readdir(dirp)) )
{
if ( isdigit(dentry->d_name[0]) )
fd_num++;

if ( fd_num >= MAX_OPEN )
break;
}

curtask->cpu.nropen = fd_num;

closedir(dirp);
}
}

/*
** CGROUP V2 specific items
*/
Expand Down
3 changes: 2 additions & 1 deletion photoproc.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ struct tstat {
int cgcpuweight; /* cgroup cpu.weight */
int cgcpumax; /* cgroup cpu.max percentage */
int cgcpumaxr; /* restrictive percentage */
int ifuture[3]; /* reserved for future use */
int nropen; /* number of opened files */
int ifuture[2]; /* reserved for future use */
char wchan[16]; /* wait channel string */
count_t rundelay; /* schedstat rundelay (nanosec) */
count_t blkdelay; /* blkio delay (ticks) */
Expand Down
3 changes: 2 additions & 1 deletion showlinux.c
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,7 @@ proc_printdef *allprocpdefs[]=
&procprt_STTIME,
&procprt_ENDATE,
&procprt_ENTIME,
&procprt_NROPEN,
&procprt_THR,
&procprt_TRUN,
&procprt_TSLPI,
Expand Down Expand Up @@ -1300,7 +1301,7 @@ priphead(int curlist, int totlist, char *showtype, char *showorder,
"RUID:8 RGID:8 EUID:5 EGID:4 "
"SUID:3 SGID:2 FSUID:3 FSGID:2 "
"STDATE:7 STTIME:7 ENDATE:5 ENTIME:5 "
"ST:6 EXC:6 S:6 SORTITEM:10 CMD:10",
"NROPEN:5 ST:6 EXC:6 S:6 SORTITEM:10 CMD:10",
"built-in varprocs");

make_proc_prints(cmdprocs, MAXITEMS,
Expand Down
1 change: 1 addition & 0 deletions showlinux.h
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,7 @@ extern proc_printdef procprt_STDATE;
extern proc_printdef procprt_STTIME;
extern proc_printdef procprt_ENDATE;
extern proc_printdef procprt_ENTIME;
extern proc_printdef procprt_NROPEN;
extern proc_printdef procprt_THR;
extern proc_printdef procprt_TRUN;
extern proc_printdef procprt_TSLPI;
Expand Down
28 changes: 28 additions & 0 deletions showprocs.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ char *procprt_ENDATE_a(struct tstat *, int, int);
char *procprt_ENDATE_e(struct tstat *, int, int);
char *procprt_ENTIME_a(struct tstat *, int, int);
char *procprt_ENTIME_e(struct tstat *, int, int);
char *procprt_NROPEN_a(struct tstat *, int, int);
char *procprt_NROPEN_e(struct tstat *, int, int);
char *procprt_THR_a(struct tstat *, int, int);
char *procprt_THR_e(struct tstat *, int, int);
char *procprt_TRUN_a(struct tstat *, int, int);
Expand Down Expand Up @@ -1235,6 +1237,32 @@ proc_printdef procprt_ENTIME =
{ " ENTIME ", "ENTIME", procprt_ENTIME_a, procprt_ENTIME_e, 8 };
/***************************************************************/
char *
procprt_NROPEN_a(struct tstat *curstat, int avgval, int nsecs)
{
static char buf[64];

if (curstat->gen.isproc)
sprintf(buf, "%*d", procprt_NROPEN.width, curstat->cpu.nropen);
else
sprintf(buf, "%*s", procprt_NROPEN.width, "-");

return buf;
}

char *
procprt_NROPEN_e(struct tstat *curstat, int avgval, int nsecs)
{
static char buf[64];

sprintf(buf, "%*s", procprt_NROPEN.width, "-");

return buf;
}

proc_printdef procprt_NROPEN =
{ " NROPEN", "NROPEN", procprt_NROPEN_a, procprt_NROPEN_e, 7 };
/***************************************************************/
char *
procprt_THR_a(struct tstat *curstat, int avgval, int nsecs)
{
static char buf[15];
Expand Down

0 comments on commit 8aca4f3

Please sign in to comment.