Tuesday, March 15, 2011

Network device driver for my Ubuntu box

I have not updated this post from a long time as currently I am busy with some other system kind of experiments,you can read more about me if you check this link http://biturl.net/tapas

These days I am studying network device drivers for wifi devices.
I am using my laptop for such experiments.The PCI id of device on my laptop is 14e4:4315.

So if interested to develop along we can share some thoughts.
Rest on this blog I am sharing a char device driver if you are interested to know more of my device driver codes you can drop me a mail.Or contact via Skype.


#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <linux/cdev.h>
#include <linux/errno.h>
#include <asm/uaccess.h>

#define FIRST_MINOR 0
#define MINOR_CNT 1

static dev_t dev;
static struct cdev c_dev;
static struct class *cl;

static int my_open(struct inode *i, struct file *f)
{
 return 0;
}
static int my_close(struct inode *i, struct file *f)
{
 return 0;
}

static char c = 'A';

static ssize_t my_read(struct file *f, char __user *buf, size_t len, loff_t *off)
{
 if (*off == 0)
 {
  if (copy_to_user(buf, &c, 1))
  {
   return -EFAULT;
  }
  *off += 1;
  return 1;
 }
 else
  return 0;
}
static ssize_t my_write(struct file *f, const char __user *buf, size_t len, loff_t *off)
{
 if (copy_from_user(&c, buf + len - 1, 1))
 {
  return -EFAULT;
 }
 return len;
}

static struct file_operations sri_fops =
{
 .owner = THIS_MODULE,
 .open = my_open,
 .release = my_close,
 .read = my_read,
 .write = my_write
};

int __init init_module()
{
 printk("Hello Universe\n");
 if (alloc_chrdev_region(&dev, FIRST_MINOR, MINOR_CNT, "EMX") < 0)
 {
  return -1;
 }
 printk("Major Nr: %d\n", MAJOR(dev));

 cdev_init(&c_dev, &sri_fops);

 if (cdev_add(&c_dev, dev, MINOR_CNT) == -1)
 {
  unregister_chrdev_region(dev, MINOR_CNT);
  return -1;
 }
 
 if ((cl = class_create(THIS_MODULE, "chardrv")) == NULL)
 {
  cdev_del(&c_dev);
  unregister_chrdev_region(dev, MINOR_CNT);
  return -1;
 }
 if (device_create(cl, NULL, dev, NULL, "mychar%d", 0) == NULL)
 {
  class_destroy(cl);
  cdev_del(&c_dev);
  unregister_chrdev_region(dev, MINOR_CNT);
  return -1;
 }

 return 0;
}

void __exit cleanup_module()
{
 device_destroy(cl, dev);
 class_destroy(cl);
 cdev_del(&c_dev);
 unregister_chrdev_region(dev, MINOR_CNT);
 printk("Bye Universe\n");
}

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Tapas");
MODULE_DESCRIPTION("Test driver");
To test the above driver you will have to create a dummy device on your machine via mknod and statically link this module to the device.
Then you will be able read and write on the device.

Orielly Linux Device Drivers Development 3rd edition has been quite useful for the above code.
If you want to understand the network device section you can read 17th chapter of book and
also Oreilly Linux Network Internals describe this topic in great detail.
If you want to understand how network device driver works you can drop me a mail.

Sunday, March 6, 2011

apache reverse proxy tutorial Ubuntu 10.04

Rather than going into any further details and wasting your time to further search things on internet or giving lecture to read Eric Stevens non sense guide How to ask questions smart way which you might have faced while asking in forums.
Here is a small scenario where you would like to configure an Apache Reverse proxy.

You are having a server with a public IP and apache is running on it.Now you want to host your applications on LAN and also want them to be accessible on internet the important part is these applications are still running on the machines on LAN.

let say the websites are :

a)internal1.example.com should map to internal1.example.com
b)internal2.example.com should map to internal2.example.com
c)internal3.example.com should point to internal3 .example.com
d)internal4.example.com should point to internal4 .example.com

