Friday, August 23, 2013

Gerrit

To those of you who are new to Gerrit, Gerrit[1] is a free, web-based team code review tool which can be used by members of a team to review each other's modifications in their source code using a web browser and approve or reject those changes. It integrates closely with Git.

Prerequisite
  • Java is needed to install and run Gerrit. If you don't have Java installed, then download and install the latest JDK on your machine.
  • Create a user named gerrit2 to host gerrit services.
    $ sudo adduser gerrit2
Installation
  • To install gerrit, first change to gerrit user
    $ sudo su - gerrit
  • Iinitialize with the batch switch enabled, so that we don't have to answer any questions.
    $ java -jar gerrit.war init --batch -d <site-path>
    site-path: lets assume that it is ~/gerrit_testsite
         This is automatically start gerrit on localhost running on port 8080.


Configuration
  • You may wish to change the port on which gerrit runs on. To do this, edit the gerrit_testsite/etc/gerrit.config and replace the port number 8080 with the port of your choice. In this document we will stick with the port number 8080.
  • Now restart the gerrit process.
    $ ~/gerrit_testsite/bin/gerrit.sh restart

Registering User
  • Open the browser and enter the url www.localhost:8080 and it will prompt you to register/sign in. You can use open-id to sign in. In Gerrit, the first user to register becomes the default administrator.

  • On the registering site, add the public key of the machine from which you 'll send patches to.
  • Now you are all set. Try loging in using ssh, gerrit uses port 29418 for ssh access.
    $ ssh -p 29418 john@localhost
The authenticity of host '[localhost]:29418 ([127.0.0.1]:29418)' can't be established.
RSA key fingerprint is 35:72:c5:2d:0c:16:8a:68:04:ab:2f:51:f1:d0:0c:6b.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[localhost]:29418' (RSA) to the list of known hosts.
***    Welcome to Gerrit Code Review    ****
Hi john, you have successfully connected over SSH.
Unfortunately, interactive shells are disabled.
To clone a hosted Git repository, use:
git clone ssh://john@localhost:29418/REPOSITORY_NAME.git
Connection to localhost closed.

Creating a Project
Gerrit gives the flexibility to either create a new project from scratch or upload an existing project to gerrit.
  • To create a new project from scratch, create a new repository on the gerrit machine by passing the option empty-project.
    $ ssh -p 29418 john@localhost gerrit create-project --empty-project -name test-proj
    In our case, we created an empty project named test-proj.
  • Alternatively, you can tell gerrit that you will be uploading an existing project. To do this, first create a project on the gerrit machine.
    $ ssh -p 29418 john@localhost gerrit create-project name test-proj
    This command will create a git repository on the gerrit machine. Behind the scenes, the above command runs 
    $ mkdir test-proj.git
    $ cd test-proj.git
    $ git init --bare --shared
    Once the project is created, add a remote repository reference to your local repository.
    $ git remote add origin ssh://john@localhost:29418/test-proj.git
    Now push your changes to the upstream repository
    $ git push origin
    Counting objects: 5, done.
    Writing objects: 100% (3/3), 248 bytes, done.
    Total 3 (delta 0), reused 0 (delta 0)
    To ssh://john@localhost:29418/test-proj.git
    ! [remote rejected] master -> master (prohibited by Gerrit)
    error: failed to push some refs to 'ssh://john@localhost:29418/test-proj.git'
The above error is because the user is trying to push the changes to the upstream repository directly, bypassing the gerrit's review process.
  • Gerrit maintains a seperate change branch to which the new changes would be committed and made available for review to other users.
    $ git push origin HEAD:refs/for/master
Hear master is the branch name to which the changes have to be applied to. Replace it with the branch name to which you want to apply your changes to.

Clone Project
  • Users who wish to clone the project must first register to the project and then clone using ssh.
    $ git clone ssh://smith@localhost:29418/test-proj.git
Permissions
    • Owner
    • Push Merge Commit
    • Label Code-Review
    • Label Verified
    • Submit
There are various types of groups like Administrator, Registered users, Anonymous, etc. Apart from this, you can explicitly a new group and add members to this newly created group and grant permissions to them.
  • Now that the permssions are all set, users can clone the repo, make changes locally and push the changes to review.
    $ git clone ssh://steve@localhost:29418/test-proj.git
    $ cd test-proj
      ---- make changes and add the changed files to git ----
    $ git commit
    $ git push origin HEAD:refs/for/<branch-name>

