summarylogtreecommitdiffstats
path: root/device-mapper.initd
diff options
context:
space:
mode:
Diffstat (limited to 'device-mapper.initd')
-rw-r--r--device-mapper.initd146
1 files changed, 146 insertions, 0 deletions
diff --git a/device-mapper.initd b/device-mapper.initd
new file mode 100644
index 00000000000..dd4ec76e449
--- /dev/null
+++ b/device-mapper.initd
@@ -0,0 +1,146 @@
+#!/usr/bin/openrc-run
+# Copyright 1999-2016 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+depend() {
+ # As of .67-r1, we call ALL lvm start/stop scripts with --sysinit, that
+ # means dmeventd is NOT notified, as it cannot be safely running
+ before dmeventd checkfs fsck
+ after modules
+}
+
+dm_in_proc() {
+ local retval=0
+ for x in devices misc ; do
+ grep -qs 'device-mapper' /proc/${x}
+ retval=$((${retval} + $?))
+ done
+ return ${retval}
+}
+
+# char **build_dmsetup_command(volume)
+#
+# Returns complete dmsetup command given single volume name
+build_dmsetup_command() {
+ local count dmsetup_cmd
+
+ # Number of lines mentioning volume name
+ count=$(grep -v -e '^[[:space:]]*\(#\|$\)' /etc/dmtab | grep -c ${1})
+
+ # If there's just one line:
+ if [ ${count} -eq 1 ] ; then
+ echo "echo $(grep -v -e '^[[:space:]]*\(#\|$\)' /etc/dmtab | \
+ grep ${1} | awk '{$1=""; print $0}') | /usr/bin/dmsetup create ${1}"
+
+ # For all cases with more lines:
+ elif [ ${count} -gt 1 ] ; then
+ for c in $( seq 1 ${count} ) ; do
+ if [ ${c} -eq 1 ] ; then
+ # Heavy escaping in awk-statement because we cannot use apostrophes
+ dmsetup_cmd="echo -e $(grep -v -e '^[[:space:]]*\(#\|$\)' /etc/dmtab | \
+ grep ${1} | awk NR==${c}\ \{\$1=\"\"\;\ print\ \$0\})"
+ else
+ # Append starting with newline
+ dmsetup_cmd="${dmsetup_cmd}\\\\n \
+ $(grep -v -e '^[[:space:]]*\(#\|$\)' /etc/dmtab | \
+ grep ${1} | awk NR==${c}\ \{\$1=\"\"\;\ print\ \$0\})"
+ fi
+ done
+ echo "${dmsetup_cmd} | /usr/bin/dmsetup create ${1}"
+ fi
+
+ return 0
+}
+
+# char **get_new_dm_volumes(void)
+#
+# Return unique volumes from /etc/dmtab
+get_new_dm_volumes() {
+ local volume
+
+ # Filter comments and blank lines
+ grep -v -e '^[[:space:]]*\(#\|$\)' /etc/dmtab | \
+ awk '{ print $1 }' | \
+ uniq | \
+ while read volume ; do
+ # If it exists, skip it
+ dmvolume_exists "${volume%:}" && continue
+
+ echo "${volume%:}"
+ done
+
+ return 0
+}
+
+# int dmvolume_exists(volume)
+#
+# Return true if volume exists in DM table
+dmvolume_exists() {
+ local x line volume=$1
+
+ [ -z "${volume}" ] && return 1
+
+ /usr/bin/dmsetup ls 2>/dev/null | \
+ while read line ; do
+ for x in ${line} ; do
+ # the following conditonal return only breaks out
+ # of the while loop, as it is running in a pipe.
+ [ "${x}" = "${volume}" ] && return 1
+ # We only want to check the volume name
+ break
+ done
+ done
+
+ # if 1 was returned from the above loop, then indicate that
+ # volume exists
+ [ $? = 1 ] && return 0
+
+ # otherwise the loop exited normally and the volume does not
+ # exist
+ return 1
+}
+
+# int is_empty_dm_volume(volume)
+#
+# Return true if the volume exists in DM table, but is empty/non-valid
+is_empty_dm_volume() {
+ local table volume=$1
+
+ set -- $(/usr/bin/dmsetup table 2>/dev/null | grep -e "^${volume}:")
+ [ "${volume}" = "$1" -a -z "$2" ]
+}
+
+
+start() {
+ if [ -e /proc/modules ] && ! dm_in_proc ; then
+ modprobe dm-mod 2>/dev/null
+ fi
+ # Ensure the dirs exist for locking and running
+ checkpath -q -d -m 0700 -o root:root /run/lvm /run/lock/lvm
+
+ local x volume
+
+ if [ -x /usr/bin/dmsetup -a -c /dev/mapper/control -a -f /etc/dmtab ] ; then
+ [ -n "$(get_new_dm_volumes)" ] && \
+ einfo " Setting up device-mapper volumes:"
+
+ get_new_dm_volumes | \
+ while read x ; do
+ [ -n "${x}" ] || continue
+
+ volume="${x##* }"
+
+ ebegin " Creating volume: ${volume}"
+ if ! eval $(build_dmsetup_command ${volume}) >/dev/null 2>/dev/null ; then
+ eend 1 " Error creating volume: ${volume}"
+ # dmsetup still adds an empty volume in some cases,
+ # so lets remove it
+ is_empty_dm_volume "${volume}" && \
+ /usr/bin/dmsetup remove "${volume}" 2>/dev/null
+ else
+ eend 0
+ fi
+ done
+ fi
+}
+