Following is network configuration

                           |--------------192.168.1.3 
                           |            (internal3.example.com)
                           |
                           |--------------192.168.1.4
                           |            (internal4.example.com)
  (Public IP )             |
            A--------------|
(reverse proxy server)     |
  (192.168.1.25)           |
example.com                |
                           |--------------192.168.1.1
                           |            (internal1.example.com)
                           |
                           |--------------192.168.1.2
                           |            (internal2.example.com)



I am using Ubuntu to host Apache the vhost definition in case of Debian based systems the definiton of websites is done on

/etc/apache2/sites-enabled/*.conf

where *conf corresponds to

internal1.conf internal2.conf internal3.conf internal4.conf

The vhost definition of each of these sites will be as follows

/etc/apache2/sites-enabled/internal1.example.conf

<virtualhost *:80>

      ServerAdmin webmaster@localhost
      ServerName internal1.example.com
      ProxyRequests off
      <proxy *>
      Order deny,allow
      Allow from all
      </proxy >
      ProxyPass / http://192.168.1.1/
      ProxyPassReverse / http://192.168.1.1/
</VirtualHost >

/etc/apache2/sites-enabled/internal2.example.conf
<virtualhost *:80>

      ServerAdmin webmaster@localhost
      ServerName internal2.example.com
      ProxyRequests off
      <proxy *>
      Order deny,allow
      Allow from all
      </proxy >
      ProxyPass / http://192.168.1.2/
      ProxyPassReverse / http://192.168.1.2/
</VirtualHost >
/etc/apache2/sites-enabled/internal3.example.conf

<virtualhost *:80>

      ServerAdmin webmaster@localhost
      ServerName internal3.example.com
      ProxyRequests off
      <proxy *>
      Order deny,allow
      Allow from all
      </proxy >
      ProxyPass / http://192.168.1.3/
      ProxyPassReverse / http://192.168.1.3/
</VirtualHost >

/etc/apache2/sites-enabled/internal4.example.conf
<virtualhost *:80>

      ServerAdmin webmaster@localhost
      ServerName internal4.example.com
      ProxyRequests off
      <proxy *>
      Order deny,allow
      Allow from all
      </proxy >
      ProxyPass / http://192.168.1.4/
      ProxyPassReverse / http://192.168.1.4/
</VirtualHost >

Note in all of the above vhost definitions I have dropped the options of Log files.
So if you apply to a production server add them in each of the vhost file.
Above is just to give you a clear cut example as how it can be working.
I run a very complex Apache setup so above is just a small example to help you.
Rest of the details can vary depending upon your configurations.

Tuesday, March 1, 2011

how to save bandwidth in git pull when you do a make world on Xen source

Those who have compiled xen from source must have faced this annoying situation.
When you did a make world then you see some output like this
install -m0644 -p /usr/src/xen-4.0.1/xen/xen-syms //boot/xen-syms-4.0.1
make[2]: Leaving directory `/usr/src/xen-4.0.1/xen'
make[1]: Leaving directory `/usr/src/xen-4.0.1/xen'
for i in  linux-2.6-pvops  ; do make $i-install || exit 1; done
make[1]: Entering directory `/usr/src/xen-4.0.1'
make -f buildconfigs/mk.linux-2.6-pvops build
make[2]: Entering directory `/usr/src/xen-4.0.1'
set -ex; \
        if ! [ -d linux-2.6-pvops.git ]; then \
                rm -rf linux-2.6-pvops.git linux-2.6-pvops.git.tmp; \
                mkdir linux-2.6-pvops.git.tmp; rmdir linux-2.6-pvops.git.tmp; \
                git clone -o xen -n git://git.kernel.org/pub/scm/linux/kernel/git/jeremy/xen.git linux-2.6-pvops.git.tmp; \
                (cd linux-2.6-pvops.git.tmp; git checkout -b xen/stable-2.6.32.x xen/xen/stable-2.6.32.x ); \
                mv linux-2.6-pvops.git.tmp linux-2.6-pvops.git; \
        fi
+ [ -d linux-2.6-pvops.git ]
+ rm -rf linux-2.6-pvops.git linux-2.6-pvops.git.tmp
+ mkdir linux-2.6-pvops.git.tmp
+ rmdir linux-2.6-pvops.git.tmp
+ git clone -o xen -n git://git.kernel.org/pub/scm/linux/kernel/git/jeremy/xen.git linux-2.6-pvops.git.tmp
Initialized empty Git repository in /usr/src/xen-4.0.1/linux-2.6-pvops.git.tmp/.git/
remote: Counting objects: 1941611, done.
remote: Compressing objects: 100% (319164/319164), done.
The above really takes long time because it is basically cloning the git repository from jeremy's tree to your local machine and you have to wait until the pull completes.
The size is approximately 875 Mb so you will have to wait till that much time.
After digging this problem for some time I finally found a remedy for the same.

You need to fix the Makefile for the same.



When you untar xen-4.0.1.tar then you see
/usr/src/xen-4.0.1  
(location /usr/src can change depending upon where you untarred it at your laptop I prefer /usr/src for all source builds)

Now before you begin any sort of compilation etc in your home directory
pull the git tree as above mentioned (since we will remove the lines from Makefile itself)

so have at some safe location
cd $HOME
git clone -o xen -n git://git.kernel.org/pub/scm/linux/kernel/git/jeremy/xen.git linux-2.6-pvops.git.tmp;
At this point you should be able to see $HOME/linux-2.6-pvops.git.tmp we will use this again and again.

Now /usr/src/xen-4.0.1/buildconfigs directory open file
src.git-clone and add a hash # at the beginning of following lines
               rm -rf $(LINUX_SRCDIR) $(LINUX_SRCDIR).tmp; \
               mkdir $(LINUX_SRCDIR).tmp; rmdir $(LINUX_SRCDIR).tmp; \
               $(GIT) clone -o $(XEN_GIT_ORIGIN) -n $(XEN_LINUX_GIT_URL) $(LINUX_SRCDIR).tmp; \
               (cd $(LINUX_SRCDIR).tmp; git checkout -b $(XEN_LINUX_GIT_LOCALBRANCH) $(XEN_LINUX_GITREV) ); \
               mv $(LINUX_SRCDIR).tmp $(LINUX_SRCDIR); \

so that they look as

#               rm -rf $(LINUX_SRCDIR) $(LINUX_SRCDIR).tmp; \
#               mkdir $(LINUX_SRCDIR).tmp; rmdir $(LINUX_SRCDIR).tmp; \
#               $(GIT) clone -o $(XEN_GIT_ORIGIN) -n $(XEN_LINUX_GIT_URL) $(LINUX_SRCDIR).tmp; \
#               (cd $(LINUX_SRCDIR).tmp; git checkout -b $(XEN_LINUX_GIT_LOCALBRANCH) $(XEN_LINUX_GITREV) ); \
#               mv $(LINUX_SRCDIR).tmp $(LINUX_SRCDIR); \
The above lines in src.git-clone are responsible for this time consuming pull.
Now when you need to compile again and again xen-tools you can simply extract
the xen-4.0.1.tar.gz
and
copy the $HOME/linux-2.6-pvops.git.tmp to /usr/src/xen-4.0.1/

now you can begin the compile process again.

make install xen-tools
and it should work fine.

Now here I would like to add some more points that I had also commented out all lines that begin with rm in file
/xen-4.0.1/buildconfigs/mk.linux-2.6-common 
since to uninstall the tools I had used
make uninstall and make clean command which is available as clear from the Makefile.
But then I again copied the

$HOME/linux-2.6-pvops.git.tmp to /usr/src/xen-4.0.1 and then again
make xen
make tools
make stubdom
make install xen
make install xen-tools

So your point is only the src.git-clone file.