Writing Stackable Filesystems
In the wrapfs_unlink example, we suggested that instead of deleting a file, you could rename it, thus saving a single backup of deleted files. Suppose we call this filesystem unrmfs, in which deleted files are instead renamed from their original name F to F.unrm. It might be annoying if all of these .unrm files started appearing in your directory, especially if you're expecting nothing there. Moreover, this kind of functionality also could be used to fool attackers who try to delete log files that may be used to track their actions. To achieve this, however, the .unrm files must not be visible or accessible to users by default.
To hide certain files in a filesystem, you have to do two things. First, prevent the file from showing up in ->readdir(). This is done by writing code in wrapfs_filldir that checks each filename passed to ->filldir() and returning NULL for those files you do not want listed. Second, prevent users from directly looking up the file by its name; this is done by checking for .unrm files in the beginning of wrapfs_lookup.
Of course, hiding those files from all users isn't very useful. Legitimate users must be able to access those files under certain conditions. A simple approach might be to check the UID of the calling process and to hide the .unrm files only from certain users. A better approach would be to use the mother of all system calls, ioctl. In Wrapfs, you can define as many new ioctls as you like, and then write small user-level programs to use those ioctls. This is, for example, the mechanism we use in encryption filesystems for a user-level tool to pass a user's cipher key to the kernel.
For our unrmfs, you could write a restore ioctl that takes a file's name, F, checks whether the file F.unrm exists and then renames F.unrm back to F, effectively unhiding it from unrmfs. The following example shows a sketch of this code:
/* len: length of source file */ newname = kmalloc(len+6, GFP_KERNEL); strncpy_from_user(newname, ioctl_arg, len); strcat(newname, ".unrm"); lower_dir = get_lower_inode(dir); src = lookup_one_len(lower_dir, newname); if (IS_ERR(src)) return PTR_ERR(src); dst = lookup_one_len(lower_dir, name); vfs_rename(lower_dir, src, lower_dir, dst);
Filesystem development need not be difficult. Using stackable filesystems, you can create new, useful and efficient filesystems quickly—all without changing kernels or existing filesystems. The examples in this article hopefully demonstrate the power of stacking, from which you gradually can build more complex filesystems. You can get the FiST software, documentation and many more examples from www.cs.sunysb.edu/~ezk/research/fist. Happy stacking.
Erez Zadok (firstname.lastname@example.org) is on the Computer Science faculty at Stony Brook University, the author of Linux NFS and Automounter Administration (Sybex, 2001), the creator and maintainer of the FiST stackable templates system and the primary maintainer of the Am-utils (aka, Amd) automounter. Erez conducts operating systems research with a focus on filesystems, security and networking.
Free Webinar: Hadoop
How to Build an Optimal Hadoop Cluster to Store and Maintain Unlimited Amounts of Data Using Microservers
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Some of key questions to be discussed are:
- What is the “typical” Hadoop cluster and what should be installed on the different machine types?
- Why should you consider the typical workload patterns when making your hardware decisions?
- Are all microservers created equal for Hadoop deployments?
- How do I plan for expansion if I require more compute, memory, storage or networking?
|Designing Electronics with Linux||May 22, 2013|
|Dynamic DNS—an Object Lesson in Problem Solving||May 21, 2013|
|Using Salt Stack and Vagrant for Drupal Development||May 20, 2013|
|Making Linux and Android Get Along (It's Not as Hard as It Sounds)||May 16, 2013|
|Drupal Is a Framework: Why Everyone Needs to Understand This||May 15, 2013|
|Home, My Backup Data Center||May 13, 2013|
- Designing Electronics with Linux
- Making Linux and Android Get Along (It's Not as Hard as It Sounds)
- Dynamic DNS—an Object Lesson in Problem Solving
- New Products
- Using Salt Stack and Vagrant for Drupal Development
- Validate an E-Mail Address with PHP, the Right Way
- Build a Skype Server for Your Home Phone System
- Why Python?
- A Topic for Discussion - Open Source Feature-Richness?
- Tech Tip: Really Simple HTTP Server with Python
- Not free anymore
28 min 49 sec ago
4 hours 16 min ago
- Reply to comment | Linux Journal
4 hours 24 min ago
- Understanding the Linux Kernel
6 hours 38 min ago
9 hours 8 min ago
- Kernel Problem
19 hours 11 min ago
- BASH script to log IPs on public web server
23 hours 38 min ago
1 day 3 hours ago
- Reply to comment | Linux Journal
1 day 3 hours ago
- All the articles you talked
1 day 6 hours ago