Skip to Content

Raw Devices on Suse Linux

Three steps to create a logical volume

How can we make raw devices in Suse Linux? Is there an easy way to build chunks based on raw devices with something like a Logical Volume manager?
The answer is: yes. In this article we learn the basics of LVM2 (created by Heinz Mauelshagen) and how to use it to create raw devices for an informix instance. We will not go through the whole set of LVM-commands but only those which are necessary for handling raw devices.

First have a look on the version of your LVM.
The output of the command "lvm version" shows

libelle:/opt # lvm version
  LVM version:     2.02.02 (2006-02-07)
  Library version: 1.02.03 (2006-02-08)
  Driver version:  4.5.0

so we know that we have LVM2. It is important to know which version you use, because Logical Volumes (LV) are differently represented in LVM1 and LVM2.
LVM1 stores information about LVs in /proc/lvm/VGs which has changed to /dev/mapper in LVM2.
LVM2 is part of the OS since Suse 9.3. If it is not automatically installed, you can install LVM2 via yast2.

To create a logical volume we have to

  1. inititalize physical volumes (disks or partitions on disks)
  2. define Volume Groups (VGs) as sets of physical volumes
  3. define logical volumes (LVs) as subsets of VGs

The first two steps will be done with yast2, the GUI-based administration tool from Suse, but you can do it also with commands like 'pvcreate' and 'vgcreate'.
For example, if you want to make the whole disk /dev/hdb a physical volume, you should enter

pvcreate /dev/hdb

This creates a volume group descriptor at the start of disk.
Perhaps we get an error if there was a partition table on the disk. Then we have to delete this table explicitly with "dd":

dd if=/dev/zero of=/dev/hbd bs=1k count=1
blockdev --rereadpt /dev/hdb

Instead of the whole disk we can use a partition /dev/hdb1:

pvcreate /dev/hdb1

