Find most recently accessed file from give files in C - c

How to get most recently accessed file in Linux?
I used stat() call checking for st_atime, but it is not updating if i open and read the file.

You can check if your filesystem is mounted with the noatime or relatime option:
greek0#orest:/home/greek0$ cat /proc/mounts
/dev/md0 / ext3 rw,noatime,errors=remount-ro,data=ordered 0 0
...
These mount options are often used because they increase filesystem performance. Without them, every single read of a file turns into a write to the disk (for updating the atime).
In general, you can't rely on atime to have any useful meaning on most computers.
If it's Ok to only detect accesses to files that happen while your program is running, you can look into inotify. It provides a method to be notified of currently ongoing filesystem accesses.
If that doesn't satisfy your requirements, I'm afraid you're out of luck.

Related

Are existing proc files available to the kernel if system loses access all sudden to root file system such as can't read disk

If the answer is NO, that if root filesystem disk partition is lost for any reason, like dying hard drive or if booted via nfs rootfs and network is lost etc, if in these cases the kernel "no longer" has access to read or write to previously existing /proc/ files, then that's the answer, NO.
If the answer is YES, that the kernel still has access to already existing /proc/ because they are virtual and not really on any filesystem and so are still available after to kernel even after root "/" is lost, then how can I do the "equivalent" of:
"echo 1 > /proc/existingfile" but WITHOUT using call_usermodehelper but via some SYSCALL? where the "echo 1 >" can be replaced with some kernel SYSCALL so that "userland" is not relied upon because it won't be available in my scenario where root partition disappeared.
(UPDATE: In reply to a comment, perhaps SYSCALL was the wrong word, I don't care if SYSCALLS might be possible or impossible to call from inside kernel because they were made with user-space in mind. SysCall method is not the point, but I simply want to know of "any" possible method whereby I can trigger a "WRITE" to an existing /proc/file without the need of reading any input from "user-space".)
(UPDATE2: Would be nice if some Kernel authority can answer if the kernel still has access to read/write to a /proc/file even after the root "/" file system (let's say its rootfs over nfs) has become "unavailable". So far comments "contradict" on this issue, some say NO, others say YES, and others unsure etc.)
I do not want to simply cut to the chase and just do the action that putting a 1 into the existing file would have done based on kernel code. I want it to go through the usual vfs_write etc pathway "before" it does what echo 1 into /proc/existing file does. (I'm debugging some crashes/issues that's why I want it to go via this specific route.)
maybe related?
Access /proc fs variable from other parts of Kernel code

Get filesystem creation date in C

I need to know the creation datetime of the filesystem on a disk (in a Linux machine) with C. I would like to avoid using shell commands, such as
tune2fs -l /dev/sdb2 | grep 'Filesystem created:'
and make a parser.
Thanks
From a program coded in C (or in any language capable of calling C routines) you would use the stat(2) system call (or, with recent kernels and some file systems, the statx(2) one) to query the creation time of a given file (or directory). Of course, commands like ls(1) or stat(1) are using internally that stat(2) system calll.
There is no standard, and file system neutral, way to get the creation time of a given file system. That information is not always kept. I guess that FAT filesystems, or distributed file systems such as NFS, don't keep that.
You might use stat(2) on the mount point of that file system.
The statfs(2) system call retrieves some filesystem information, but does not give any time stamps.
For ext4 file systems, see ext4(5) and use proc(5). You might parse /proc/mounts and some /proc/fs/ext4/*/ directory. The pseudofiles in /proc/ can be parsed quickly and usually won't involve physical disk IO.
You could also work at the ext2/3/4 disk partition level, on an unmounted file ext[234] system, with a library like (or programs from) e2fsprogs. You should not access (even just read) a disk partition containing some file system if that file system is mounted.
(your question should give some motivation and context)

Reading/Writing to Disk directly using C [duplicate]

This question already has answers here:
Direct access to hard disk with no FS from C program on Linux
(3 answers)
Closed 7 years ago.
i know how to read/write a from/to a file in c using FILE pointer.But i want to go one step ahead and learn how to directly read/write to the disk partition.Also what is the difference between writing to a file and to a disk.Also can i manipulate the content already present on disk such as videos,images etc.
I am using C language on Linux 14.04 with gcc as my compiler.
TIA.
One of the nice things about UNIX/Linux systems is that pretty much anything you want to access is a file.
Linux has a /dev filesystem that has special files that are actually block and character devices. Among these are the raw disk partitions. If you run df -k, you'll see the devices associated with your currently mounted filesystems.
On one of my systems, this command outputs the following:
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/mapper/vg0-root 1040280 427008 560844 44% /
/dev/mapper/vg0-var 4161216 3275900 675604 83% /var
/dev/mapper/vg0-usr 30559268 14297456 14721716 50% /usr
/dev/mapper/vg0-prod 30526500 11905152 17082892 42% /prod
/dev/mapper/vg0-tmp 4161216 175168 3776336 5% /tmp
/dev/sda1 256681 28231 215196 12% /boot
From this example, we can see that the /var filesystem is associated with the special file /dev/mapper/vg0-var. So if you were to open that file, you would get access to the raw filesystem. Then you need to understand exactly how the filesystem is laid out to find what you're looking for.
Note that in order to do this, you need root access.
Warning!
It is generally a bad idea to access a mounted filesystem in this way. The OS caches writes to the filesystem, so what's physically on disk might not match what the OS says is there. Writing directly to a filesystem in this way can damage the filesystem because you are bypassing the OS's caching mechanisms.

Working with block special files/devices to implement a filesystem

I've implemented a basic filesystem using FUSE, with all foreseeable POSIX functionality implemented [naturally I haven't even profiled yet ;)]. Currently I'm able to run the filesystem on a regular file (st_mode & S_IFREG), but the next step in development is to host it on an actual block device. Running my code as is, immediately fails on reading st_size after calling fstat on the device. Of course I don't expect the problems to stop there so:
What changes are required to operate on block devices as opposed to regular files?
What are some special considerations I need to make with regard to performance, limitations, special features and the like?
Are there any tutorials and references with dealing with block special files? Googling has turned up very little useful; I only have background knowledge (ironically from MSDN in my dark past) and some scanty information in the manpages.
Update0
I've pointed out what I mean by "regular file".
I don't want to concentrate on getting the device size, I want general guidelines for differences between regular files and device files with respect to performance and usage.
Currently I'm able to run the
filesystem on a regularly file, but
the next step in development is to
host it on an actual block device
I don't completely understand what you mean - I assume you are saying that "you currently save your filesystem data to a plain file on a normally mounted filesystem - but now wish to use a raw block device for your data storage".
If so - having done this a few times - I'd advise the following:
Never use an "actual" block device for you filesystem. Always use a partition. There are several rarely-used partition-types that you can use to denote that such a filesystem may be your filesystem type, and that your filesystem can check and mount it if it is such. Thus, you will never be running on something like "/dev/sdb", but rather you will store you data on one such as /dev/sdb1, and assign it some partition type. This has obvious advantages, like allowing your filesystem to be co-resident on a single phyiscal disk as another, etc.
If you are implementing any caching in your filesystem (like Linux does with the Page Cache), do all I/Os to the block devices with O_DIRECT. This requires you to pass page-alligned memory to do all I/O, and requires that the requests be sector/block aligned - but will remove a data copy which would otherwise be required when data is moved from the block device to the page cache, then from the page-cache to your user-space [filesystem] reader.
What do you mean that the fstat "fails"? This is an fstat trying to determing the length of the block device? Do you receive an error? What is it?
block devices behave very much like files - tools like dd can operate on them without any special handling. fstat, though, returns information about the special-file node, not the blockdev it refers to. you probably want to use the BLKGETSIZE64 ioctl to read the size.
there's no particular reason to use a partition over a raw device, though - a blockdev is a blockdev. O_DIRECT is good, as well, assuming your workload won't generate repeated accesses. don't confuse it with a real protocol for ensuring the permanence and atomicity of your filesystem, though (fsync, barriers, etc).

Reading a sector on the boot disk

This is a continuation of my question about reading the superblock.
Let's say I want to target the HFS+ file system in Mac OS X. How could I read sector 2 of the boot disk? As far as I know Unix only provides system calls to read from files, which are never stored at that location.
Does this require either 1) the program to run kernel mode, or 2) the program to be written in Assembly? I would prefer to avoid either of these restrictions, particularly the latter.
I've done this myself on the Mac, see my disk editor tool: http://apps.tempel.org/iBored
You'd open the drive using the /dev/diskN or /dev/rdiskN (N is a disk index number starting from 0). Then you can use lseek (make sure to use the 64 bit range version!) and read/write calls on the opened file.
Also, use the shell command "ls /dev/disk*" to see which drives exist currently. And note that the drives also exist with a "sM" extension where M is the partition number. That way, could can also read partitions directly.
Or, you could just use the shell tool "xxd" or "dd" to read data and then use their output. Might be easier.
You'll not be able to read your root disk and other internal disks unless you run as root, though. You may be able to access other drives as long as they were mounted by the user, or have their permissions disabled. But you may also need to unmount the drive's volumes first. Look for the unmount command in the shell command "diskutil".
Hope this helps.
Update 2017: On OS X 10.11 and later SIP may also prevent you from directly accessing the disk sectors.
In Linux, you can read from the special device file /dev/sda, assuming the hard drive you want to read is the first one. You need to be root to read this file. To read sector 2, you just seek to offset 2*SECTOR_SIZE and read in SECTOR_SIZE bytes.
I don't know if this device file is available on OS X. Check for interestingly named files under /dev such as /dev/sda or /dev/hda.
I was also going to suggest hitting the /dev/ device file for the volume, but you might want to contact Amit Singh who has written an hfsdebug utility and has probably done just what you want to do.
How does this work in terms of permissions? Wouldn't reading from /dev/... be insecure since if you read far enough you would be able to read files for which you do not have read access?

Resources