OS-5167: cached v_path should be kept fresh

Details

Issue Type:Bug
Priority:4 - Normal
Status:Resolved
Created at:2016-02-18T17:06:55.000Z
Updated at:2016-06-10T18:53:20.000Z

People

Created by:Patrick Mooney [X]
Reported by:Patrick Mooney [X]
Assigned to:Patrick Mooney [X]

Resolution

Fixed: A fix for this issue is checked into the tree and tested.
(Resolution Date: 2016-06-10T18:53:20.000Z)

Fix Versions

2016-06-23 Rock n' Rummy (Release Date: 2016-06-23)

Labels

lxbrand

Description

While debugging a separate issue, I'm observing readlink throwing ENOENT for /proc/self/exe. It does not consistently occur.

[pid 79466] execve("/root/winstone/jdk1.7.0_79//bin/java", ["/root/winstone/jdk1.7.0_79//bin/"..., "-jar", "winstone-2.9.jar", "--httpPort=8811", "--httpsPort=8443", "--httpsCertificate=/root/winston"..., "--httpsPrivateKey=/root/winstone"..., "--warfile=sample.war"], ["MANPATH=:/native/usr/share/man", "SHELL=/bin/bash", "TERM=screen-256color", "SSH_CLIENT=50.93.248.179 58927 2"..., "SSH_TTY=/dev/pts/17", "USER=root", "PATH=/usr/local/sbin:/usr/local/"..., "MAIL=/var/mail/root", "_=/root/winstone/jdk1.7.0_79//bi"..., "PWD=/root/winstone", "JAVA_HOME=/root/winstone/jdk1.7."..., "LANG=en_US.UTF-8", "HOME=/root", "SHLVL=2", "LOGNAME=root", "SSH_CONNECTION=50.93.248.179 589"...]) = 0
[pid 79466] brk(0)                      = 0x600af8
[pid 79466] uname({sysname="Linux", nodename="37363e56-6322-4c5b-9abc-3d6ac2ddb992", release="3.16.0", version="BrandZ virtual linux", machine="x86_64", domainname=""}) = 0
[pid 79466] access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
[pid 79466] mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fffff060000
[pid 79466] readlink("/proc/self/exe", 0x7fffffefe7b0, 4096) = -1 ENOENT (No such file or directory)

Comments

Comment by Patrick Mooney [X]
Created at 2016-02-18T17:46:29.000Z
Updated at 2016-02-18T20:09:08.000Z

It appears to be related to certain circumstances where the stale v_path is not purged. In order to provide a value for /proc/<pid>/exe, lxpr_readlink calls vnodetopath. This is failing on the v_path due to the fact that the /root/winstone directory tree had been renamed. (But after entries made it into the dnlc)


Comment by Patrick Mooney [X]
Created at 2016-02-18T19:12:28.000Z

The logic for purging invalid v_path entries only does so on VDIR nodes. In this specific example, the bogus v_path on the vnode for the java binary persists in the dnlc despite failing the validity check.

Even if that vnode were to be purged correctly during the vnodetopath operation, it wouldn't be properly repopulated until a subsequent lookup was performed causing the lxpr_readlink to still fail.


Comment by Patrick Mooney [X]
Created at 2016-02-18T20:01:32.000Z
Updated at 2016-02-18T20:03:24.000Z

In order to solve this problem, I believe that v_path needs to be checked for stale values actions such as VOP_LOOKUP and VOP_CREATE. Here is one way that may be accomplished:

1. A new hrtime_t field to is added to vnode_t. (Named 'v_path_stamp' for this example)
2. If v_path is empty during LOOKUP/CREATE, the child vnode will inherit v_path_stamp from the parent when its v_path is populated.
3. If v_path is not empty, the v_path_stamp is compared between the child and parent. If the child is older than the parent, its v_path is assumed to be stale and is refreshed. Instead of inheriting v_path_stamp from the parent, the current time is used. This should allow concurrent changes at different height in a directory tree to resolve to a correct path at the end of a lookup operation.


Comment by Bot Bot [X]
Created at 2016-06-10T16:47:50.000Z

illumos-joyent commit 0f70e4e (branch master, by Patrick Mooney)

OS-5167 cached v_path should be kept fresh
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>