Setting up QEMU with a NAT

This is a continuation of my previous post which deals with setting up network connection for Qemu between host and guest. In this post we will learn to configure Qemu to access outside world.

There are a number of ways to configure Qemu to access internet like bridging, proxy arp, etc. In this post I will use tap device that we configured in the previous post and then make some changes to host iptables to forward the packets over the internet.

Nat
$ echo 1 > /proc/sys/net/ipv4/ip_forward
# iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
# iptables -I FORWARD 1 -i tap0 -j ACCEPT
# iptables -I FORWARD 1 -o tap0 -m state --state RELATED,ESTABLISHED -j ACCEPT
Thats it. Verify now by pinging any of the outside connection in the guest. The simplest is,
$ ping google.com
Links
* http://tech-jnaan.blogspot.in/2013/08/configuring-qemu-tap-interface-for.html
* http://felipec.wordpress.com/2009/12/27/setting-up-qemu-with-a-nat/

Tuesday, August 20, 2013

Configuring Qemu tap interface for guest<-->host communication

I recently started playing with Qemu. One of the first things that I wanted to setup was a communication link between the host(physical machine) and guest(the vm). Qemu provides a number of techniques to achieve this. In this post I will explain about setting up network with tun/tap device.

It is easy to set it up when you know what it is. I spent couple of hours while I was fiddling with it. Read a lot of documents but dint find one which explained this completely and hence this post. I received a lot of help on the Qemu irc channel(#qemu on OFTC).

I assume that Qemu is already installed on your machine and you also have installed OS on the virtual disc. If not you can download the latest source code and install Qemu from it. Also, you can download a sample virtual disk. Once all these are ready, follow the steps below.

First, start the qemu emulator on the host machine. 

$ qemu-system-x86_64 -hda cirros-0.3.0-x86_64-disk.img -netdev tap,id=net0,script=no,downscript=no -device e1000,netdev=net0

The above command will start the Qemu with KVM. The most interesting parts of the command is the -netdev option. Here, we instruct the Qemu to use tap interface to provide networking capability. Once we have started the Qemu, lets configure the host to send/receive packets. On the host, check the name of the tap device that Qemu is using to communicate the packets. It picks up the first unused device. 
 $ ip addr show
Once we know the name of the tap device, we should bring the interface up and also assign an IP address to it. Here, we are assuming the interface name as tap0. 
$ ip link set tap0 up
Now assign IP address to the tap interface 
$ ip addr add 10.1.70.1/24 broadcast + dev tap0
Once we do this, we are all set to send/receive the packets from the host. Now, we must configure the guest to send/receive the packets over the tap device. Once the guest machine is up, assign an IP address to the guest machine from the same subnet. 
$ ip addr add 10.1.70.2/24 broadcast + dev eth0
Since we had already instructed Qemu to use the tap device, it will send the packets through it. Now, check for connectivity by running
$ ping 10.1.70.1
The above IP address is the IP that we assigned to the tap device. The interesting thing to note here is that when we try to access the IP address of your host machine, ping command will return with network unreachable error message. The reason being that the guest machine doesn't know the route to follow to reach the host when this IP address is given. Let us add the necessary rule which would be used to send/received the packets.
$ route add default gw 10.1.70.1 dev eth0
Now, we can use the IP address of tap or host to access the host machine.

Links:

Sunday, November 13, 2011

Mutexes VS Semaphore

Mutex: Mutex is a program object that is typically used to serialise access to a section of re-entrant code that cannot be executed concurrently by more than one thread. A mutex object only allows one thread into a controlled section, forcing other threads which attempt to gain access to that section to wait until the first thread has exited from that section."

Semaphore: A semaphore is like an integer, with three differences:
  • When you create the semaphore, you can initialize its value to any integer, but after that the only  operations you are allowed to perform are increment (increase by one) and decrement (decrease by one). You cannot read the current value of the semaphore.
  • When a thread decrements the semaphore, if the result is negative, the thread blocks itself and cannot continue until another thread increments the semaphore.
  • When a thread increments the semaphore, if there are other threads waiting, one of the waiting threads gets unblocked.
To say that a thread blocks itself is to say that it notifies the scheduler that it cannot proceed. The scheduler will prevent the thread from running until an event occurs that causes the thread to become unblocked. In the tradition of mixed metaphors in computer science, unblocking is often called  as€œWaking.

From the definitions, it is very much clear that mutex contains binary value either True or False but a semaphore contains an integer value which holds those many number of keys to get that resource.

To further understand these two, lets consider an example
  • Mutex is a key to a toilet. One person can have the key - occupy the toilet-at the time. When finished, the person gives (frees) the key to the next person in the queue.
  • Semaphore on the other hand is analogous to the he number of free identical toilet keys. Say we have four toilets with identical locks and keys. The semaphore count - the count of keys - is set to 4 at beginning (all four toilets are free), then the count value is decremented as people are coming in. If all toilets are full, ie. there are no free keys left, the semaphore count is 0. Now, when eq. one person leaves the toilet, semaphore is increased to 1 (one free key), and given to the next person in the queue.
One of the often asked question is "what is the difference between a mutex and a binary semaphore?"
  By binary semaphore I mean that the value store in the semaphore is 1. So its similar to the mutex. But there are quiet a few good characteristics that distinguish the two.
  • Mutexes can be recursive (so reentrant lock works), and Semaphores are not.
  • One significant difference - a semaphore may be procured and vacated by any thread in any sequence (so long as the count is never negative), but a mutex may only be unlocked by the thread that locked it. Attempting to unlock a mutex which was locked by another thread is undefined behavior
  • The Mutex class enforces thread identity by virtue of owners, so a mutex can be released only by the thread that acquired it. In contrast, the Semaphore class doesnot enforce thread identity.

Now lets understand what are recursive mutexes:
POSIX allows mutexes to be recursive. That means the same thread can lock the same mutex twice and won't deadlock. Of course it also needs to unlock it twice, otherwise no other thread can obtain the mutex. Not all systems supporting pthreads also support recursive mutexes, but if they want to be POSIX conform, they have to.

Now, you may ask why on the earth would I call lock on the same mutex. To find the answer please refer links 1 and 2. It has pretty good explanation and I dont want to duplicate the effort.

There is something called as Futexes aswell, these are Fast user level mutexes, pthread library on linux implements Futexes, so all your user level programs that spawn thread are already using Futexes. Futexes have an edge over mutexes and hence are very useful.

[] http://stackoverflow.com/questions/2415082/when-to-use-recursive-mutex
[] http://stackoverflow.com/questions/187761/recursive-lock-mutex-vs-non-recursive-lock-mutex
[] http://blog.feabhas.com/2009/09/mutex-vs-semaphores-%E2%80%93-part-2-the-mutex/
[] http://web.itu.edu.tr/kesgin/mul06/intel/instr/cmpxchg.html

Monday, September 12, 2011

Formatting a filesystem using loopback Devices



When it comes to selecting a filesystem, Linux provides its users with a vast set of filesystem to choose from. There are many filesystems which are part of the linux kernel and there are others that are developed over fuse layer and the list is constantly growing everyday. When ever a new filesystem is released you might not want to format it on a partition (because of limited disk space, or to avoid disk fragmentation etc). One of the best method to try out a new filesystem is to format it on a loop back device and mount it on a directory. In this post I will demonstrate how to create a loopback device and then format it with ext4 (you can use any Filesystem of your choice) and the mount it on a directory.

The very first step is to create a file which will act as a psuedo partition so choose the size appropriately. There are two ways of doing it
  * using dd command
  * using truncate command
I prefer truncate over dd  because truncate creates a sparse file so the file does not consume any
disk space untill you add data into it but file created using dd will consume the disk space. To confirm that, 
truncate --size=1GB file-1GB
  Now check the output of
ls -l file-1GB
du -h file-1GB
ls will report the file size as 1GB but du will report the file size as 0. So, it can be confirmed that the file doesn't use any disk space.

  Now try
dd if=/dev/zero of=file-1GB bs=1KB count=1000000
  Now check the output of ls and du.

So, now you have created partition but the system doesn't recongnize it. So lets attach it to a device file.
losetup -f
Let's assume that it retured /dev/loop0, now run
losetup /dev/loop0 file-1GB
Okay. Now all set, choose a filesystem of your choice and format the device. I choose ext4 to demonstrate it.
mkfs.ext4 /dev/loop0
Now mount the device on a directory.
mkdir /my-fs
mount -t ext4 -oloop /dev/loop0 /my-fs.
Thats it. You can confirm it by running
df
your Filesystem will be listed there. Happy hacking :)