Next we create the Volume Group (if you didn't create it with Yast2):

vgcreate system  /dev/hdb1 

Next we want to see the results:

libelle:/home/f995440 # pvdisplay
  --- Physical volume ---
  PV Name               /dev/hda6
  VG Name               system
  PV Size               4,00 GB / not usable 0   
  Allocatable           yes 
  PE Size (KByte)       4096
  Total PE              1023
  Free PE               102
  Allocated PE          921
  PV UUID               RCHWtF-r1Kn-iwlc-oA13-RGwd-B2X3-GVoEfi
libelle:/etc # vgdisplay
  --- Volume group ---
  VG Name               system
  System ID             
  Format                lvm2
  Metadata Areas        1
  Metadata Sequence No  49
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                16
  Open LV               15
  Max PV                0
  Cur PV                1
  Act PV                1
  VG Size               4,00 GB
  PE Size               4,00 MB
  Total PE              1023
  Alloc PE / Size       921 / 3,60 GB
  Free  PE / Size       102 / 408,00 MB
  VG UUID               7hZSbH-JsM3-92au-OQ9C-jRuQ-y7Zp-xI453P

On my Suse Linux System the name of the volume group is "system", it's size is 4GB, and the size of PE=physical Extent is 4MB. Later we will see that Logical Volumes consist of Physical Extents (PE), which are mapped onto Physical Extents of the VG to which LV belongs.

Now we are ready to create the raw device for our Root DB space. We want to have about 50MB for the Root DBspace.

Create the Logical Volume (LV)

libelle:/home/f995440 # lvcreate -L 50M -n example system
  Rounding up size to full physical extent 52,00 MB
  Logical volume "example" created

Our "example" Volume was rounded up to full physical extent size of 52,00 MB, because the size must be a multiple of 4MB PE-Size.

From Logical Volume to Raw device

What is the result of the lvcreate command? "lvdisplay" gives a detailed description of the LV:

libelle:/etc # lvdisplay /dev/system/example
  --- Logical volume ---
  LV Name                /dev/system/example
  VG Name                system
  LV UUID                6J7uMK-0pwI-1olB-bESP-UtET-p94v-XkoDaZ
  LV Write Access        read/write
  LV Status              available
  # open                 0
  LV Size                52,00 MB
  Current LE             13
  Segments               1
  Allocation             inherit
  Read ahead sectors     0
  Block device           253:16

You see, that the "name" of the LV is /dev/system/example. This is not a raw device but only a symbolic link to a block device:

libelle:/etc # ls -ail /dev/system/example
1986699 lrwxrwxrwx 1 root root 26 2006-11-02 15:51 /dev/system/example -> /dev/mapper/system-example
libelle:/etc # ls -ail /dev/mapper/system-example
1986698 brw------- 1 root root 253, 16 2006-11-02 15:51 /dev/mapper/system-example

We cannot change the block device somehow into a raw device but we can bind a raw device to this blockdevice. This will be done by a utility called raw (see man raw).

Raw devices are character devices with major number 162. The first minor number (i.e. 0) is reserved as a control interface and is usually found at /dev/rawctl. The control device /dev/rawctl can be generated with the command

/sbin/modprobe raw

Raw-devices are located in /dev/raw and can be created with "mknod":

cd /dev/raw
while  ((i<= 128))
       mknod raw$i c 162 $i
       let i=i+1

Next we want to bind the block device /dev/system/example to raw device /dev/raw/raw50:

libelle$raw /dev/raw/raw50 /dev/system/example
/dev/raw/raw50: bound to major 253, minor 16

raw -qa
/dev/raw/raw50: bound to major 253, minor 16

The command raw -qa shows all raw devices which are bounded to other devices. The only method to identify the logical volume to which the raw device is bounded is to compare the major/minor numbers. It is important to put this information somewhere in a file so that you can rebind all your raw devices after a system crash. Usually this is the file /etc/raw. Here is an example of /etc/raw on my Suse system:

# /etc/raw
# sample configuration to bind raw devices
# to block devices
# The format of this file is:
# raw: 
# example:
# ---------
# raw1:hdb1
# this means: bind /dev/raw/raw1 to /dev/hdb1
# ...

After a reboot you must rebind your raw devices because they are not automatically bounded - may be that they do not exist so that you have to generate the control device and the other raw devices again. To do this you can extend the script /etc/init.d/raw. /usr/sbin/rcraw is a symbolic link to /etc/init.d/raw. With rcraw you can start raw devices and show the status (i.e. "raw -qa"):

rcraw start # start raw devices (i.e. binds...)
rcraw staus # status of raw devices

You cannot stop raw devices/unbound them. This can
only be done by a system shutdown!

Here is an example of /etc/init.d/raw on my system:

# Copyright (c) 1995-2001 SuSE GmbH Nuernberg, Germany.
# Author: Dirk Lerner 
# Provides:       raw
# Required-Start: $local_fs $remote_fs
# Required-Stop:
# Default-Start:  2 3 5
# Default-Stop:   0 1 6
# Description:    raw-devices

    echo `date +%d-%m-%Y/%T` $* >> $PROTOKOLL
    return $?

        # generate Raw-Devices, if the do not exist
        if [[ ! -d /dev/raw ]]
                myecho "Directory /dev/raw do not exist"
                myecho "Directory /dev/raw will be generated"
                mkdir /dev/raw
        if [[ ! -f /dev/raw/raw* ]]
                myecho "No raw devices, must create"
                cd /dev/raw
                while  ((i<= 128))
                        mknod raw$i c 162 $i
                        let i=i+1



. /etc/rc.status

test -x $RAW_BIN || exit 5

if [ ! -f $CONFIG ];then
 myecho "file: $CONFIG not found"
 exit 6

case "$1" in
        # modprobe adds the Modul raw into Linux-kernel
        # and generates the control device
        myecho "starting genraw "
        /sbin/modprobe $RAW_MODULE && sleep 2
        line=`cat $CONFIG | grep -v ^#`

        rawdev=`cat $CONFIG | cut -f1 -d:`
        rawbind=`cat $CONFIG | cut -f2 -d:`

        for i in $line;do
                rawdev=`echo $i | cut -f1 -d:`
                rawbind=`echo $i | cut -f2 -d:`
                myecho "rawdev=$rawdev, rawbind=$rawbind"
                myecho "bind /dev/raw/$rawdev to /dev/$rawbind..."
                $RAW_BIN /dev/raw/$rawdev /dev/$rawbind  >>$PROTOKOLL 1>> $PROTOKOLL 2>&1
                rc_status -v
      myecho  "to unbind the rawdevice please perform a system shutdown"
      rc_failed 3
      rc_status -v
      $RAW_BIN -qa 2> /dev/null
      rc_status -v
      myecho "Usage: $0 {start|stop|status}"
      exit 1

Add a symbolic link

ln -s /etc/rc.d/raw /etc/rc.d/rc2.d/S21raw

to start automatically raw devices after booting the system. Please note, that /etc/init.d/raw uses the content of Config-file /etc/raw to find logical volumes to be bound.

Let us summarize the steps for creating a raw device:

  • create a logical volume
  • create a raw device
  • bind this raw device to the logical volume
  • put an appropriate row in /etc/raw

Now we are able to create a sample informix instance. We assume, that we have enough raw devices in /dev/raw. Look at the following list of commands:

  • Create a logical volume (100MB) for the root Dbspace:
    lvcreate -L 100M -n inf_0_001 system
  • Bind a raw device to the LV:
    raw /dev/raw/raw1 /dev/mapper/system-inf_0_001
  • chmod 660 /dev/raw/raw1
    chown informix:informix /dev/raw/raw1
  • Put all links to chunks in a special directory: on my system it is /db/inf/dev/libelle. Then change ROOTPATH in your ONCONFIG file and create a symbolic link:
    ln -s /dev/raw/raw1 /db/inf/dev/libelle/inf_0_001
    ROOTPATH        /db/inf/dev/libelle/inf_0_001
  • Start initialization:
    oninit -ivy

A Python-Program for creating dbspaces und raw-devices

If you want to create more dbspaces it is recommended to write a program which can do for you the steps mentioned above. Take a look at inf_space, a python program wich can do the most used tasks for you:
  • inf_space -c -d dbspacename -m megabytes [-t]
           -c stands for "Create"
           -d dbspacename
           -m size in Megabyte 
           -t for temporary Dbspaces
  •  inf_space -c -S dbspacename -m megabytes [-t]
           -c stands for "Create"
           -S Smart Blobspacename
           -m size in Megabyte  
           -t for temporary Dbspaces
  •  inf_space -a -d dbspacename -m megabytes
           -a adds a chunk
           -d dbspacename
           -m size in Megabyte  
  •  inf_space -r -d dbspacename
           -d dbspacename
           -r remove dbspace
  •  inf_space -r -d dbspacename  -n chunknumber
           -d dbspacename
           -r remove dbspace
           -n Chunknumber

inf_space is only a low-level routine for the most common tasks when creating dbspaces. You can change or extend if you want.

Download inf_space.tar.gz

Copyrightblog |