On UNIX File Permissions

It is pretty shameful to say that i still get UNIX permissions wrong sometimes. I hope to make this final forever by writing about them here 🙂

Every file and directory has three set of permissions associated with it: owner’s permissions, group members’ permissions and others’ permissions. User identity is checked against these sets in this order and the first matching set is chosen, which has a side-effect that i always tend to ignore:

* File owner may have less permissions than group members

* Group members may have less permissions that others (i.e, rest of the world)

For example, a file can have rwx permissions for others, but no permissions for owner and group members. (Of course owner can change the file permissions to get what he wants, but thats irrelevant.)

Second point i always miss is, the semantics of directory permissions.

* Read permission on a directory means you can read the contents of the directory, which means you can read file names inside the directory (but not their attributes — you need execute permission for this.)

* Write permission on a directory means you can modify the contents of the directory, which means you can add new files, remove files, rename files, etc. (you don’t need to be owner of any of these files.)

* Execute permission on a directory means you can traverse the directory down to further sub directories (but you cannot list the files — you need read permission for this)

What is interesting here is, write permission to a directory is sufficient to add or remove any file in it, which also means — you don’t need to be the owner of that file to delete it. This point is necessary to understand the need for sticky-bit and is also a cause for old mkdirs’ time-of-check and time-of-use (TOCTOU) bug.

I will write a notes on set-user-id, set-group-id and sticky-bits some other time.

Bottom Halfs

Bottom-halfs are non-critical portion of interrupt-handlers, i.e. interrupt-handler code that is executed with interrupts enabled. Bottom-halfs can be masked by processes when they access any data shared with bottom-halfs using local_bh_disable, spin_lock_bh, etc. functions.

Though bottom-halfs are a deferred work, in priority they are considered as equal to interrupts. So kernel processes them as quickly as possible. Kernel guarantees to execute all unmasked bottom-halfs on meeting below two conditions:

1. Following the execution of any top-half, after interrupts are enabled.
2. Following any process’s context switch, on a call to schedule(), before another process is scheduled.

Two types of bottom-halfs are supported with different different concurrency semantics.

Softirqs

Bottom-halfs which can be executed on multiple cpus simultaneously, are called softirqs. Softirqs are completely reentrant, which means, softirq code for an interrupt X can be executed on multiple cpus simultaneously.

This concurrency requirement suggest that the device serviced is of very high priority and/or can generate interrupts at a every high rate. Very few devices need this level of interrupt service, so Linux supports only a fixed number of softirqs and which devices belong to this class is decided at compile time.

Tasklets

Tasklets are sufficient to service almost all devices. Tasklets are a type of bottom-halfs which are guaranteed to be executed in serial. When tasklet code for interrupt X is executing on cpu ONE, it will be delayed from execution on other cpus. In fact, as a cache optimization, it is queued to execute on cpu ONE after completion.

There is no limitation on number of tasklets. Device drivers can add or remove tasklets dynamically.

Implementation Notes

Since all interrupt-handlers need not have work as a bottom-half, Linux provides a fixed number of bottom-halfs. After completing any top-half it iterates over all bottom-half slots looking for active (or activated) bottom-halfs and executes them.

One of the bottom-half slot has a reentrant framework which in turn iterates over all registered softirqs and executes the pending softirqs (of course, only when it is not executing on other cpus at that time). This is how tasklets are built on top of softirqs and provide serialization.

Ticket Spin Locks

Nice explanation on how spin locks are implemented in Linux currently and a new design checked-in to make them fair (as in first-come-first-serve).

http://lwn.net/SubscriberLink/267968/60e6ec9a59ec9677/

GNUPLOT Tips

How to get the plot output in a .png file using gnuplot?

    gnuplot> set terminal png
    gnuplot> set output "outfile.png"

How to produce specific sized .png file with gnuplot?

    gnuplot> set terminal png size 1024,768
    gnuplot> set output "outfile.png"

Rajanikanth is Nothing Less ;-)

Rajanikanth makes onions cryRajanikanth

Rajanikanth can delete the Recycle Bin.

Ghosts are actually caused by Rajanikanth killing people faster than Death can process them.

Rajanikanth can build a snowman….. out of rain.

Rajanikanth can strangle you with a cordless phone.

Rajanikanth can drown a fish.

When Rajanikanth enters a room, he doesn’t turn the lights on,……… …. he turns the dark off.

When Rajanikanth looks in a mirror the mirror shatters, because not even glass is stupid enough to get in between Rajanikanth and Rajanikanth.

