-
Mount the PRFS disk at boot
09/26/2023 at 20:24 • 0 commentsIt was some experimenting, but I managed to get the PRFS working at boot. Also the Samba server and ProFTPD are started at boot. So now after putting on the power, one can use it directly.
During experimenting the RPi stopped booting after I modified /etc/modules and /etc/fstab. The easiest way to get the RPi working again was to take the SD card and connect it to (through an USB card reader) to my laptop. After starting Linux in Virtual Box and have the USB bridged to Linux, I could access /etc/modules and /etc/fstab again and commented out the changes.
There were two unexpected things that were different than one would expect. Firstly the modules should be copied in /lib/modules/6.1.21+ and not in one of the subdirectories. Also one should use kmod and not depmod, by creating a symbolic link.
I have updated the building instructions.
-
The project is working
09/03/2023 at 08:10 • 0 commentsThe project is working. The file system works in the three modes which can be controlled with the switch.
The sources can be found on GitHub:
https://github.com/elbojvv/fat32prfs
https://github.com/elbojvv/prfsswitch
Proftpd and samba are working. Only Windows get really confused when switching the modes while working on the files through samba. But this was also not the intended use. Also, if you delete a backup file through samba, it seems to be deleted, but after a refresh the file is back.
-
First version of PRFS file system is working
08/26/2023 at 07:18 • 0 commentsAfter further experimenting I have a first version working. When a file is written, a makes a copy of the existing file with the name of this file, trailed with 14 characters, of which the first an dthe last are underscores, and in between only numbers (actually the time seconds since the epoch). So the file “test.txt” gets a backup “_001693031634_test.txt”.
More specific’, there is a hook in the file_operations.open kernel function:
- When a file is read, everything goes as normal.
- When a file is
written:
- It checks whether the filename has a backup file format (_NNNNNNNNNNNN_).
- If it is a backup file: If the file does not exist (or is empty) it can be written (*), otherwise it cannot be written
- If it is not a backup file, it makes a copy of the file as backup file. If the backup is successful, the file can be modified. Otherwise it cannot be modified.
(*) This step seems maybe unnecessary. However, the file_operations.open function is called both form user space as from kernel space. And the kernel module cannot distinguish between them. And we want to be able to write to the backup file from the kernel module, but not from ransomware from the servers in the user space. But this is not possible. So the solution here is that it treats the backup file as WORM: you can write them once, but not change them afterwards.
I also write “(or is empty)”. This is due to the Linux kernel. The kernel knows already form the directory listing whether a file exist or not. If a file does not exist, it first calls the vfat_create function, before the file_operations.open function. So the file does exits already, but is empty (and has different flags). So this does determine whether it ‘exists’ or not.
The PRFS works fine when editing text within the RPi linux environment. And also the FTP server (proftpd) works reliable. Samba does not work properly yet.
Still to do:
- Fix samba
- Connect the switch for the cleaning the disc
- Make a backup copy at delete and rename
-
Getting experience with kernel module writing
08/21/2023 at 21:42 • 0 commentsYou would think that the functions fopen, fprintf and fclose have counterpart functions in the kernel module. Looking for those functions showed that this is not the case. The kernel is already doing that and the kernel module is at a lower level. I could not find good documentation, so I did put debugging messages at the different functions, so I could see which functions I could put my code in.
Also a surprise for me: in kernel modules you have to use different – and limited set of – functions. With printk one could see the output with dmesg.
I looked that no functions were actually called. But the kernel module was reading and writing just fine. It turned out you should be very careful with the EXPORT_SYMBOL macro. I did not change all the function names properly, in all the files. And that is why my kernel module just jumped to the FAT kernel functions half way. You do not get any compiler warnings or run time errors, since this will work fine. Maybe next time I should use an IDE, instead of gedit, but maybe that will be even slower on a Rpi zero… After correcting this, I can see which functions are called. When you write from a pipe: fat_write_begin is called. When you e.g. edit a file: fat_write_pages.
-
I got my own port of the FAT file system working
08/14/2023 at 21:22 • 0 commentsI came a long way with modifying tarfs. I managed to fool the system to read a file form another drive while the system was thinking I was reading the tar file. This would have been a good basis for the PRFS. However, I kept reading that it is not a good idea to read files from another file system in a kernel module, Also, it was rather difficult to get e.g. a list of the files and their properties.
So once again, a change of plans…
I will use the FAT32 file system and will modify it to my own file system: FATPRFS. I copied the source of the FAT system from Raspberry Pi OS. Since it was part of a larger build, I had to modify the Makefile and give the file system a new name: fatprfs. The module also exports some variables to the kernel. Since it is the same names as the official FAT source, I had to change these names too.
My micro-USB OTG adapter has not arrived yet (to mount an USB memory stick) so with Gparted (offline on another PC with Linux on Virtual Box) I made a FAT32 partition on the SD card by resizing (reducing) the ext4 partition and adding the FAT32 partition. Now I can test mounting FAT32 partitions
After some trial-and-error experimenting I got it working. I have now an fatprfs file partition! OK, it is still a normal FAT32 partition, but now I can start implementing the prfs-part in the kernel module.
-
I have made an example file system working
08/10/2023 at 21:34 • 0 commentsAfter trying to port vsftpd, I realized I was on the wrong way. It would be a messy work. And Samba would even be much larger. So another change of plan. Why not making a new file system? Then all servers could just write to the PRFS file system (Protected Revertible File System) without having to modify the server software!
The ‘easiest’ way is to make a kernel module. This can be loaded on the fly.
After reading and compiling some tutorials and compiling https://blog.sourcerer.io/writing-a-simple-linux-kernel-module-d9dc3762c234, I was ready for the real work.
I have taken a file system which (transparently) reads a TAR file, as was it a file system: https://github.com/Papierkorb/tarfs
Raspbian OS seems to bit a little ‘off’. So I had to change a few things (with a lot of Googling and a little logical thinking):
- The way to install the header files is: sudo apt-get install raspberrypi-kernel-headers
- In tar.h and tar.c
- timespec -> timespec64
- kstrtoul -> kstrtoll
- In driver.c
- MS_RDONLY | MS_NOATIME -> SB_RDONLY | SB_NOATIME
- Adding struct timespec64 CURRENT_TIME; and ktime_get_real_ts64(&CURRENT_TIME);
- First parameter added: inode_init_owner(sb->s_user_ns, root, NULL, ROOT_INO_MODE);
- Last parameter added: static struct posix_acl *tarfs_get_acl(struct inode *inode, int flags, bool rcu)
- .readlink = generic_readlink -> .readlink = vfs_readlink
I have mounted the kernel module and it works!
Next step is to make it read from a normal (mounted) file system.
-
Getting the Rpi to work
08/07/2023 at 12:23 • 0 commentsI received the Rpi Zero W. I was surprised it does not have an USB host. It seems to be possible, but that is of later concern. I can use the SD storage for the moment.
I burned the SD card with the Raspberry Pi Imager (32 bit with desktop). I used the advanced options in the Imager to get SSH and WiFi set up, without having to (set up and) use the monitor (mini HDMI) and keyboard. I named it “raspberrypizw”. I had to wait 5 minutes the first time before it showed up in the LAN scan.
I enabled the VNC interface (sudo raspi-config) via SSH terminal (Teraterm, for old times sake) and changed the resoution too. I also installed and RealVNC on the PC. I could use “raspberypizw” to log into VNC. I am ready to program!
-
FTP server from Github
07/31/2023 at 20:31 • 0 commentsI want to modify a simple FTP server. Github has many FTP servers. I think I will start with https://github.com/sunaku/simple-ftp