#!/bin/sh

# This script sets method "lvm" for all partitions that have the lvm
# flag set.  It also discovers the logical volumes and creates in them
# a loop partition table and partition.

. /lib/partman/lib/base.sh
. /lib/partman/lib/lvm-base.sh

# Avoid warnings from lvm2 tools about open file descriptors
export LVM_SUPPRESS_FD_WARNINGS=1

if [ -x /sbin/vgdisplay ]; then
	vgroups=$(/sbin/vgdisplay 2>/dev/null | grep '^[ ]*VG Name' | \
		sed -e 's/.*[[:space:]]\(.*\)$/\1/' | sort)
else
	vgroups=''
fi

for dev in /var/lib/partman/devices/*; do
	[ -d "$dev" ] || continue
	cd $dev
	partitions=
	open_dialog PARTITIONS
	while { read_line num id size type fs path name; [ "$id" ]; }; do
		if [ "$fs" != free ]; then
			partitions="$partitions $id,$path"
		fi
	done
	close_dialog

	# Check if device/partitions are used for LVM (PV)
	for part in $partitions; do
		set -- $(IFS=, && echo $part)
		id=$1
		path=$2
		lvm=

		# If the device is in fact being used for lvm, mark it as such.
		# This is a hack and it only works for full block devices, not
		# partitions. It makes raid devices used for lvm show up as such.
		if pvdisplay $(cat $dev/device) >/dev/null 2>&1 ; then
			lvm=1
		else
			open_dialog GET_FLAGS $id
			while { read_line flag; [ "$flag" ]; }; do
				if [ "$flag" = lvm ]; then
					lvm=1
					# can not break here
				fi
			done
			close_dialog
		fi
		if [ "$lvm" ]; then
			mkdir -p $id
			echo lvm >$id/method

			if ! [ -e $id/locked ]; then
				vg=$(pv_get_vg $path)
				for vgs in $vgroups; do
					if [ "$vg" = "$vgs" ]; then
						vg_lock_pvs $vg $path
					fi
				done
			fi
		fi
	done

	# Check if device is a logical volume
	if [ -f device ]; then
		# Obtain the VG from the device name
		device=$(cat device)
		case "$device" in
		    # LVM2
		    /dev/mapper/*)
			vglv=${device#/dev/mapper/}
			vglv=$(echo "$vglv" | sed -e 's/\([^-]\)-\([^-]\)/\1 \2/' |
			       sed -e 's/--/-/g')
			vg=$(echo "$vglv" | cut -d" " -f1)
			;;
		    # LVM1
		    *)
			vg=$(sed 's,^/[^/]*/\([^/]*\)/.*,\1,' device)
			;;
		esac
		is_lv=
		for vgs in $vgroups; do
			[ ! "$vgs" = "$vg" ] || is_lv=1
		done

		# If this is a new logical volume
		if [ "$is_lv" ] && [ -z "$partitions" ]; then
			# create a label
			open_dialog NEW_LABEL loop
			close_dialog
			# find the free space
			open_dialog PARTITIONS
			free_space=''
			while { read_line num id size type fs path name; [ "$id" ]; }; do
				case $fs in
				    free|unknown)
					free_space=$id
					free_size=$size
					free_fs=$fs
					;;
				esac
			done
			close_dialog
			# create partition in the free space
			if [ "$free_space" ]; then
				id=
				if [ "$free_fs" = unknown ]; then
					# parted >= 3.2 gives us a partition
					# automatically.
					id=$free_space
				else
					# With parted < 3.2 we must create a
					# partition manually.
					open_dialog NEW_PARTITION primary ext2 $free_space full $free_size
					read_line num id size type fs path name
					close_dialog
				fi
				if [ "$id" ]; then
					open_dialog GET_FILE_SYSTEM $id
					read_line filesystem
					close_dialog
					if [ "$filesystem" != none ]; then
						open_dialog CHANGE_FILE_SYSTEM $id $filesystem
						close_dialog
					fi
				fi
			fi
			open_dialog DISK_UNCHANGED
			close_dialog
		fi
	fi
done
