#!/bin/bash
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
# ex: ts=8 sw=4 sts=4 et filetype=sh

# This script implements systemd-fstab-generator's add_root_mount()
# function but for handling usr= cmdline args instead of root=
# TODO(marineam): Write a patch to do this in systemd-fstab-generator
#
# grub passes mount.usr= instead of usr=, and mount.usr= is handled
# by systemd-fstab-generator. This module is only needed for old
# bootloaders that pass usr=.

set -e

UNIT_DIR="${1:-/tmp}"

# env var for testing
if [[ -n "${USR_GENERATOR_CMDLINE}" ]]; then
    cmdline=( ${USR_GENERATOR_CMDLINE} )
else
    cmdline=( $(</proc/cmdline) )
fi

# Usage: cmdline_arg name default_value
cmdline_arg() {
    local name="$1" value="$2"
    for arg in "${cmdline[@]}"; do
        if [[ "${arg%%=*}" == "${name}" ]]; then
            value="${arg#*=}"
        fi
    done
    echo "${value}"
}

usr=$(cmdline_arg usr)
usrfstype=$(cmdline_arg usrfstype auto)
usrflags=$(cmdline_arg usrflags ro)
if [[ "$(echo ",${usrflags}," | grep -v -F ',ro,')" != "" ]]; then
  true # Don't set "norecovery" when mounting rw
else
  usrflags="${usrflags},norecovery"
fi

case "${usr}" in
    LABEL=*)
        usr="$(echo $usr | sed 's,/,\\x2f,g')"
        usr="/dev/disk/by-label/${usr#LABEL=}"
        ;;
    UUID=*)
        usr="${usr#UUID=}"
        usr="$(echo $usr | tr "[:upper:]" "[:lower:]")"
        usr="/dev/disk/by-uuid/${usr}"
        ;;
    PARTUUID=*)
        usr="${usr#PARTUUID=}"
        usr="$(echo $usr | tr "[:upper:]" "[:lower:]")"
        usr="/dev/disk/by-partuuid/${usr}"
        ;;
    PARTLABEL=*)
        usr="/dev/disk/by-partlabel/${usr#PARTLABEL=}"
        ;;
esac

# Only proceed if the source is a path.
if [[ "${usr}" != /* ]]; then
  # Here "$usr" does not contain the values of "mount.usr", hence the extra check not found in diskless-generator/ignition-generator
  if [[ -z "${usr}" && -z "$(cmdline_arg mount.usr)" && -f /usr.squashfs ]]; then
    # Don't set "norecovery" for squashfs
    exit 0
  fi
  # Add "norecovery" to systemd-fstab-generator's unit and exit
  mount_usrflags=$(cmdline_arg mount.usrflags ro)
  if [[ "$(echo ",${mount_usrflags}," | grep -v -F ',ro,')" != "" ]]; then
    # Don't set "norecovery" when mounting rw
    exit 0
  fi
  mount_usrflags="${mount_usrflags},norecovery"
  # sysroot-usr.mount is a bind mount from /sysusr/usr
  mkdir -p "${UNIT_DIR}/sysusr-usr.mount.d"
  cat >"${UNIT_DIR}/sysusr-usr.mount.d/10-norecovery.conf" <<EOF
[Unit]
DefaultDependencies=no
Wants=systemd-tmpfiles-setup-dev-early.service
After=systemd-udevd.service systemd-tmpfiles-setup-dev-early.service
[Mount]
Options=${mount_usrflags}
EOF
  exit 0
fi

cat >"${UNIT_DIR}/sysroot-usr.mount" <<EOF
# Automatically generated by usr-generator

[Unit]
SourcePath=/proc/cmdline
Before=initrd-root-fs.target
Wants=remount-sysroot.service
After=remount-sysroot.service

[Mount]
What=${usr}
Where=/sysroot/usr
Type=${usrfstype}
Options=${usrflags}
EOF

requires_dir="${UNIT_DIR}/initrd-root-fs.target.requires"
mkdir -p "${requires_dir}"
ln -sf "../sysroot-usr.mount" "${requires_dir}/sysroot-usr.mount"

cat >"${UNIT_DIR}/sysusr-usr.mount" <<EOF
# Automatically generated by usr-generator

[Unit]
SourcePath=/proc/cmdline
Conflicts=initrd-switch-root.target
DefaultDependencies=no
Wants=systemd-tmpfiles-setup-dev-early.service
After=systemd-udevd.service systemd-tmpfiles-setup-dev-early.service

[Mount]
What=${usr}
Where=/sysusr/usr
Type=${usrfstype}
Options=${usrflags}
EOF