Raw Devices on Suse Linux
-
Three steps to create a logical volume
-
From Logical Volume to Raw device
-
A Python-Program for creating dbspaces und raw-devices
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
- inititalize physical volumes (disks or partitions on disks)
- define Volume Groups (VGs) as sets of physical volumes
- 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))
do
mknod raw$i c 162 $i
let i=i+1
done
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 # # ... raw1:system/inf_0_001 raw10:system/physdbs_001 raw100:system/logdbs_001 raw103:system/perfdbs_001 raw104:system/perfdbs_002 raw107:system/tempdbs3_001 raw108:system/tempdbs1_001 raw109:system/tempdbs1_001 raw11:system/tempdbs2_001 raw110:system/testspace_001 raw111:system/datenspace1_001 raw112:system/sbspace_001 raw113:system/sbspace_default_001 raw101:system/logdbs_002 raw102:system/massendaten_001 raw105:system/s9_sbspc_001
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:
#!/bin/bash # Copyright (c) 1995-2001 SuSE GmbH Nuernberg, Germany. # # Author: Dirk Lerner# ### BEGIN INIT INFO # Provides: raw # Required-Start: $local_fs $remote_fs # Required-Stop: # Default-Start: 2 3 5 # Default-Stop: 0 1 6 # Description: raw-devices ### END INIT INFO myecho() { echo `date +%d-%m-%Y/%T` $* >> $PROTOKOLL return $? } genraw() { # generate Raw-Devices, if the do not exist if [[ ! -d /dev/raw ]] then myecho "Directory /dev/raw do not exist" myecho "Directory /dev/raw will be generated" mkdir /dev/raw fi if [[ ! -f /dev/raw/raw* ]] then myecho "No raw devices, must create" cd /dev/raw while ((i<= 128)) do mknod raw$i c 162 $i let i=i+1 done fi } i=1 PROTOKOLL=/db/inf/log/raw.log . /etc/rc.status CONFIG=/etc/raw RAW_BIN=/usr/sbin/raw RAW_MODULE=raw test -x $RAW_BIN || exit 5 if [ ! -f $CONFIG ];then myecho "file: $CONFIG not found" exit 6 fi rc_reset case "$1" in start) # modprobe adds the Modul raw into Linux-kernel # and generates the control device myecho "starting genraw " 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 done ;; stop) myecho "to unbind the rawdevice please perform a system shutdown" rc_failed 3 rc_status -v ;; status) $RAW_BIN -qa 2> /dev/null rc_status -v ;; *) myecho "Usage: $0 {start|stop|status}" exit 1 ;; esac rc_exit
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.
Rok is right we open
Rok is right we open character and block devices in case of KAIO with the O_DIRECT flag.
This means the raw command on Linux is not needed since IDS 10.00
BTW - That's funny ...
because it was Sandor who told me as I met him at last year's Infobahn at Munich. I took the opportuninity and aske him JUST THAT .




Why raw devices ?
Okay, this article is quite interesting and well written, but .. do I really
have to use raw devices mapped with "raw". I agree that it is crucial on
(other) unices, but as far as I understood, IDS 10.0 handles disks/partitions
like raw devices, if libaio.so is present - with the additional benfits of kaio.
cu
rok