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?
answer
- one device, several spellings
- the kernel node is not stable
- udev makes the friendly links
- the joining character is also legal in names
- 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 sDevice-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 linesls -l /dev/mapper/
lvs -o lv_name,vg_name,lv_path,lv_dm_path
dmsetup ls
lsblkgo deeper
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.
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.
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.
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