Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

locate path to a file from inode number

by gnu@perl (Pilgrim)
on Nov 08, 2002 at 15:33 UTC ( [id://211448]=perlquestion: print w/replies, xml ) Need Help??

gnu@perl has asked for the wisdom of the Perl Monks concerning the following question:

I have a situation where I need to track a file through directories on the same files system.

Originally I was going to use File::Find to locate the files, store the information in a hash, wait a little bit do the same routine again and compare the two hashes for differences. This seemed like to much IO just to see if a file moved from one directory to another.

Enter my next idea. Using the cpan module 'ReadDir' I can get the inode numbers of the files in the directory I am using as my starting place for the sake of monitoring. I now have a list of inode numbers and what I would like to do is be able to find the path of a file with inode number XXXXXXX.

This would keep me from having to do all the IO of locating the file every time. I could swear I saw something like this a few years ago. It was a set of shell utilities. One would give you the inode number of a file (note, not ls -i, it was an actual utility) and the other would tell you the file an inode pointed to.

Unfortunately, I cannot recall what these were. Does anyone recall these two utilities or have another way to quickly get the path of a file from the inode number?

TIA, Chad.

Replies are listed 'Best First'.
Re: locate path to a file from inode number
by Abigail-II (Bishop) on Nov 08, 2002 at 16:53 UTC
    You seem to assume the mapping between filenames and i-node numbers is a 1-1 mapping. It isn't. While each filename has one i-node number, more than one filename can have the same i-node number - this is called "links". If you do
    ln old new
    you create a new filename new, but it will have the same i-node number as old. Furthermore, it's also possible that you have a file (and hence an i-node number), without a file name. That happens for instance in the following code:
    my $file = "/tmp/whatever"; open my $fh => "> $file" or die; unlink $file or die;
    The file still exists (and you can write to it), it uses an i-node, but there's no directory with an entry, and hence there's no file name for it.

    Abigail

      One of those questions that I've always wondered about but never been bothered enough to research: is there a way to create a new link to such a file that exists in the inode table but has no other links, using only the inode number? Not that I can supply any practical use - I guess I'm just curious for purposes of orthogonality.

      Makeshifts last the longest.

        This is what fsck does - it'll link unreferenced inodes to lost+found.

        Abigail

Re: locate path to a file from inode number
by Daruma (Curate) on Nov 08, 2002 at 17:00 UTC
    Greetings!!

    I have run accross this issue in the past and solved it by writing Bourne, Korn and BASH shell scripts to find all paths to a single inode.

    In Unix/Linux operating systems, a hard link is basically another path pointing to the same inode. Unfortunately, there's no quick and easy solution for finding all the places (paths) that point to that same inode. Here's the basics of how I've done this in the past.

    1. Use ls -i filename to find the inode of the file in question.
    2. Use find / -inum XXXXXX -print to find the full path for each file pointing to inode XXXXXX.

    Note that this is searching from the root, and can take quite a while. Not necessarily the most desirable of solutions, but it's worked in the past.

    One of our applications makes very heavy use of hard links. Often our clients do not understand hard linking and might move things around or inadvertently break links. I've taken this very shell script idea and used it to help me reconcile the links and report on those that are misplaced, broken or completely missing.

    Are you looking for a perl solution to your problem? If so, I've not yet developed something to trace down inodes. I would certainly like to give it a try, however. If you are looking for a basic shell utility, it's not hard to write one up.

    I note that you mention the utility you saw previously did not use ls -i filename. However, many utilities on Unix systems are collections of the basic shell functions of the system, like ls and find. You might find that down in the workings of this utility, it is making use of good old Unix standard utilites.

    Alternatively, it could be that this utility, if written in something like C, made use of the underlying C functions behind ls and find.

    With a perl solution, it might be hard to get away from the heavy IO you are experiencing in File::Find. I do think it is worth a shot.

    -Daruma
      " find / -inum XXXXXX -print " Use    find [....] -xdev  to stay on the file system the inode number came from.    Not only is this more efficient, but if you find a file with the same inode on a different file system, it will be a different file!

        p
      Yeah, i kind of wanted to keep it to perl if I could. Shortly after posting here I did find the utility, as was pointed out in this thread (ncheck).

      I was really trying to stay away from C if possible, I haven't done C in about 3 years and I'm a little rusty. Also, C would need to be changed from one *nix to another. I would like something more portable. If you can think anything else I am open.

      Also, if anyone does know of a C method of doing something like this, please don't hold back. Like I said, I haven't done C in a little while, but I wouldn't be opposed to it.

      You could install the samesame package and rebuild the links automatically, by typing: find /path/ | samefile -i | samelink
Re: locate path to a file from inode number
by traveler (Parson) on Nov 08, 2002 at 16:23 UTC
    In UNIX a popular tool for getting names from i-numbers is ncheck(1). Under Linux it is part of debugfs(8). To get the i-node information, you can use stat(1). If you use the -t option the output can be parsed by perl quite easily. Of course, I'd use perl's own stat to get the i-number in a perl script...

    HTH, --traveler

Re: locate path to a file from inode number
by gnu@perl (Pilgrim) on Nov 08, 2002 at 18:09 UTC
    In reply to some of the posts thus far:

    First of all, thank all of you for your help. It is truly appreciated.

    Concerning the nature of an inode, I am aware of the issues with links (both hard and symbolic), but in this circumstance I can guarantee that will never arise.

    What I am trying to do is track the location of a file(s) through directories on a filesystem. Now this is not all that hard to do. There are many methods a couple of which being File::Find or a combination of opendir/readdir. The problem is that this has to be done quite regulary, only a few seconds apart in some circumstances. Both of these methods would produce heavy I/O. I am trying to find out if anyone has an idea on tracking a file that is not a heavy impact on the FS.

    I hope that cleared it up a little, I apologize if it was a little vague in the original post.

      Just thought to add this. I have tried the unix utility 'ncheck' but this takes quite a long time. The system I am using runs veritas and the vxfs file system, so the ncheck utility won't work there, but there is ncheck_vxfs, although it is not installed on this box. Probably never will be either (boss is a twit).

      But either way, ncheck is not much more than a glorfied 'find /path -inum <NUM>' as far as this circumstance is concerned.

      What do you mean "track the location of a file through directories"? Is something moving the file around? How do you identify this file? How often is the file moved? What is moving the file?

      If the file is moved infrequently, then saving the path and only searching when it goes missing might work fine. You would basically be caching the location in a known spot. If you have control over the process moving the file, then restrict where it can be moved get it to tell the other process where to find the file.

      There is no quick way to map from inode to the paths that link to the inode. Searching the filesystem is the best you can do.

Re: locate path to a file from inode number
by waswas-fng (Curate) on Nov 08, 2002 at 17:48 UTC
    Could you explain what your are trying to do in more deatail, maybe there is a better (faster) way of tracking what you are trying to track than your solution.

    -Waswas

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://211448]
Approved by Tanalis
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others rifling through the Monastery: (5)
As of 2024-03-28 14:00 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found