Skip to main content

Device Mapper

Device-mapper is a very important component of Linux 2.6 kernel. It is used for many critical storage related applications, such as LVM2, Linux native multipath tool device-mapper-multipath, device-mapper software RAID, etc. A solid understanding of device-mapper helps system administrators to investigate various kinds of issues with these applications.

In the Linux kernel, the device-mapper is a generic framework to map one block device into another. It is not just for LVM2. By using device-mapper, the kernel provides general services to dm-multipath, LVM2 and EVMS, device-mapper software RAIDs, dm-crypt disk encryption and offers additional features such as file system snapshots.


In device-mapper architecture there are three important concepts to be familiarized
  • 1. Mapped Device
  • 2. Mapping Table
  • 3. Target Device
Mapped Device
Mapped device is a logical device provided by device-mapper driver. It provides an interface to operate on. The logical volumes in LVM2 and pseudo disks in dm-multipath are good examples of mapped devices.

Mapping Table

Mapping table represents a mapping from a mapped device to target devices. One table can be seen as an group of variables including mapped device’s starting address, length and target device’s physical device, starting address, length. The unit used here is a sector (512 bytes). The command “dmsetup create” will create such a table with parameters provided.

Target Device

Target device is a modularized plugin. The device-mapper filters and redirects I/O requests with it. some good examples for target device:

  • linear for LVM2
  • mirror for RAID
  • stripped for LVM2
  • snapshot for LVM2
How application deals with device mapper
Device-mapper works by processing data passed in from a virtual block device, that it itself provides, and then passing it on to another block device.
Applications (like dm_multipath and LVM2) that want to create new mapped devices talk to the Device-mapper via the libdevmapper.so shared library, which in turn issues ioctls to the /dev/mapper/control device node.

Comments

Popular posts from this blog

Spinlock implementation in ARM architecture

SEV and WFE are the main instructions used for implementing spinlock in case of ARM architecture . Let's look briefly at those two instructions before looking into actual spinlock implementation. SEV SEV causes an event to be signaled to all cores within a multiprocessor system. If SEV is implemented, WFE must also be implemented. Let's look briefly at those two instructions before looking into actual spinlock implementation. WFE If the Event Register is not set, WFE suspends execution until one of the following events occurs: an IRQ interrupt, unless masked by the CPSR I-bit an FIQ interrupt, unless masked by the CPSR F-bit an Imprecise Data abort, unless masked by the CPSR A-bit a Debug Entry request, if Debug is enabled an Event signaled by another processor using the SEV instruction. In case of  spin_lock_irq( )/spin_lock_irqsave( ) , as IRQs are disabled, the only way to to resume after WFE intruction has executed is to execute SEV ins

Explanation of "struct task_struct"

This document tries to explain clearly what fields in the structure task_struct do. It's not complete and everyone is welcome to add information. Let's start by saying that each process under Linux is defined by a structure task_struct. The following information are available (on kernel 2.6.7): - volatile long state;    /* -1 unrunnable, 0 runnable, >0 stopped */ - struct thread_info *thread_info; a pointer to a thread_info... - atomic_t usage; used by get_task_struct(). It's also set in kernel/fork.c. This value acts like a reference count on the task structure of a process. It can be used if we don't want to hold the tasklist_lock. - unsigned long flags;    /* per process flags, defined below */ process flag can be, for example, PF_DEAD when exit_notify() is called. List is of possible values is in include/linux/sched.h - unsigned long ptrace; used by ptrace a system call that provides the ability to a parent process to observe and con

Macro "container_of"

Understanding container_of macro in the Linux kernel When you begin with the kernel, and you start to look around and read the code, you will eventually come across this magical preprocessor construct. What does it do? Well, precisely what its name indicates. It takes three arguments – a  pointer ,  type  of the container, and the  name  of the member the pointer refers to. The macro will then expand to a new address pointing to the container which accommodates the respective member. It is indeed a particularly clever macro, but how the hell can this possibly work? Let me illustrate… The first diagram illustrates the principle of the  container_of(ptr, type, member)  macro for who might find the above description too clumsy. I llustration of how the containter_of macro works. Bellow is the actual implementation of the macro from Linux Kernel: #define container_of(ptr, type, member) ({ \ const typeof( ((type *)0)->member ) *__mptr = (