I. scenario 1. obtain the absolute path of the file. This is obtained by FD. 2. obtain the absolute path of the process. two data structures related to the Linux kernel and Path: 1. the struct dentry file name is stored in the struct prototype:
Struct dentry {int d_mounted; struct inode * d_inode;/* Where the name belongs to-null is negative */struct hlist_node d_hash;/* lookup hash list */struct dentry * d_parent; /* parent directory */struct qstr d_name;/* the file name is here * // * omitting some content */};
2. Mount information of the struct vfsmount file system. The mount command structure prototype is as follows:
Struct vfsmount {struct list_head mnt_hash; struct vfsmount * mnt_parent;/* FS we are mounted on */struct dentry * mnt_mountpoint;/* dentry of mountpoint */struct dentry * mnt_root; /* root of the mounted tree * // * omitting some content */};
3. Trace back from struct dentry and struct vfsmount until/, You can piece together the complete path to obtain the absolute path of the process. Example 1:
Void get_absolute_path () {/* assume that 512 is sufficient */char * tmp_path [512]; char * PTR = NULL; struct dentry * dentry = NULL; struct vfsmount * mnt = NULL; memset (tmp_path, '\ 0', 512); PTR = tmp_path + 512-1; task_lock (current ); /* Get the Process Working dentry */dentry = Current-> FS-> pwd. dentry;/* Get the Process Working vfsmount */mnt = Current-> FS-> pwd. MNT; do {/* process the dentry */while (dentry && Dentry-> d_name.name & strcmp (dentry-> d_name.name, "/") {PTR = PTR-strlen (dentry-> d_name.name ); if (PTR <= tmp_path + strlen (dentry-> d_name.name) + 1) {break;} memcpy (PTR, dentry-> d_name.name, strlen (dentry-> d_name.name )); * (-- PTR) = '/'; dentry = dentry-> d_parent;}/* process the filesystem mountpoint, break through the mount point */If (mnt & MNT-> mnt_mountpoint \ & MNT-> mnt_mountpoint-> d_name.name \ & strcmp (MNT-> Mnt_mountpoint-> d_name.name, "/") {dentry = mnt-> mnt_mountpoint; PTR = PTR-strlen (dentry-> d_name.name ); if (PTR <= tmp_path + strlen (dentry-> d_name.name) + 1) {break;} memcpy (PTR, dentry-> d_name.name, strlen (dentry-> d_name.name )); * (-- PTR) = '/'; mnt = mnt-> mnt_parent; dentry = dentry-> d_parent ;}} while (0! = Strcmp (MNT-> mnt_mountpoint-> d_name.name, "/");/* end do * // * until the mount point of the file system is/*/task_unlock (current ); printk ("full path: % s \ n", PTR );}
due to your own implementation, if you encounter a mount-rbind directory, the processing may fail. For a better method, see the next decomposition