I am using dtrace to record all files being deleted.
Is it possible to find out what the symlink target is (if it's a symlink)? I want to output the symlink filename and the target filename for logging in case I need to restore the link later.
One solution I came up with is to use the dtrace "system" function to call my own program that will print out the symlink target: system("myprogram %s") where %s is the full name of the symlink I want to print out the target for.
This works ok (it's a very short C program and does the job) - but is there a way to get the info directly through dtrace, seeing as we are handling the file anyway we should be able to look up the symlink target?
I had a look at the fileinfo_t struct but it doesn't have the symlink target: http://docs.oracle.com/cd/E18752_01/html/817-6223/chp-io-args.html#chp-io-fileinfo
This is my script so far: This is in Solaris 10. (This is probing for fop_remove rather than syscall::unlink and the reason for that is to be able to get the symlink directory in case the user doesn't specify the directory in the call to rm).
#!/usr/sbin/dtrace -s
#pragma D option quiet
fbt::fop_remove:entry
{
self->dir = stringof(args[0]->v_path);
self->file = stringof(args[1]);
}
fbt::fop_remove:return
/self->file != NULL/
{
printf("%s/%s\n", self->dir, self->file);
self->file = 0;
self->dir = 0;
}
thanks!
On Solaris VFS level (aka the vnode_t
structure), the symlink target is not attached to the node for the symlink itself. It's a filesystem implementation detail.
For UFS filesystems, if the pathname of the link target is shorter than 48 Bytes (what UFS calls a 'fast symlink'), it's recorded inline with the inode_t
struct, and you can print the value through DTrace via:
vnode = args[0];
inode = (inode_t*)vnode->v_data;
printf("symlink tgt: %47s\n",
vnode->v_type != VLNK ||
vnode->v_op != ufs_vnodeops ||
inode->i_flags & I_FASTSYMLINK == 0 ?
"[unresolved]" :
(char *)inode->i_db);
For other filesystems / in the generic case, you'd have to use a fsinfo::readlink:return
(or fop::fop_readlink:return
) probe points to get the target - on access, that is, it won't (usually) be retrievable directly from the vnode_t
.