proc: restore seekdir("/proc", 256) semantics
PATCH 1/1 proc: restore seekdir("/proc", 256) semantics
Long time ago "/proc/self" was an honest symlink and all not-PID entries were output before /proc/$PID. To not lose /proc/self in readdir output after it became permanently positive dentry it was stuck before /proc/1.
One side effect of the change was that the code
d = opendir("/proc");
seekdir(d, 256);stopped pointing to the first PID for applications that want to skip all the crap.
Later "/proc/thread-self" was added in the same way.
It looks like ps and top aren't seeking over /proc but are simply skipping over so nobody noticed.
Restore old behaviour, make seekdir(254) point to /proc/self and seekdir(255) point to /proc/thread-self.
Commit in question:
commit 021ada7dff22d0d9540ff596cb0f8bb866755ee1 procfs: switch /proc/self away from proc_dir_entry
---
fs/proc/base.c | 14 ++++++-------- fs/proc/root.c | 4 ++-- 2 files changed, 8 insertions(+), 10 deletions(-)
fs/proc/base.c +6 -8
@@ -3230,8 +3230,6 @@ static struct tgid_iter next_tgid(struct pid_namespace *ns, struct tgid_iter itereturn iter; } -#define TGID_OFFSET (FIRST_PROCESS_ENTRY + 2) -/* for the /proc/ directory itself, after non-process stuff has been done */ int proc_pid_readdir (struct file *file,struct dir_context *ctx) {
@@ -3239,22 +3237,22 @@ int proc_pid_readdir(struct file *file, struct dir_context *ctx)struct pid_namespace *ns =file_inode (file)->i_sb->s_fs_info;loff_t pos = ctx->pos; -if (pos >=PID_MAX_LIMIT +TGID_OFFSET ) +if (pos >=PID_MAX_LIMIT +FIRST_PROCESS_ENTRY )return 0 ; -if (pos ==TGID_OFFSET -2 ) { +if (pos ==FIRST_PROCESS_ENTRY -2 ) {struct inode *inode =d_inode (ns->proc_self);if (!dir_emit (ctx,"self" ,4 , inode->i_ino,DT_LNK ))return 0 ; ctx->pos = pos = pos +1 ; } -if (pos ==TGID_OFFSET -1 ) { +if (pos ==FIRST_PROCESS_ENTRY -1 ) {struct inode *inode =d_inode (ns->proc_thread_self);if (!dir_emit (ctx,"thread-self" ,11 , inode->i_ino,DT_LNK ))return 0 ; ctx->pos = pos = pos +1 ; } - iter.tgid = pos -TGID_OFFSET ; + iter.tgid = pos -FIRST_PROCESS_ENTRY ; iter.task =NULL ; for (iter = next_tgid(ns, iter); iter.task;
@@ -3267,14 +3265,14 @@ int proc_pid_readdir(struct file *file, struct dir_context *ctx)continue ; len =snprintf (name,sizeof (name),"%u" , iter.tgid); - ctx->pos = iter.tgid +TGID_OFFSET ; + ctx->pos = iter.tgid +FIRST_PROCESS_ENTRY ;if (!proc_fill_cache (file, ctx, name, len, proc_pid_instantiate, iter.task,NULL )) {put_task_struct (iter.task);return 0 ; } } - ctx->pos =PID_MAX_LIMIT +TGID_OFFSET ; + ctx->pos =PID_MAX_LIMIT +FIRST_PROCESS_ENTRY ;return 0 ; }
fs/proc/root.c +2 -2
@@ -162,11 +162,11 @@ static struct dentry *proc_root_lookup(struct inode * dir, struct dentry * dentrstatic int proc_root_readdir (struct file *file,struct dir_context *ctx) { -if (ctx->pos <FIRST_PROCESS_ENTRY ) { +if (ctx->pos <FIRST_PROCESS_ENTRY -2 ) {int error =proc_readdir (file, ctx);if (unlikely (error <=0 ))return error; - ctx->pos =FIRST_PROCESS_ENTRY ; + ctx->pos =FIRST_PROCESS_ENTRY -2 ; }return proc_pid_readdir (file, ctx);
Quoted 12 lines · On Tue, 24 Apr 2018 00:50:09 +0300 Alexey Dobriyan <[email protected]> wrote:
Long time ago "
/proc/self" was an honest symlink and all not-PID entries were output before/proc/$PID. To not lose/proc/selfin readdir output after it became permanently positive dentry it was stuck before/proc/1.One side effect of the change was that the code
d = opendir("/proc"); seekdir(d, 256);stopped pointing to the first PID for applications that want to skip all the crap.
Quoted 8 lines
Later "
/proc/thread-self" was added in the same way.It looks like ps and top aren't seeking over /proc but are simply skipping over so nobody noticed.
Restore old behaviour, make seekdir(254) point to
/proc/selfand seekdir(255) point to/proc/thread-self.
Gee. Why? That's a pretty weird artifact in the userspace API and if we were able to withdraw it without damage then good, let's leave it withdrawn?
I mean, if we're to make this a permanent part of the userspace API then it should be documented in the proc(5) manpage and we should have something in tools/testing/selftests to detect regressions in the interface. Good luck with all that!
Hi!
Quoted 12 lines
Long time ago "
/proc/self" was an honest symlink and all not-PID entries were output before/proc/$PID. To not lose/proc/selfin readdir output after it became permanently positive dentry it was stuck before/proc/1.One side effect of the change was that the code
d = opendir("/proc"); seekdir(d, 256);stopped pointing to the first PID for applications that want to skip all the crap.
Quoted 7 lines
Later "
/proc/thread-self" was added in the same way.It looks like ps and top aren't seeking over /proc but are simply skipping over so nobody noticed.
Restore old behaviour, make seekdir(254) point to
/proc/selfand seekdir(255) point to/proc/thread-self.
Is there anyone relying on the old behaviour?
Pavel
Signature · 2 lines
(english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
Quoted 19 lines · Andrew Morton
Quoted 17 lines · On Tue, 24 Apr 2018 00:50:09 +0300 Alexey Dobriyan <[email protected]> wrote:
Long time ago "
/proc/self" was an honest symlink and all not-PID entries were output before/proc/$PID. To not lose/proc/selfin readdir output after it became permanently positive dentry it was stuck before/proc/1.One side effect of the change was that the code
d = opendir("/proc"); seekdir(d, 256);stopped pointing to the first PID for applications that want to skip all the crap.
Later "
/proc/thread-self" was added in the same way.It looks like ps and top aren't seeking over /proc but are simply skipping over so nobody noticed.
Quoted 7 lines
Quoted 3 lines
Restore old behaviour, make seekdir(254) point to
/proc/selfand seekdir(255) point to/proc/thread-self.Gee. Why? That's a pretty weird artifact in the userspace API and if we were able to withdraw it without damage then good, let's leave it withdrawn?
I checked ps, top and htop, they are not doing seekdir(256). Apparently userspace devs were unaware of this trick. I'll remove this before anyone notices.
Quoted 4 lines
I mean, if we're to make this a permanent part of the userspace API then it should be documented in the proc(5) manpage and we should have something in
tools/testing/selfteststo detect regressions in the interface. Good luck with all that!