lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Message-ID: <1430269652-17705-1-git-send-email-scientist@fb.com>
Date:	Tue, 28 Apr 2015 18:07:32 -0700
From:	Yannick Brosseau <scientist@...com>
To:	<viro@...iv.linux.org.uk>
CC:	<linux-fsdevel@...r.kernel.org>, <linux-kernel@...r.kernel.org>,
	<kernel-team@...com>, Yannick Brosseau <scientist@...com>
Subject: [PATCH] proc: Add number of allocated FD in PID/status file

Iterating over the fd directory to count the number of allocated FD in
a process is expensive if you have lots of them. This expose the count
of open FDs from the fdtable open_fds bitmap.

Signed-off-by: Yannick Brosseau <scientist@...com>
---
 Documentation/filesystems/proc.txt |  3 ++-
 fs/file.c                          | 12 ++++++++++++
 fs/proc/array.c                    | 11 +++++++----
 include/linux/fdtable.h            |  2 +-
 4 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt
index c3b6b30..d2ceb81 100644
--- a/Documentation/filesystems/proc.txt
+++ b/Documentation/filesystems/proc.txt
@@ -205,7 +205,7 @@ asynchronous manner and the value may not be very precise. To see a precise
 snapshot of a moment, you can see /proc/<pid>/smaps file and scan page table.
 It's slow but very precise.
 
-Table 1-2: Contents of the status files (as of 3.20.0)
+Table 1-2: Contents of the status files (as of 4.1.0)
 ..............................................................................
  Field                       Content
  Name                        filename of the executable
@@ -220,6 +220,7 @@ Table 1-2: Contents of the status files (as of 3.20.0)
  Uid                         Real, effective, saved set, and  file system UIDs
  Gid                         Real, effective, saved set, and  file system GIDs
  FDSize                      number of file descriptor slots currently allocated
+ FDAlloc		     number of file descriptor allocated
  Groups                      supplementary group list
  NStgid                      descendant namespace thread group ID hierarchy
  NSpid                       descendant namespace process ID hierarchy
diff --git a/fs/file.c b/fs/file.c
index 93c5f89..caa973b 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -236,6 +236,18 @@ static int count_open_files(struct fdtable *fdt)
 	return i;
 }
 
+int count_open_files_exact(struct fdtable *fdt)
+{
+	int size = fdt->max_fds;
+	int i, count = 0;
+
+	for (i = 0; i <  size / BITS_PER_LONG; i++)
+		if (fdt->open_fds[i])
+			count += hweight_long(fdt->open_fds[i]);
+
+	return count;
+}
+
 /*
  * Allocate a new files structure and copy contents from the
  * passed in files structure.
diff --git a/fs/proc/array.c b/fs/proc/array.c
index fd02a9e..421ea674 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -140,7 +140,7 @@ static inline void task_state(struct seq_file *m, struct pid_namespace *ns,
 	struct task_struct *tracer;
 	const struct cred *cred;
 	pid_t ppid, tpid = 0, tgid, ngid;
-	unsigned int max_fds = 0;
+	unsigned int max_fds = 0, count_fds = 0;
 
 	rcu_read_lock();
 	ppid = pid_alive(p) ?
@@ -155,8 +155,10 @@ static inline void task_state(struct seq_file *m, struct pid_namespace *ns,
 	cred = get_task_cred(p);
 
 	task_lock(p);
-	if (p->files)
+	if (p->files) {
 		max_fds = files_fdtable(p->files)->max_fds;
+		count_fds = count_open_files_exact(files_fdtable(p->files));
+	}
 	task_unlock(p);
 	rcu_read_unlock();
 
@@ -169,7 +171,7 @@ static inline void task_state(struct seq_file *m, struct pid_namespace *ns,
 		"TracerPid:\t%d\n"
 		"Uid:\t%d\t%d\t%d\t%d\n"
 		"Gid:\t%d\t%d\t%d\t%d\n"
-		"FDSize:\t%d\nGroups:\t",
+		"FDSize:\t%d\nFDAlloc:\t%d\nGroups:\t",
 		get_task_state(p),
 		tgid, ngid, pid_nr_ns(pid, ns), ppid, tpid,
 		from_kuid_munged(user_ns, cred->uid),
@@ -180,7 +182,8 @@ static inline void task_state(struct seq_file *m, struct pid_namespace *ns,
 		from_kgid_munged(user_ns, cred->egid),
 		from_kgid_munged(user_ns, cred->sgid),
 		from_kgid_munged(user_ns, cred->fsgid),
-		max_fds);
+		max_fds,
+		count_fds);
 
 	group_info = cred->group_info;
 	for (g = 0; g < group_info->ngroups; g++)
diff --git a/include/linux/fdtable.h b/include/linux/fdtable.h
index 230f87b..5ca987e 100644
--- a/include/linux/fdtable.h
+++ b/include/linux/fdtable.h
@@ -112,7 +112,7 @@ extern void __fd_install(struct files_struct *files,
 		      unsigned int fd, struct file *file);
 extern int __close_fd(struct files_struct *files,
 		      unsigned int fd);
-
+extern int count_open_files_exact(struct fdtable *fdt);
 extern struct kmem_cache *files_cachep;
 
 #endif /* __LINUX_FDTABLE_H */
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