Dual Disk LVM with Loopback Files

Mon 05 February 2018

Filed under Gentoo

Tags gentoo lvm sparc

The story

My SPARC Enterprise T5120 came with two 10000 RPM SAS HDDs, both with a labeled capacity of 146GB. Gentoo was installed on the first hard drive, and thanks to the old SILO that was in charge of booting the system up, I have to keep a single-large-root partition scheme. While the second disk seemed to be in some odd state (it had a block size of 528) and can't get recognized by Linux's SCSI driver, I got it formatted with sg_format, turning it into a data disk with single partition on disk with ext4, and used it as the default download location for Deluge, my BitTorrent client. So far, so good.

Yet 146GB is damn too tight these days, and soon it got filled up. Yet, the first disk, which was completely used as the root drive, had around 130GB to spare. So is there a plan so that I can utilize all the free space on the two disks, say, to combine them into a big new pool?

The solution

Fortunately, LVM comes to the rescue. It's trivial to create empty files, set them up as loopback devices, and make them considered pv's by the system. Thanks to truncate, we can create files with big sizes, yet doesn't take up actual space.

Creating the filesystem

cd /
truncate pool_member.img -s 135G # won't consume disk space
losetup /dev/loop0 /pool_member.img
cd /var/lib/deluge # mountpoint for /dev/sdb1
truncate pool_member.img -s 135G # won't consume disk space
losetup /dev/loop1 /var/lib/deluge/pool_member.img
pvcreate /dev/loop0
pvcreate /dev/loop1
vgcreate data /dev/loop0 /dev/loop1
lvcreate -i 2 -l +100%FREE -n download data
mkfs.ext4 /dev/data/download
mkdir -p /pool
mount /dev/data/download /pool

Check with df -h and we can see that there's a brand new filesystem mounted there, taking space from the two drives. What I had to do next was simply moving the existing torrents over with Deluge's "Move Storage" feature.

Automatically mounting the LV

Wait a second. Even though the volume is up and running, it would be too much labor having to do it manually every time the system reboots. The following init script for OpenRC works well to solve this problem:

# Copyright 1999-2018 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2


wait_file() {
    local file="$1"; shift
    local wait_seconds="${1:-10}"; shift # 10 seconds as default timeout

    until test $((wait_seconds--)) -eq 0 -o -e "$file" ; do sleep 1; done


depend() {
    need localmount
    before net

start() {
    ebegin "Starting mount local disk pool"
    losetup /dev/loop0 /pool_member.img
    losetup /dev/loop1 /var/lib/deluge/pool_member.img
    einfo "Waiting for LV to appear..."
    wait_file "$lv_file" 5 || {
        eend 1 "LV did not show up after waiting for 5 seconds"
    mount /dev/data/download /pool
    eend $? "Failed to mount /pool"

stop() {
    ebegin "Stopping mount local disk pool"
    umount /pool
    vgchange -an /dev/data
    losetup -d /dev/loop0
    losetup -d /dev/loop1
    eend $? "Failed to unmount /pool"

Save it to /etc/init.d/disk-pool, give it +x permission, and add it to the default runlevel with

rc-update add disk-pool default


Credit for this method goes to lilydjwg. Thanks!


Personal details (portrait, CV) © Pengcheng Xu All Rights Reserved; articles licensed under CC BY-SA 4.0.
Powered by Pelican, Bootstrap, and NixOS. Icons by Font Awesome. Generated from 9c526f2.