Note: When you reboot the system your filesystem will not be displayed by df command. You can either add the entry into /etc/fstab or write a script that will attach the file-1GB to a device and run the mount command. A sample script can be found here

Sunday, August 7, 2011

Explore VIM


"Give me six hours to chop down a tree and I will spend the first four sharpening the axe.”
– Abraham Lincoln
I start the post with an interesting note. We must have our tools ready before we start our work, it makes our work more fun otherwise it becomes a pain. A similar case is with the programmers. They spend most of there time in front of the terminal either writing new code or refactoring the old code. Having an environment customized as per one's need can make a huge difference.

Vim is one of the pieces of software that I use almost everyday. I have been a VIM user since the college days. I started with vi, When I started using it I was a bit annoyed because I had to remember all those commands to browse through the file, changing the modes to move from one line to another was a pain. But when I first used VIM, I was like I have been waiting for something like this because it had all the features that were provided by vi and it had many more. It was definitely more powerful than vi. In this post I will share some of the features which I personally have found to be very useful.
  • In VIM searching a word in the given file is achieved  by typing "/" in the command mode. But adding the following lines to your .vimrc file can make a huge difference.

    To move the cursor to the matched string while typing the search pattern, set
    set incsearch
     With 'ignorecase', searching is not case sensitive:
    set ignorecase
     If 'ignorecase' is on, you may also want:
    set smartcase
    When 'ignorecase' and 'smartcase' are both on, if a pattern contains an uppercase letter, it is case sensitive, otherwise, it is not. For example, "/The" would find only "The", while "/the" would find "the" or "The" etc.

    We can also search for a word in the file by placing the cursor on the word to be searched and pressing "*", this will take you to the next instance of the word in the file.
    Press "n" to move to the next instance of the searched word and "N" to goto the previous instance of the searched string.
  • Searching and replacing is one of the very common task. One can achieve this in VIM by typing
    :%s/search-string/replace-string/
    This will search for "search-string" and replace only the first matched instance of that string with "replace-string. To replace all the instances of the "search-string" add "g" at the end of the command.
    :%s/search-string/replace-string/g
    To search and replace only in few lines, provide the range of lines in the command. To do a find and replace only in lines 50-100, run
    :50,100s/search-string/replace-string/g
    To delete "search-string", donot pass any parameter in the replace-string, it will delete the "search-string". To delete all the "search-string" in lines 50-100, run
    :50,100s/search-string//g
  • Type "gf" in command mode to open the file containing the word the cursor currently points to.
  • Most of the time while browsing the code we feel the need to have more than one file opened in the terminal, either we open each file in a seperate terminal or close the current file and open the other. But VIM has tabs. Yes, it provides tabs just the way the browser's provide tabs. To open a file in the new VIM tab, type
    :tabedit file_name


    Use "ctrl+alt+pgup/pgdn" to traverse between the VIM tabs.

    Type :help tabedit in the command mode to explore more.
  • You use some words frequently in your document and wish there was a way that it could be quickly filled in the next time you use the  same word, VIM provides autofill feature. Press
    ctrl+n
    to achieve this.


  • To add line numbers to the file type
    :set number
















  • Good programming is all about making the code more readable, one of the ways  of achieving it is through indenting the code. Most of the time coping a piece of code from one block to another breaks this, VIM provides a way to perform some actions on the selected block. Press shift+v to select a block, as shown in the figure below:
     