Brett Favre can throw a football over 50 yards. Rajanikanth can throw Brett Favre even further.

The last digit of pi is Rajanikanth. He is the end of all things.

Rajanikanth does not know where you live, but he knows where you will die.

Bullets dodge Rajanikanth.

A Handicap parking sign does not signify that this spot is for handicapped people. It is actually in fact a warning, that the spot belongs to Rajanikanth and that you will be handicapped if you park there.

Rajanikanth’ calendar goes straight from March 31st to April 2nd, no one fools Rajanikanth.

If you spell Rajanikanth wrong on Google it doesn’t say, “Did you mean Rajanikanth?” It simply replies, “Run while you still have the chance.”

Rajanikanth can do a wheelie on a unicycle.

Once a cobra bit Rajanikanth’ leg. After five days of excruciating pain, the cobra died.

When Rajanikanth gives you the finger, he’s telling you how many seconds you have left to live.

Rajanikanth can kill two stones with one bird.

Rajanikanth was once on Celebrity Wheel of Fortune and was the first to spin. The next 29 minutes of the show consisted of everyone standing around awkwardly, waiting for the wheel to stop.

Leading hand sanitizers claim they can kill 99.9 percent of germs. Rajanikanth can kill 100 percent of whatever he wants.

There is no such thing as global warming. Rajanikanth was cold, so he turned the sun up.

Rajanikanth can set ants on fire with a magnifying glass. At night.

Rajanikanth has a deep and abiding respect for human life… unless it gets in his way.

It takes Rajanikanth 20 minutes to watch 60 Minutes.

Rajanikanth once shot down a German fighter plane with his finger, by yelling, “Bang!”

In an average living room there are 1,242 objects Rajanikanth could use to kill you, including the room itself.

Behind every successful man, there is a woman. Behind every dead man, there is Rajanikanth.

Rajanikanth destroyed the periodic table, because Rajanikanth only recognizes the element of surprise.

Rajanikanth got his drivers license at the age of 16 Seconds.

With the rising cost of gasoline, Rajanikanth is beginning to worry about his drinking habit.

The square root of Rajanikanth is pain. Do not try to square Rajanikanth, the result is death.

When you say “no one’s perfect”, Rajanikanth takes this as a personal insult.

Enable Root login through Telnet

Almost all Linux distributions now a days come with “root” login disabled through telnet. Some distributions doesn’t have telnet login service at all. This is generally a Good Thing, because telnet login needs passwords to be sent over the network in plain-text format. This has lots of security implications, like anybody snooping your network can read your password.

But still, sometimes you may need to enable root login through telnet. Below are steps to enable this for RHEL5 (GA).

1. Make sure you have xinetd and telnet-server packages installed on your box. You can verify this using below commands

    $ rpm -qa | grep xinetd
    $ rpm -qa | grep telnet-server

2. If you don’t have above packages installed (which is the case by default) download or copy those packages and install them using,

    # rpm -i xinetd*.rpm telnet-server*.rpm

command.

3. Now enable the xinetd service. To do this you need to run two commands

    # service xinetd start
    # chkconfig xinetd on

4. Now you can enable telnet service either using “serviceconf” GUI utility or by manually editing /etc/xinetd.d/telnet files.

5. By now telnet login service will be up and running on your box. But it is by default disabled for root user. You can enable it by appending pts/0, pts/1,…, pts/9, etc. entries into /etc/securetty file. Once you do this, you will be able to open 10 root sessions through telnet.

Have Fun.

Using GRUB and QEMU with TFTP

GRUB boot-loader and QEMU virtual machine are two invaluable tools for any OS developer. GRUB greatly simplifies your OS boot-up mechanism. All you need to do is, make your OS kernel binary multi-boot complaint. This can be done very very easily, within one hour of work. And QEMU gives an easy and fast, PC compatible virtual machine to experiment your OS with. No rebooting your machine every time your kernel crashes 🙂

In this post, i will tell you how to setup an efficient testing environment with QEMU and GRUB for your OS development. We make use of QEMU’s user-mode networking and TFTP features with GRUB’s network boot magic.

For booting QEMU virtual machine, we need a boot-disk. A GRUB boot-disk can be created very easily using the below command:

    cat /usr/lib/grub/i386-pc/stage{1,2} > bootdisk.img

You can test this image using QEMU by simply running the below command. Once the virtual machine starts, you will be stopped at GRUB command-line prompt and you can enter GRUB commands.

    $ qemu bootdisk.img

