summaryrefslogtreecommitdiffstats
path: root/dev-tools/prepare-persistent-disks
blob: 2e68dd9ec09092414c9a45528d73fd38e09773c6 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
#!/bin/bash
###############################################################################
# GLOBALS
#

# flag file containing pids of running instances for concurrency checks
declare -rg OPENSLX_DISK_FLAG="/tmp/openslx.disk"
# file that will contain the name of the device used for the /tmp partition
# - label 'OPENSLX_TMP' in GPT / type '0x44' in MBR
declare -rg OPENSLX_TMP_MARKER="/tmp/openslx.disk.tmp"
# file that will contain the name of the device used for storing qcow2
# - label 'OPENSLX_SYS' in GPT / type '0x46' in MBR
declare -rg OPENSLX_SYS_MARKER="/tmp/openslx.disk.sys"
# mount point for system partition
declare -rg OPENSLX_SYS_MOUNT="/opt/openslx/system"

#
# END GLOBALS
###############################################################################

###############################################################################
# FUNCTION DEFINITIONS
#
# helper to mount the OPENSLX_SYS partition to /opt/openslx/system
# Usage: mount_sys_part <path_to_sys_partition>
mount_sys_part() {
	if [ ! -b "$1" ]; then
		warn "($$) Refusing to mount '$1' as its not a block device!"
		return 1
	fi

	local OPENSLX_SYS_DEVICE="$1"
	mkdir -p ${OPENSLX_SYS_MOUNT}
	if ! mount -t auto "${OPENSLX_SYS_DEVICE}" "${OPENSLX_SYS_MOUNT}"; then
		warn "($$) Mounting '${OPENSLX_SYS_DEVICE}' to '${OPENSLX_SYS_MOUNT}' failed."
		return 1
	fi
	return 0

}
#
# generic helper to format the given partition with the given filesystem or
# from the prefdefined list of xfs, ext4, ...
# Usage: format_disk <dev> <fs>
#  e.g.  format_disk /dev/sda1 xfs
format_disk () {
	local TARGET_DEVICE="$1"
	local fslist="xfs ext4"
	# if we have a second arguments, its the filesystem of choice
	local fs
	[ $# -ge 2 ] && fslist="$2"
	for fs in $fslist ; do
		unset found
		local MKFS="$(busybox which mkfs.$fs)"
		if [ -n $MKFS ]; then
			found=yes
			case "mkfs.$fs" in
				mkfs.xfs)   fopt="-fq"  ;;
				mkfs.ext4)  fopt="-Fq"  ;;
			esac
			info "($$) Formatting $TARGET_DEVICE as $fs"
			return $(${MKFS} ${fopt} "${TARGET_DEVICE}")
		fi
		[ -n "$found" ] && break
	done
	# still here? then we didn't find a proper formatter...
	warn "($$) Could not format $PART_DEV as $fs."
	return 1
}

#
# END FUNCTION DEFINITIONS
###############################################################################

###############################################################################
# MAIN CODE
#

command -v warn >/dev/null || . /lib/dracut-lib.sh

# let check the arguments
if [ "$#" -ne 2 ]; then
	warn "($$) '$0' need 2 arguments: '$0 [OPENSLX_SYS|OPENSLX_TMP] <dev_path>'"
	exit 1
fi
# $1 sane?
if [ "x$1" != "xOPENSLX_SYS" ] && [ "x$1" != "xOPENSLX_TMP" ]; then
	warn "($$) First arg needs to be either 'OPENSLX_SYS' or 'OPENSLX_TMP', given: $1"
	exit 1
fi
# $2 sane?
if [ ! -b "/dev/$2" ]; then
	warn "($$) Second arg appears not to be a block device!"
	exit 1
fi

# ok all seems well, set the arguments
PART_TYPE="$1"
PART_DEV="/dev/$2"

unset OPENSLX_TMP_DEVICE
unset OPENSLX_SYS_DEVICE