Selecting a block with shift+v



       
          Once a block is selected we can
              *  Move the block 8 spaces to the left by pressing shift + < or 8 spaces to the right by pressing
                  shift + > so as to indent the code
              *  Copy the block by pressing "y" and then pasting it somewhere else by pressing "p".
              *  Search and replace a word only in the selected block, press
                  ":'<,'>s/search_string/replace_string/g"


        Or we can select column's by pressing "ctrl + v" as shown in the figure below.

         
Selecting a Column by pressing cntl + v














  • This is my favorite, VIM allows to split the page horizontally and vertically. This is of great use when we want to view two different files at a time. To split the file vertically press :vsp in the command mode.

    Vertical split















              Press ":sp" to split the screen horizontally. Press ":help vsp" to explore more about how to
              switch between the window etc.
    • Upper case and Lower case: VIM provides an easy way to change the case of the line to UPPER case or LOWER case. Here is the command,

                gUU or guu 

      Place the cursor on the line which you want to convert the case and in the command mode type these letters. gUU will convert the text to upper case and guu will convert the text to lower case.

      You can also flip the case of a set of character with the help of "~" command. To explore more on this type

              :help gUU
    • To open files located in other directories, you can use the full or relative paths such as 
    :e file name 
    • redo and undo: In Vim to undo the last command press

                undo- u

      and to redo the last command press

                ctrl+r

      in command mode
    • When you copy some code from the browser or other editors like gedit and paste it into Vim, you may loose the alignment. To keep the alignment intact, type

                :set paste

       and then paste the code. To change back to normal mode, type

                :set nopaste

      in command mode.
    • To find more help on Vim type ":help" command mode.
    • Find below a few other options that can be set in your .vimrc

                * set scrolloff=100
                * set cursorline
                * set autoindent " always set autoindenting on
                * set backup " keep a backup file
                * set backupdir=~/bkp/vim
                * set history=50 " keep 50 lines of command line history
                * set background=dark

    Some useful links:
    [1]  http://vim.wikia.com/wiki/Vim_Tips_Wiki
    [2]  https://github.com/mja054/Random-tweeks/blob/master/vimrc - to find a sample vimrc
    [3] http://dan.hersam.com/docs/vim.html
    [4] http://vimdoc.sourceforge.net/htmldoc/options.html#'shiftwidth'

    Thursday, July 7, 2011

    Segmentation Fault

    A segmentation fault or bus error occurs when the hardware notifies a operating system about a memory access violation. On receiving the notification the OS sends a signal to the process which caused the exception. Now its upto the process receiving the exception to decide how it would like to handle this exception. By default the process receiving the signal dumps its state in to a core file and terminates but the default signal handler can be overridden to customize how the signal is handled.

    There are many ways to get a segmentation fault, at least in the lower-level languages such as C(++). A common way to get a segmentation fault is to dereference a null pointer:
    int *p = NULL;
    *p = 1;
    Segmentation fault also happens when you try to write to a portion of memory that was marked as read-only:
    char *str = "Foo"; // Compiler marks the constant string as read-only
    *str = 'b';              // Which means this is illegal and results in a segfault
    Accessing Dangling pointer also causes segmentation faults like here:
    char *p = NULL;
    {
        char c;
        p = &c;
    }
    // Now p is dangling
    The pointer p dangles because it points to character variable c that ceased to exist after the block ended. And when you try to dereference dangling pointer (like *p='A'), you would probably get a segmentation fault.


    Another reason for segmentation fault is to recurse without a base case, which causes a stack overflow:
    int main() { main(); }
    Segmentation fault also happens when accessing a region of memory already freed

    Whenever segmentation faults happens, a core is generated by the process in the current directory. By default, most of the Linux distros disable the creation of core. So if you dont find the core file run the following command to enable the creation of core files.
    $ ulimit -c unlimited
     Generally core files are created as core.<pid>, pid is the pid of the process that created the core.

    Running the above command will set ulimit to unlimited on that terminal. So when you start a new terminal it would not be set. So to make it default in all the new terminals add it into ~/.bashrc.

    But to make sense out of the core dump you must compile the program with debugging symbols. Lets take an example program to understand how to use the core dump to the fullest.
    $ cat hello.c
    #include <stdio.h>
    int
    main ()
    {
            int *p = NULL;
            *p = 2;
            return 0;
    }
     Now enable debugging symbols while compiling
    $ gcc -g -O0 hello.c -o hello
    Now when you run this program, you will receive the following error
    $ ./hello
    Segmentation fault (core dumped)
    You will find that a core file is created in the current directory.

    Now run the core with the debugger (on most of the distros gdb is provided if not install it)
    $ gdb hello core.5123
    It will display the line in the program that caused the error. There are many other options that you can use with gdb to debug your issue, we will visit that in future posts.

    Some of the best practices to follow while programming in C/C++ is to 
    • Always check for NULL before dereferencing the pointers. Example

               if (ptr == NULL)
                         //return with error
    • Also check for NULL after the call to dynamic memory allocation functions like malloc, calloc, new etc. Example

              ptr = (int *) malloc (10 * sizeof (int));
              if (ptr == NULL)
                         //return with error
    References
    * http://collectd.org/wiki/index.php/Core_file
    * http://stackoverflow.com/questions/2346806/what-is-segmentation-fault
    * http://en.wikipedia.org/wiki/Segmentation_fault