skip to content

An LVM logical volume appears on Linux as /dev/vg0/data, /dev/mapper/vg0-data and /dev/dm-2. What is each of those three paths, and how does device-mapper name a volume whose VG or LV name contains a dash?

level: middleimportance: nice to knowfreq 30%

answer

  1. one device, several spellings
  2. the kernel node is not stable
  3. udev makes the friendly links
  4. the joining character is also legal in names
  5. doubled means literal

basics

~20 s

/dev/dm-2 is the real device-mapper device node, whose number is assigned at activation and is not stable. /dev/mapper/vg0-data and /dev/vg0/data are udev-created symlinks to it. Dashes inside a VG or LV name are doubled in the /dev/mapper form.

solid answer

~40 s

Device-mapper creates the actual node as `/dev/dm-N`, where N is handed out in activation order — it can differ after a reboot, so nothing should reference it. udev then creates two stable symlinks pointing at it: `/dev/mapper/<vg>-<lv>`, built from the device-mapper name, and `/dev/<vg>/<lv>`, the older LVM-style path. Both are fine to use in a mount entry or a service unit. The trap is the separator: because `-` joins the VG and LV halves in the `/dev/mapper` name, any dash inside either name is escaped by doubling it. A VG called `backup-vg` holding an LV called `db-data` shows up as `/dev/mapper/backup--vg-db--data`, while the `/dev/backup-vg/db-data` form stays unescaped. `lvs -o lv_name,lv_path,lv_dm_path` prints both spellings so you never have to guess.

code

bash · 4 lines
bash
ls -l /dev/mapper/
lvs -o lv_name,vg_name,lv_path,lv_dm_path
dmsetup ls
lsblk

go deeper

for a junior

Recognise that /dev/vg0/data and /dev/mapper/vg0-data are two names for the same logical volume, and use either one rather than the /dev/dm-N node.

for a middle

Explain that device-mapper owns the real node, that udev creates both symlinks, and be able to decode an escaped name where a doubled dash means a literal dash inside the VG or LV name.

for a senior

Use the mapping in an incident: translate the dm-N name from iostat or a kernel message back to a volume with ls -l /dev/mapper or lvs -o lv_dm_path, and know that none of the symlinks exist before LVM activation during early boot.

for a principal

Set the naming convention that avoids the problem: ban dashes in VG and LV names across the fleet so escaped and unescaped forms never diverge in scripts, alerts and runbooks.

## Three names, one device A logical volume is implemented by the kernel's **device-mapper** subsystem: LVM computes a mapping table ("logical sectors 0–51199 live on PV /dev/sdb starting at sector X") and loads it into a device-mapper device. That device is the only real object; everything else is a name for it. **`/dev/dm-2`** is that object. The number is allocated when the device is activated, in whatever order activation happens. Add a disk, reorder activation, or reboot, and the same logical volume can become `/dev/dm-5`. Treat these paths as diagnostic output only — useful when you are correlating with `iostat`, `lsblk` or `/proc/diskstats`, which report the kernel names — and never as a configuration value. **`/dev/mapper/vg0-data`** is a symlink created by udev, named after the device-mapper name of the device. Every device-mapper device gets one, not just LVM volumes — cryptsetup, multipath and thin pools all populate `/dev/mapper` too. `dmsetup ls` lists these names directly. **`/dev/vg0/data`** is the LVM-flavoured symlink: a directory per volume group, containing one entry per logical volume. It is the friendlier form, and it is what `lvcreate` echoes back at you. The last two are equivalent in practice and both are stable across reboots, because they are derived from names you chose rather than from activation order. `ls -l` on either shows the relative link to `../dm-2`. ## Why the dashes get doubled The device-mapper name is a single flat string, and LVM builds it by joining the VG and LV names with a dash: `vg0` + `-` + `data` = `vg0-data`. That is ambiguous the moment a name contains a dash of its own — `backup-vg-db` could split three ways. LVM resolves it by escaping: every literal dash inside a component is written twice. So a VG named `backup-vg` with an LV named `db-data` produces the device-mapper name `backup--vg-db--data`, and hence: ```bash /dev/mapper/backup--vg-db--data # escaped, single-dash separator /dev/backup-vg/db-data # unescaped, directory separator ``` The single dashes in that first path are the separator; the doubled ones are literal characters. Reading it back is mechanical: collapse `--` to `-`, and the remaining single dash is the split point. This is a genuine source of confusion in scripts and in log messages, because kernel and device-mapper messages use the escaped form while your notes almost certainly use the unescaped one. Two mitigations: prefer VG and LV names without dashes (underscores are not escaped), and let the tooling tell you the answer instead of deriving it by hand. ## Getting the names from the tools ```bash lvs -o lv_name,vg_name,lv_path,lv_dm_path ``` `lv_path` is the `/dev/<vg>/<lv>` form; `lv_dm_path` is the `/dev/mapper/...` form with escaping already applied. For the device-mapper side of the house: ```bash dmsetup ls # device-mapper names and their dev_t dmsetup info /dev/mapper/vg0-data lsblk # tree view: disk -> partition -> lvm device ``` `lsblk` is often the fastest orientation tool of the lot, because it shows the stack — physical disk, then the LVM devices sitting on it, with the mountpoint on the right. ## Which one to write down For anything persistent — a mount entry, a systemd unit's `What=`, a backup script — use a stable identifier. The `/dev/<vg>/<lv>` and `/dev/mapper/<vg>-<lv>` symlinks qualify, and they have the advantage of being self-documenting about which volume you meant. What must not appear is `/dev/dm-N`. A subtlety worth knowing: these symlinks only exist while the volume group is activated and udev has processed the event. During early boot, before LVM activation runs, none of them are present — which is why an initramfs has to activate the volume group itself before it can mount a root filesystem that lives on an LV. ## Where the names show up unbidden Once you know the mapping, several outputs stop being mysterious. `iostat -x` and `/proc/diskstats` show `dm-2`. Kernel messages in `dmesg` and `journalctl -k` refer to `dm-2` as well. `df` shows whichever path was passed to `mount`. Correlating a slow device in `iostat` with the volume that owns it is a two-step: read the `dm-N` name, then match it against `lvs -o lv_name,lv_dm_path` or `ls -l /dev/mapper`.

  • You see a device called dm-3 saturating the disk in iostat -x output. How do you find out which logical volume that is?
    Match the kernel name back to a volume: `ls -l /dev/mapper` shows every symlink and the `../dm-N` it points at, and `lvs -o lv_name,vg_name,lv_dm_path` prints the same mapping in table form. `lsblk` shows it in context — which physical disk the device sits on and where it is mounted — which is usually the fastest of the three.
  • Why should a persistent mount never reference /dev/dm-2 directly?
    The number is assigned when the device is activated, in activation order, so it can change after a reboot or after another volume is added. The `/dev/mapper/<vg>-<lv>` and `/dev/<vg>/<lv>` symlinks are derived from names you chose and stay put, which makes them safe to write down.
  • Do those symlinks exist before the volume group has been activated?
    No. udev creates them in response to the device-mapper device appearing, which only happens once the volume group is activated. That is why an initramfs must activate LVM itself before it can mount a root filesystem on a logical volume — at that point in boot the paths simply do not exist yet.

saying these in an interview costs you the question

  • Treats /dev/dm-N as a stable path to configure
  • Thinks /dev/mapper and /dev/vg are different devices
  • Reads backup--vg as containing two dashes literally
  • Believes only LVM populates /dev/mapper
  • Assumes the symlinks exist before activation

context