summaryrefslogtreecommitdiffstats
path: root/core/modules/disk-partitions/data/opt/openslx/scripts/systemd-setup_partitions
diff options
context:
space:
mode:
Diffstat (limited to 'core/modules/disk-partitions/data/opt/openslx/scripts/systemd-setup_partitions')
-rwxr-xr-xcore/modules/disk-partitions/data/opt/openslx/scripts/systemd-setup_partitions272
1 files changed, 272 insertions, 0 deletions
diff --git a/core/modules/disk-partitions/data/opt/openslx/scripts/systemd-setup_partitions b/core/modules/disk-partitions/data/opt/openslx/scripts/systemd-setup_partitions
new file mode 100755
index 00000000..641ae372
--- /dev/null
+++ b/core/modules/disk-partitions/data/opt/openslx/scripts/systemd-setup_partitions
@@ -0,0 +1,272 @@
+#!/bin/bash
+# Arrays etc and $(( )) with big numbers
+# -----------------------------------------------------------------------------
+#
+# Copyright (c) 2018 bwLehrpool-Projektteam
+#
+# This program/file is free software distributed under the GPL version 2.
+# See https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
+#
+# If you have any feedback please consult https://bwlehrpool.de and
+# send your feedback to bwlehrpool@hs-offenburg.de.
+#
+# General information about bwLehrpool can be found at https://bwlehrpool.de
+#
+# -----------------------------------------------------------------------------
+#
+# Local hard disk autodetection script for OpenSLX linux stateless clients,
+# detecting swap and special partitions
+
+#############################################################################
+
+. /opt/openslx/bin/slx-tools
+
+# Mount point for persistent scratch partition (type 45)
+MOUNT_POINT_45="/opt/openslx/persistent"
+PARTITION_FILE="/run/openslx/partitions"
+readonly MOUNT_POINT_45 PARTITION_FILE
+mkdir -p "/run/openslx"
+
+declare -a TMPFILES
+gettmp () {
+ local vn file
+ for vn in "$@"; do
+ file=$(mktemp -p /run/openslx) # since we fiddle around with /tmp in this script
+ declare -g "${vn}=${file}"
+ TMPFILES+=("$file")
+ done
+}
+delalltmp () {
+ rm -f -- "${TMPFILES[@]}"
+}
+trap delalltmp EXIT
+
+# get_mount_options <fstype> <varname>
+get_mount_options () {
+ case "$1" in
+ ext2)
+ declare -ag "${2}=(-o nocheck)"
+ ;;
+ ext4)
+ declare -ag "${2}=(-o 'errors=remount-ro,data=ordered,relatime,quota')"
+ ;;
+ *)
+ declare -ag "${2}=()"
+ esac
+}
+
+# General formatter for the /tmp partition on a local harddisk
+format_disk () {
+ declare -ag MOUNT_OPTIONS_SET_BY_FORMAT_DISK=() # Global var!
+ local target="$1"
+ local fslist="xfs jfs ext3 ext2 ext4"
+ local fs
+ declare -a fopt
+ [ $# -ge 2 ] && fslist="$2"
+ for fs in $fslist ; do
+ if grep -q "\\b${fs}\\b" "/proc/filesystems"; then
+ # Filesystem already supported by running kernel
+ :
+ elif modprobe "${fs}"; then
+ # Filesystem module could be loaded and should be supported now
+ :
+ else
+ # Not supported, try next one
+ continue
+ fi
+ if which "mkfs.$fs" ; then
+ case "$fs" in
+ reiserfs)
+ fopt=("-f")
+ ;;
+ xfs)
+ fopt=("-f" "-K")
+ ;;
+ ext2|ext3)
+ fopt=("-F")
+ ;;
+ ext4)
+ fopt=(-F -b 4096 -O "extent,huge_file,flex_bg,metadata_csum,64bit,dir_nlink,extra_isize,quota" -E "nodiscard,quotatype=usrquota:prjquota" -I 256)
+ ;;
+ jfs)
+ fopt=()
+ ;;
+ *)
+ fopt=()
+ ;;
+ esac
+ get_mount_options "$fs" MOUNT_OPTIONS_SET_BY_FORMAT_DISK
+ "mkfs.$fs" "${fopt[@]}" "${target}" && return 0 # Success!
+ fi
+ done
+ return 1
+}
+
+wait_for_udev () {
+ local upid ctr hdd
+ hdd=
+ if [ "x$1" = "x--hdd" ]; then
+ hdd=true
+ shift
+ fi
+ ctr=$(( "$1" * 10 ))
+ if ! [ "$ctr" -gt 0 ]; then # Negation to catch NaN
+ ctr=1
+ fi
+ udevadm trigger &
+ usleep 20000 # 20ms
+ udevadm settle &> /dev/null & # --timeout doesn't work reliably, sometimes the process just hangs
+ upid=$!
+ while [ "$ctr" -gt 0 ]; do
+ [ -n "$hdd" ] && has_hdd && break
+ [ -z "$hdd" ] && ! [ -d "/proc/$upid" ] && break
+ usleep 100000 # 100ms
+ ctr=$(( ctr - 1 ))
+ done
+ if [ -d "/proc/$upid" ]; then
+ kill -9 "$upid" &> /dev/null &
+ fi
+}
+
+has_hdd () {
+ [ -n "$( ls -U -1 /dev/disk/by-path/ )" ]
+}
+
+wait_for_udev 2
+
+if ! has_hdd; then
+ wait_for_udev --hdd 4
+fi
+
+shopt -s extglob
+for disk in /dev/disk/by-path/!(*-part*|*-usb-*); do
+ [ -L "$disk" ] || continue
+ fdisk -l "$( readlink -f "$disk" )"
+done > "$PARTITION_FILE"
+shopt -u extglob
+if ! [ -s "$PARTITION_FILE" ]; then
+ echo "none" > "$PARTITION_FILE"
+fi
+echo "Partitions:"
+cat "$PARTITION_FILE"
+
+# Check for standard swap partitions and make them available to the system
+HAVE_SWAP=no
+for PART_DEV in $(dev_find_partitions "82" "0657fd6d-a4ab-43c4-84e5-0933c84b4f4f"); do
+ if swapon "$PART_DEV" -p 10; then
+ HAVE_SWAP=yes # low priority, in case we have zram swap, prefer that)
+ echo -e "$PART_DEV\tswap\t\tswap\t\tdefaults\t 0 0" >> "/etc/fstab"
+ fi
+done
+
+# Put detected linux partitions (83) into /etc/fstab with "noauto"
+for PART_DEV in $(dev_find_partitions "83"); do
+ mkdir -p "/media/${PART_DEV#/dev/*}"
+ echo -e "${PART_DEV}\t/media/${PART_DEV#/dev/*}\tauto\t\tnoauto,noexec\t 0 0" >> "/etc/fstab"
+done
+
+# special partition 45 (persistent scratch) to $MOUNT_POINT_45
+HAVE_PARTITION_45=no
+get_mount_options "ext4" mopts
+# try all the ID45 partitions until one succeeds, from large to small
+for PART_DEV in $(dev_find_partitions "45" "87f86132-ff94-4987-b250-454545454545"); do
+ mkdir -p "$MOUNT_POINT_45"
+ # Let's see if this is an ext4 partition and if so, whether it has the proper size
+ # Any fixing should happen first
+ gettmp "logfile"
+ COUNT=0
+ while true; do
+ [ "$COUNT" -ge 4 ] && break
+ let COUNT++
+ fsck.ext4 -y "$PART_DEV" &> "$logfile"
+ RET=$?
+ if [ "$(( RET & 7 ))" = 4 ]; then
+ slxlog "partition-45-fsck" "Error fixing file system errors on ID45 partition" "$logfile"
+ break
+ fi
+ [ "$(( RET & 3 ))" != 1 ] && break
+ done
+ # awk script to take block count and block size from dumpe2fs output and multiply them to get byte size
+ fs_size=$(dumpe2fs -h "$PART_DEV" | awk -F: 'BEGIN{a=0;b=0}{if ($1 == "Block count") a=$2; if($1 == "Block size") b=$2;}END{ if (a>0 && b>0) print a" * "b}' | bc)
+ echo "$PART_DEV has ext4 fs of size $fs_size"
+ if [ -n "$fs_size" ] && [ "$fs_size" -gt 1000000 ]; then
+ # It's ext4, see if partition size was changed offline
+ dev_size=$(blockdev --getsize64 "$PART_DEV")
+ echo "$PART_DEV has actual size of $dev_size"
+ if [ -n "$dev_size" ] && [ "$dev_size" -gt 1000000 ]; then
+ # somewhat sane, see what to do
+ dev_mb=$(( dev_size / 1024 / 1024 ))
+ fs_mb=$(( fs_size / 1024 / 1024 ))
+ echo "Dev: $dev_mb, fs: $fs_mb"
+ if [ "$(( fs_mb + 100 ))" -lt "$dev_mb" ]; then
+ # dev size plus 100MB is still smaller than reported fs size -- resize fs
+ gettmp "logfile"
+ fsck.ext4 -f -y "$PART_DEV" &> "$logfile"
+ if resize2fs "$PART_DEV" &>> "$logfile"; then
+ slxlog "partition-45-resize-ok" "Resized partition $PART_DEV from $fs_mb MiB to $dev_mb MiB" "$logfile"
+ else
+ slxlog "partition-45-resize-fail" "Could not enlarge file system size of $PART_DEV from $fs_mb MiB to $dev_mb MiB" "$logfile"
+ dd if=/dev/zero of="$PART_DEV" bs=1M count=1 &>/dev/null
+ fi
+ elif [ "$dev_size" -lt "$fs_size" ]; then
+ # partition is smaller than expected by fs -- killall
+ slxlog "partition-45-shrink" "$PART_DEV has ext4 file system which is $fs_mb MiB, but partition size is only $dev_mb MiB. Will wipe partition to be safe..."
+ dd if=/dev/zero of="$PART_DEV" bs=1M count=1 &>/dev/null
+ fi
+ fi
+ fi
+ # try to mount
+ if ! mount -v -t ext4 "${mopts[@]}" "${PART_DEV}" "$MOUNT_POINT_45"; then
+ # failed, try to format
+ gettmp "logfile"
+ if ! format_disk "$PART_DEV" "ext4" &> "$logfile"; then
+ slxlog "partition-45-format" "Cannot format $PART_DEV with ext4" "$logfile"
+ continue
+ fi
+ gettmp "logfile"
+ if ! mount -v -t ext4 "${mopts[@]}" "${PART_DEV}" "$MOUNT_POINT_45" &> "$logfile"; then
+ slxlog "partition-45-newmount" "Cannot mount $PART_DEV with ext4 right after formatting" "$logfile"
+ continue
+ fi
+ fi
+ # Mount success -- clean up lost+found
+ find "${MOUNT_POINT_45}/slx_lost+found" -mindepth 1 -maxdepth 1 -mtime +90 -type d -exec rm -rf -- {} \;
+ if [ -d "${MOUNT_POINT_45}/lost+found" ]; then
+ touch "${MOUNT_POINT_45}/lost+found"
+ mkdir -p "${MOUNT_POINT_45}/slx_lost+found"
+ mv -f -- "${MOUNT_POINT_45}/lost+found" "${MOUNT_POINT_45}/slx_lost+found/$(date +%s)_$$-$RANDOM"
+ fi
+ chmod 0700 "${MOUNT_POINT_45}/slx_lost+found"
+ chown 0:0 "${MOUNT_POINT_45}/slx_lost+found"
+ # fstab entry
+ echo -e "${PART_DEV}\t${MOUNT_POINT_45}\tauto\t\tnoauto\t\t 0 0" >> "/etc/fstab"
+ HAVE_PARTITION_45=yes
+ break # success, done
+done
+
+# and 46 to /media/devXX
+for PART_DEV in $(dev_find_partitions "46"); do
+ mkdir -p "/media/${PART_DEV#/dev/*}"
+ echo -e "${PART_DEV}\t/media/${PART_DEV#/dev/*}\tauto\t\tnoauto\t\t 0 0" >> "/etc/fstab"
+done
+
+# finally, prepare the data subdir on persistent part
+if [ "$HAVE_PARTITION_45" = "yes" ]; then
+ mkdir -p "$MOUNT_POINT_45/data"
+ chown root:root "$MOUNT_POINT_45" "$MOUNT_POINT_45/data"
+ chmod a+rwxt "$MOUNT_POINT_45/data"
+elif [ -d "$MOUNT_POINT_45" ]; then
+ rm -f -- "$MOUNT_POINT_45"
+fi
+
+mount -a
+
+if [ "$HAVE_SWAP" = "no" ]; then
+ TOTAL_RAM=$(grep ^MemTotal /proc/meminfo | awk '{print $2}')
+ if [ -n "$TOTAL_RAM" ] && [ "$TOTAL_RAM" -lt "3000000" ]; then
+ slxlog "partition-swap" "Have no (formatted) swap partition, using zram swap only!" "$PARTITION_FILE"
+ fi
+fi
+
+exit 0
+