Now you can check whether your GRUB has network boot support or not using dhcp or bootp GRUB commands. If GRUB cribs with invalid command message, it means your GNU/Linux distribution has GRUB installed with network boot support disabled. In this case, you can download and compile GRUB manually with network boot options enabled as shown below:

    $ wget ftp://alpha.gnu.org/gnu/grub/grub-0.97.tar.gz
    $ tar xzf grub-0.97.tar.gz
    $ cd grub-0.97
    $ ./configure --enable-ne
    $ make

If you are not able to build GRUB using above commands then, you might be using a newer version of GCC compiler. Try compiling with gcc-3.4 compiler. Once you built GRUB with network support, you need to rebuild the bootdisk.img using stage{1,2} files from the current build directory as shown below:

    $ cat stage1/stage1 stage2/stage2 > bootdisk.img

This bootdisk.img should have GRUB with network boot support enabled for NE2000 ISA network card. You can start QEMU virtual machine with this network card and built-in TFTP server using below command:

    $ qemu bootdisk.img -net nic,model=ne2k_isa -net user -tftp TFTP-ROOT-DIR

The “-net user” option tells the QEMU to enable internal DHCP server, so that GRUB can get a valid IP address to talk TFTP protocol. The TFTP-ROOT-DIR can be any directory within your host system, where you should place your OS kernel binaries and modules. Now you can issue commands at GRUB prompt which will fetch your OS binaries using TFTP protocol, as shown below:

    grub> dhcp
    grub> kernel (nd)/path/to/kernel-image
    grub> boot

Above commands will assign a DHCP IP address to virtual machine network card and fetches kernel-image from the host, where path is relative to TFTP-ROOT-DIR directory. Final boot command will pass control to your multiboot complaint OS kernel and your OS starts inside the QEMU virtual machine.

Everything is fine, except that you have to enter GRUB commands manually every time you start your virtual machine, right? Thankfully, there is a way to preset a GRUB commands into the GRUB bootdisk itself using “–enable-preset-menu” configure time option. I leave it for you to explore!

Now what is the advantage of doing all this?

The advantage is, you don’t need to rebuild any boot disk images every time you rebuild your OS kernel. Once you setup your build environment and preset GRUB configuration menu, just run QEMU with proper arguments and GRUB boot disk. Your virtual machine automatically starts with your latest kernel bits!

Yes, build your kernel, run QEMU to try it. Nothing more to do! Have Fun!

Build, Host and Target Concepts

i don’t know why i keep forgetting these concepts

The build, host and target concepts are defined for gcc as follows:

  • build: the platform on which gcc is built.
  • host: the platform on which gcc is run.
  • target: the platform for which gcc generates code.

BTW, these concepts need not apply for all programs. For example, target concept applies only to compilers and binutils.

Lucidatypewriter/Bitmap Fonts in Ubuntu

By default Ubuntu comes with bitmap fonts disabled in the system. Since lucidatypewriter is a bitmap font, it doesn’t show up in the font chooser windows. You need to enable bitmap fonts to use it.

To enable bitmap fonts, follow the below procedure.

1. Run the below command in the terminal, and choose “YES” when it asks for “enable bitmap fonts?” question. Choose the defaults for other queries.

        $ sudo dpkg-reconfigure fontconfig-confg

2. Once you do the above step, you should regenerate the font cache using below command.

        $ sudo dpkg-reconfigure fontconfig

3. Now you should logout and re-login. Now bitmap fonts start appearing on the font chooser dialog boxes.

Installing New TTF Fonts (non-root)

Here is a small notes on how to install ttf fonts as a non-root user. Below instructions are for installing liberation fonts from RedHat.You can follow the same for installing other fonts too.

1. Download the fonts first.

        cd $HOME
        wget https://www.redhat.com/f/fonts/liberation-fonts-ttf-3.tar.gz
        tar xzvf liberation-fonts-ttf-3.tar.gz

2. Create .fonts directory and copy the fonts

        mkdir .fonts
        cd .fonts

        mv ~/liberation-fonts-0.2 .
        cd liberation-fonts-0.2

3. Run these commands inside the fonts directory

        ttmkfdir > fonts.dir
        ttmkfdir > fonts.scale
        mkfontdir

4. Update the fonts cache

        xset fp+ $HOME/.fonts/liberation-fonts-0.2
        xset fp rehash

Enjoy the fonts.