#!/bin/bash

# 06/05/2014, author: Maxim Suhanov

#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 2 of the License, or
#    (at your option) any later version.

#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.

#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.

list_volumes()
{
	blkid -o device | grep -vE '^/dev/loop([[:digit:]]+|/.*)$'
}

list_loops()
{
	blkid -o device | grep -E '^/dev/loop([[:digit:]]+|/.*)$'
}

get_type()
{
	blkid -o value -s TYPE "$1"
}

lo_setup()
{
	loopinfo=`losetup -j "$1"`
	if [ -z "$loopinfo" ]; then
		losetup -r -f "$1" 2> /dev/null # Do not remove "-r"!
		if [ $? != 0 ]; then
			echo "Cannot setup loop device! $1 will be ignored..."
		fi
	else
		echo "$1 is already on loop device!"
	fi
}

lvm_config='
config {
    checks = 1
    abort_on_errors = 0
    profile_dir = "/etc/lvm/profile"
}
devices {
    dir = "/dev"
    scan = [ "/dev" ]
    obtain_device_list_from_udev = 1
    preferred_names = [ ]
    filter = [ "a/^/dev/loop/", "r/.*/" ] # Use loop devices only!
    cache_dir = "/run/lvm"
    cache_file_prefix = ""
    write_cache_state = 1
    sysfs_scan = 1
    multipath_component_detection = 1
    md_component_detection = 1
    md_chunk_alignment = 1
    data_alignment_detection = 1
    data_alignment = 0
    data_alignment_offset_detection = 1
    ignore_suspended_devices = 0
    ignore_lvm_mirrors = 1
    disable_after_error_count = 0
    require_restorefile_with_uuid = 1
    pv_min_size = 2048
    issue_discards = 0
}
allocation {
    maximise_cling = 1
    mirror_logs_require_separate_pvs = 0
    thin_pool_metadata_require_separate_pvs = 0
}
log {
    verbose = 0
    silent = 0
    syslog = 1
    overwrite = 0
    level = 0
    indent = 1
    command_names = 0
    prefix = "  "
    debug_classes = [ "memory", "devices", "activation", "allocation",
		      "lvmetad", "metadata", "cache", "locking" ]
}
backup {
    backup = 1
    backup_dir = "/etc/lvm/backup"
    archive = 1
    archive_dir = "/etc/lvm/archive"
    retain_min = 10
    retain_days = 30
}
shell {
    history_size = 100
}
global {
    umask = 077
    test = 0
    units = "h"
    si_unit_consistency = 1
    activation = 1
    proc = "/proc"
    locking_type = 1
    wait_for_locks = 1
    fallback_to_clustered_locking = 1
    fallback_to_local_locking = 1
    locking_dir = "/run/lock/lvm"
    prioritise_write_locks = 1
    abort_on_internal_errors = 0
    detect_internal_vg_cache_corruption = 0
    metadata_read_only = 0
    mirror_segtype_default = "raid1"
    raid10_segtype_default = "raid10"
    use_lvmetad = 0
}
activation {
    checks = 0
    udev_sync = 1
    udev_rules = 1
    verify_udev_operations = 0
    retry_deactivation = 1
    missing_stripe_filler = "error"
    use_linear_target = 1
    reserved_stack = 64
    reserved_memory = 8192
    process_priority = -18
    raid_region_size = 512
    readahead = "auto"
    raid_fault_policy = "warn"
    mirror_log_fault_policy = "allocate"
    mirror_image_fault_policy = "remove"
    snapshot_autoextend_threshold = 100
    snapshot_autoextend_percent = 20
    thin_pool_autoextend_threshold = 100
    thin_pool_autoextend_percent = 20
    use_mlockall = 0
    monitoring = 0
    polling_interval = 15
}
dmeventd {
    mirror_library = "libdevmapper-event-lvm2mirror.so"
    snapshot_library = "libdevmapper-event-lvm2snapshot.so"
    thin_library = "libdevmapper-event-lvm2thin.so"
}
'

activate_lvm()
{
	for volume in `list_volumes`; do
		volume_type=`get_type "$volume"`
		if [ `echo "$volume_type" | grep '^LVM2_member$'` ]; then
			lo_setup "$volume"
		fi
	done

	echo "Running 'vgscan'..."; vgscan --config "$lvm_config"
	echo "Running 'vgchange -a y'..."; vgchange --config "$lvm_config" -a y
	echo "Running 'lvdisplay'..."; lvdisplay --config "$lvm_config"
	echo "Running 'vgdisplay'..."; vgdisplay --config "$lvm_config"
	echo "Running 'pvdisplay'..."; pvdisplay --config "$lvm_config"
	echo "Note:"
	echo "	Execute '$0 stop' to deactivate LVM!"
}

deactivate_lvm()
{
	echo "Running 'vgchange -a n'..."; vgchange --config "$lvm_config" -a n
	echo "Deleting loop devices..."
	for volume in `list_loops`; do
		volume_type=`get_type "$volume"`
		if [ `echo "$volume_type" | grep '^LVM2_member$'` ]; then
			losetup -d "$volume"
		fi
	done
}

if [ -z "$1" ] || [ "$1" == 'start' ]; then
	activate_lvm
elif [ "$1" == 'stop' ]; then
	deactivate_lvm
else
	echo "Usage: $0 [start|stop]" >&2
	exit 1
fi
