A Glendix project

I decided to use HTTP Get request as a good test of the /net filesystem’s first deliverable (once I complete it). I plan to get connect, sendmsg and recvmsg working in order to have this work in Linux. The script just reads and writes to files, and achieves fetching a page over HTTP on Plan 9’s shell. Even so, simple cat and echo commands sent to the netfs in shell do not work, because when we echo connect <ip>!<port> to the ctl file, and exit to terminal again for next command, the file and the connection get closed. Here’s the script, that works on Plan 9:

To use this script, run it with the server ip as an argument. While using the url will work on Plan 9, I have not implemented DNS for /net on Linux yet, so even after I complete the first deliverable, only IPs will work. After you run the command, enter the request as :
GET / HTTP/1.0
Host: <hostname>

You will see the requested page fetched and displayed on your shell. It will be best to use rc from plan9ports though.

I recently discussed with a diagram, exactly where I plan to hook onto the existing structure in Linux. My plan is to bypass the Socket ioctl and the Socket structure, and plug in directly to the sk structure, which is a common interface to the various transport layer protocols. I plan to write my own connection create and sendpkt functions, which work with the sk structure. Initially I had planned to plug these functions into the .connect , .sendmsg etc. of proto_ops structure, but it seems unnecessary to do that. I now think I’ll call those functions directly in my FS code, when relevant commands are written to the ctl and data files.

I was recommended to look at ksocket by a friend. While the package is looking to provide BSD-style network programming in kernel I cannot hook onto the functions they are hooking on to. ksocket is simply a wrapper on top of the socket structure, and does not help me gain insight on what’s underneath. My plan currently is to work at a much lower layer than they are doing, even though we are both in kernel-space. I just find it useless overhead to maintain a socket structure, for what I am working to achieve. Doing it my way might be much harder though!

Current issue that needs solving: If I dont have sock->sk element, because I dont use a socket to represent a connection, but use a folder /net/tcp/n , then how to I associate the sk structure with it? struct file has no sk element like struct socket does…

With this revision I have figured out a way to use tcp.c, cs.c, ether.c etc. to do the file-specific processing, while passing only the file structure *filp from a common “write_file” function in net.c. The filesystem however now occupies some memory – TMPSIZE * no_of_files to be precise. I would say this is desirable. I dont know with respect to code, but Plan 9 also seems to behave in the same fashion as far as usability is concerned.

Next, what needs to be done is implement the functions of /net/tcp/clone and the /net/tcp/n/ctl files. Doing these will be enough to test out a simple connection from command-line. Predicted forthcoming issue –> Plan 9 uses “connect 192.168.1.8!80” as the command. ! is a symbol not allowed in bash. I dont know if it will work if I used other shells (or use rc from plan9ports?).

I think I have found my footing. Here is a design diagram. I am considering creating a fsnet which is more or less equivalent to inet – and perhaps even borrows / wraps some code – except that it provides functions to the libfs based netfs implementation program.

Glendix for routers? I was poking around for what it would take to get there. I found this. I am basically looking to have a way to do routing using Glendix. You can already do that on any standard Linux using Quagga (see http://www.quagga.net/docs/quagga.html#SEC3 ). They use a traditional dynamic library approach with architecture specific code.

I plan to expose the UNIX Kernel Routing Table as a filesystem instead. Then do the routing protocols, and other actions like updating the table from information from other routers, and load-balancing etc from userspace scripts. The advantage is that, we will not need any daemons working directly on top of the kernel. Our simple userspace scripts that do the routing can hack on the, say /net/ether0/route file.

One of the factors that will excite people will obviously be a awesome infrastructure to test new routing protocols in real networks, without writing complex architecture-specific daemons for GNU Zebra. Plus, I wonder what network mounts of such directories might lead us to achieve?!

UPDATE (May 03, 2009): Further discussion of this idea led to me applying to GSoC 2009 with this proposal. Although the idea was not selected, I got some valuable feedback and the project is still on (probably with a more relaxed timeline, and aligned towards Glendix rather than Plan 9 from Bell Labs).

Apparently, Linux kernel does not seem to have a DNS resolver! The fundtion gethostbyname() first checks /etc/hosts and if no entries are found, it makes a direct socket connection with the ip address given in resolv.conf and fetches the DNS resolved ip address!

I would do a in-kernel DNS implementation from scratch, but apparently, there are many issues with it. Its not so easy as it originally seemed! Read this response by a certain Josh Graessley in the MAC OS X community who understands Darwin probably. So did the Linux Kernel Hackers actually chose not to have DNS in-kernel for some real-world reasons?

More information we need, but a change of track in the project is apparent. We have decided to move on to the /net/tcp implementation and work with IPs for now.

My first commit into Glendix (and incidentally and surprisingly, the first non-Anant Narayanan commit to the project!).

The design for the inode and file creation is much the same as lwnfs. I added the mechanism for read and write of files created in the /net. One of the issues I ran into was using the i_private field of the inode to point to the buffer created to store the input content in slashnet_write_file(). See comment at the bottom of this function to know more about this issue.

UPDATE:- Some memory leaks. I forgot to use kfree() after kmalloc(). Gamers will call that n00b error?! lol!

Before I start with /net, I wanted to try implementing a sample FS. I thank lwn.net for providing that piece of documentation. I implemented the lwnfs.c in my home folder like they mentioned. NOTE:- A patch is needed on newer kernel versions.

2) Ctrl+C exit signal for running scripts —-> “Delete” key on the keyboard.
Comments: Another example of how old UNIX is. They probably had no “Delete” key when UNIX was designed, so they used “Ctrl+C” which, logically speaking, makes absolutely no sense!

About

This blog is a project log for the /net virtual filesystem being developed by Rahul Murmuria under the Glendix umbrella. The project will provide Linux users with a more flexsible, powerful and simple alternative to TCP/IP Sockets.

The Glendix project is about bringing the beauty of Plan 9 from Bell Labs to the world of Linux. Some of the work already done by the Glendix project include native Plan9 binary compatibility in Linux and a few new Plan9-like system calls that are missing in Linux. Read more on Glendix on the project website ( http://www.glendix.org ).

When UNIX was originally designed, there were no computer networks. Yes, BSD Sockets were designed first on a UNIX, but that does not imply that UNIX is the best possible design for a networking enabled operating system. Today, all operating systems – including Mac OS X, GNU/Linux, Solaris and Windows – are direct derivatives of the original UNIX first designed over 40 years ago!

So folks at Bell Labs (read Rob Pike, Ken Thompson, Dave Presotto, Phil Winterbottom, Dennis Ritchie, Brian Kernighan, et. al.) designed a new network structure, that exposes the kernel TCP/IP stack in form of filesystems to the user space, instead of the traditional Socket library approach. Plan 9 has been designed from gound up, with networking in mind, and is inherently a distributed operating system. Here’s an extract from Wikipedia:

Plan 9 does not have system calls for the multitude of communication protocols or device driver interfaces. For example /net is the API for all TCP/IP, and it can be used even with scripts or shell tools, writing data to control files to write and read connections. Relevant sub-directories like /net/tcp and /net/udp are used to interface to respective protocols. You can implement a NAT by mounting a /net from a perimeter machine with a public IP, while connecting to it from an internal network of private IP addresses, using the Plan 9 protocol 9P in the internal network. Or you can implement a VPN by mounting a /net directory from a remote gateway, using secured 9P over the public Internet.