Is there any way to create a file on Solaris 10 (ZFS preferably, but UFS would be helpful as well) with a specific inode number? I need to create a file with a large inode, greater than a 32bit integer.
I am trying to test a piece of software which may be incorrectly truncating large inodes down to 32-bit numbers.
Thank you. I changed the filename to "passwd2" because I wasn't sure what impact this would have on my /etc/passwd file.
Was I supposed to run fake_inode.d from within /etc? I created fake_inode.d and passwd2 inside /data, and ran the script from there. It has been saying this for a while:
The dtrace script has hopefully no impact in the target file.
From anywhere you like.
This is the expected output. You should leave the script running for the inode renumbering hack to persist.
As Bartus11 already stated, just use another terminal to experiment with you program expecting a large inode number.
That's the reason why Bartus11 asked you about what your application uses to read the inode number. "ls -li file" uses stat64 which is temporarily "patched" with the dtrace script, "ls -li" alone uses getdents which is not.
You should trace your application to figure out what it uses. Use the truss command to do it.
As far as I'm aware, it is not possible (or very hard to do). Did you confirm that the DTrace script did not change the inode reported by your application?
It is possible that the application is using "fstat*" system calls to get inode numbers. I can prepare a new version of the DTrace script tomorrow, if you are interested.
I'm actually going to be out of town for a few days starting tomorrow so I won't be able to look at this issue until I return, but if is still unresolved when I get back I will attempt to bump the thread. Thanks again!
Kind of. Create more than four billion empty files and the next ones will have an inode not fitting in a 32 bit integer. That might be a lenghty task though ...
I believe that this might be possible (for ufs filesystems) via a combination of fsdb and fsck. I don't have a test system available so I am not going to try it. The general flow would be:
create a filesystem with enough inodes but do not mount it
use fsdb to increment the link count of the desired inode
use fsck to find what now looks like an orphaned file and reattach it to lost+found
I have never tried this because I have always been content with the inode number I get. My feeling is that I could make it work... but I would not be real surprised if I trash the file system a few times during the attempt. I definately would not try this on a filesystem that I cared about.
If you try this and get it to work, please post the fsdb commands used to increment the link count on your chosen inode number.
There are only a few ways to get an inode number. Offhand, I know of getdents(), stat(), and fstat(). Oh, and getdents64(), stat64(), and fstat64().
You can truss the failing process and see what it uses:
truss -f -a -vall -o /truss/output/file command args...
FWIW, I'd bet quite a sum that your program is compiled as a 32-bit process and is using standard calls such as stat(), open(), etc. Read the man page for types.h. Note that an ino_t is an unsigned long, which in an ILP32 environment such as a 32-bit Solaris application is a 32-bit value. But in the LP64 environment of a 64-bit Solaris application an ino_t is 64 bit value. If you need the 64-bit value in a 32-bit application you need to use the open64(), stat64(), etc functions throughout your code.
Read and heed the man pages for lfcompile, lfcompile64, and lf64.
Another thing to watch out for: NFSv2. NFSv2 does not handle 64-bit values. And most NFS mounts are set to autonegotiate. And guess what? The negotiation is done via UDP. Sometimes that fails and you don't get your desired NFSv4 or NFSv3 mount and you get a fallback to an NFSv2 mount. If you have large files, or files with large inode values, you will see some really strange results. Run nfsstat, and if your v2 stats aren't all zero, you're in trouble. So always, always, always specify "vers=3" or "vers=4" in your mounts, or set the minimum version your server will serve to 3. (It's in a config file somewhere, that I'm too lazy to look up right now.)
BTW, when faking the inode for "/etc/passwd", I noticed that I can not login to the server by SSH, so it is probably better to use some other file name for your tests