# lets check if we are already running
INSTANCES="$(grep "$PART_TYPE" "$OPENSLX_DISK_FLAG" | busybox wc -l)"
if [ "$INSTANCES" -ge 1 ]; then
	# uhoh we are not alone! Need to check
	# if the other instance actually did its job
	warn "($$) '$0' already running for $PART_TYPE on $PART_DEV... checking state."
	# here two/three cases depending on which PART_TYPE we are
	# currently processing.
	for timeout in 1 1 2; do
		# always give the other instance time to finish
		# but only check 3 times overall
		sleep $timeout
		case "$PART_TYPE" in
			OPENSLX_TMP)
				# was the tmp partition marker created with a device?
				if [ ! -f "${OPENSLX_TMP_MARKER}" ]; then
					info "($$) Invalid state: no marker for $PART_TYPE"
					continue
				fi
				# it was, is it a valid block device?
				OPENSLX_TMP_DEVICE="$(cat ${OPENSLX_TMP_MARKER})"
				if [ -z $OPENSLX_TMP_DEVICE -o ! -b $OPENSLX_TMP_DEVICE ]; then
					info "($$) Invalid state: no for device $OPENSLX_TMP_DEVICE"
					continue
				fi
				# its detected, its a block device and as mounting is
				# done later, we can not check for more at this point
				info "($$) Valid state for $OPENSLX_TMP_DEVICE as $PART_TYPE"
				exit 0
				;;
			OPENSLX_SYS)
				# was the system partition marker created with a device?
				if [ ! -f "${OPENSLX_SYS_MARKER}" ]; then
					info "($$) Invalid state: no marker for $PART_TYPE"
					continue
				fi
				# it was, is it a valid block device?
				OPENSLX_SYS_DEVICE="$(cat ${OPENSLX_SYS_MARKER})"
				if [ -z $OPENSLX_SYS_DEVICE -o ! -b $OPENSLX_SYS_DEVICE ]; then
					info "($$) Invalid state: no for device $OPENSLX_SYS_DEVICE"
					continue
				fi
				# its detected, its a block device, is it mounted?
				if mount | grep -qE "^$OPENSLX_SYS_DEVICE\ on $OPENSLX_SYS_MOUNT"; then
					info "($$) Valid state for $OPENSLX_SYS_DEVICE as $PART_TYPE"
					exit 0
				fi
				# if its not mounted, we want to keep on, so no exit!
				;;
			*)
				# weird case which should never happen
				warn "($$) If you see this, then $0 was called with a bad PART_TYPE: $@"
				continue
				;;
		esac
	done
	warn "($$) Timeout reached!"
	warn "($$) '$PART_TYPE' was found but not device was associated to it!"
fi

# We write our pid to $OPENSLX_DISK_FLAG in order to make sure
# we are the only instance of this script running.
info "($$) Processing: $PART_TYPE -> $PART_DEV ($$)"
echo "$PART_TYPE.$$" >> "$OPENSLX_DISK_FLAG"

# if we are still here, then we can go on and process the partition
if [ "$PART_TYPE" = "OPENSLX_TMP" ]; then
	# always format /tmp partition
	if ! format_disk "${PART_DEV}" xfs; then
		# error while formatting, cleanup
		warn "($$) Error formatting $PART_DEV ... removing $$"
		sed -i "/^${PART_TYPE}\.$$/d" "${OPENSLX_DISK_FLAG}"
		exit 1
	fi
	info "($$) Using '$PART_DEV' as '$PART_TYPE'"
	# mark it for later: in pre-pivot we will check this file
	# and mount it as $NEWROOT/tmp
	echo "$PART_DEV" > "$OPENSLX_TMP_MARKER"
	# remove our pid from OPENSLX_DISK_FLAG
	sed -i "/^${PART_TYPE}\.$$/d" "${OPENSLX_DISK_FLAG}"
	exit 0
fi
if [ "$PART_TYPE" = "OPENSLX_SYS" ]; then
	# TODO make the formatting of the system partition configurable
	if ! format_disk "${PART_DEV}" xfs; then
		# error while formatting, cleanup
		warn "($$) Error formatting $PART_DEV ... removing $$"
		sed -i "/^${PART_TYPE}\.$$/d" "${OPENSLX_DISK_FLAG}"
		exit 1
	fi
	# mark it
	# mount it now, since qemu-nbd needs it asap!
	if mount_sys_part "$PART_DEV"; then
		# mount worked, mark it as done
		info "($$) Using '$PART_DEV' as '$PART_TYPE'"
		echo "$PART_DEV" > "$OPENSLX_SYS_MARKER"
		sed -i "/^${PART_TYPE}\.$$/d" "${OPENSLX_DISK_FLAG}"
		exit 0
	else
		warn "($$) 'mount_sys_part' failed in $0"
		sed -i "/^${PART_TYPE}\.$$/d" "${OPENSLX_DISK_FLAG}"
		exit 1
	fi
fi

#
# END MAIN CODE
###############################################################################