Index: where-we-are
===================================================================
--- where-we-are (nonexistent)
+++ where-we-are (revision 5)
@@ -0,0 +1,272 @@
+#!/bin/bash
+
+program=`basename $0`
+sbindir=`cd $(dirname ${BASH_SOURCE[0]}) >/dev/null 2>&1 && pwd`
+
+# 14 = target device is not a partition
+# 15 = target device is not found
+EXITSTATUS=0
+
+usage() {
+ cat << EOF
+
+Usage: $program [options] [partition]
+
+options:
+ -o, --output <list> - output columns
+ -n, --no-header - output columns without header line
+
+ Available columns (for --output):
+
+ DISK device name of HW disk
+ ROOT device name of current ROOT partition
+ UUID filesystem UUID
+ MAJOR device major number
+ MINOR device minor number
+
+optional argument:
+
+ partition - If 'partition' is present then we assume that the 'partition'
+ is a root FS partition. In this case the $program do not try
+ to find working root FS partition.
+
+EOF
+}
+
+push_err() {
+ local message=$1
+ echo -n "$program: " 1>&2 ; echo "${message}" 1>&2
+}
+
+#
+# returns root partition device (such as /dev/part_name)
+#
+root_part() {
+ local dev=`findmnt --noheadings --raw / | tr -s ' ' | cut -f2 -d' '`
+ if [ "$dev" != "" ] ; then
+ echo "$dev"
+ return 0
+ fi
+}
+
+major_number() {
+ local part=$1
+ local name=`basename $part`
+
+ local major=`ls -l /dev | grep -v ^l | grep ${name} | tr -s ' ' | sed 's/,//g' | cut -f5 -d' ' | sort -u | tr '\n' ',' | sed 's/,$//'`
+ echo "${major}"
+}
+
+minor_number() {
+ local part=$1
+ local name=`basename $part`
+
+ local minor=`ls -l /dev | grep -v ^l | grep ${name} | tr -s ' ' | sed 's/,//g' | cut -f6 -d' ' | sort -u | tr '\n' ',' | sed 's/,$//'`
+ echo "${minor}"
+}
+
+#
+# returns root partition disk (such as /dev/disk_name)
+#
+root_disk_by_part() {
+ local part=$1
+ local mjrs=`major_number $1`
+ local disks="`lsblk -I ${mjrs} -l -o name,type | grep 'disk\|raid\|loop$' | cut -f1 -d' '`"
+ disks="`echo -e "$disks" | sort -r`"
+ for line in $disks ; do
+ local found=`echo "$part" | grep "$line"`
+ if [ "$found" != "" ] ; then
+ echo "/dev/$line"
+ break
+ fi
+ done
+}
+
+root_disk() {
+ local part=$1
+ local name=`basename $part`
+ local mjrs=`major_number $1`
+ echo "`lsblk -I ${mjrs} -l -o name,type`" | grep $name | while read -r line ; do
+ local type=`echo "$line" | tr -s ' ' | cut -f2 -d' '`
+ if [ "$type" = "part" ] ; then
+ root_disk_by_part $part
+ break
+ fi
+ done
+}
+
+#
+# returns root partition UUID (by /dev/part_name)
+#
+root_uuid() {
+ local part=`basename $1`
+ local mjrs=`major_number $1`
+ echo "`lsblk -I ${mjrs} -l -o name,uuid`" | while read -r line ; do
+ local pname=`echo "$line" | tr -s ' ' | cut -f 1 -d ' '`
+ local puuid=`echo "$line" | tr -s ' ' | cut -f 2 -d ' '`
+
+ if [ `echo "$pname" | grep "$part"` ] ; then
+ echo "$puuid"
+ break
+ fi
+ done
+}
+
+
+check_root_partition_device() {
+ local part=$1
+ local base=`basename $part`
+ local mjrs=`major_number $1`
+ line="`lsblk -I ${mjrs} -l -o name,type | grep \"$base \" | head -1 | tr -s ' '`"
+ if [ "$line" != "" ] ; then
+ local name=`echo "$line" | tr -s ' ' | cut -f1 -d' '`
+ local type=`echo "$line" | tr -s ' ' | cut -f2 -d' '`
+ if [ "$base" = "$name" ] && [ "$type" != "part" ] ; then
+ push_err "ERROR: The DEVICE ($part) is not a disk partition"
+ EXITSTATUS=14
+ exit $EXITSTATUS
+ fi
+ else
+ push_err "ERROR: The DEVICE ($part) not found"
+ EXITSTATUS=15
+ exit $EXITSTATUS
+ fi
+}
+
+
+#
+# Optional argument:
+#
+ROOT_PARTITION=
+
+#
+# Parse options:
+#
+HEADER="yes"
+OTPUTLIST="DISK,ROOT,UUID,MAJOR,MINOR"
+
+while [ 0 ] ; do
+ if [ "$1" = "-h" -o "$1" = "--help" ] ; then
+ usage
+ exit 0
+ elif [ "$1" = "-o" -o "$1" = "--output" ] ; then
+ if [ "$2" != "" ] ; then
+ OTPUTLIST="$2"
+ shift 2
+ else
+ shift 1
+ fi
+ elif [ "$1" = "-n" -o "$1" = "--no-header" ] ; then
+ HEADER="no"
+ shift 1
+ else
+ ROOT_PARTITION="$1"
+ break
+ fi
+done
+
+#
+# check optional partition (if present):
+#
+if [ "${ROOT_PARTITION}" != "" ] ; then
+ if [ ! `echo ${ROOT_PARTITION} | grep "^/dev.*"` ] ; then
+ push_err "ERROR: Wrong PARTITION device name: ${ROOT_PARTITION}"
+ usage
+ exit 1
+ fi
+ check_root_partition_device ${ROOT_PARTITION}
+fi
+
+
+################################################################
+# main()
+#
+
+#
+# root partition /dev/... :
+#
+if [ "${ROOT_PARTITION}" != "" ] ; then
+ root_part=${ROOT_PARTITION}
+else
+ root_part=`root_part`
+fi
+
+#
+# root phy disk /dev/... :
+#
+root_disk=`root_disk ${root_part}`
+
+#
+# root partition UUID :
+#
+root_uuid=`root_uuid ${root_part}`
+
+#
+# root partition device MAJOR number :
+#
+root_major=`major_number ${root_part}`
+
+#
+# root partition device MINOR number :
+#
+root_minor=`minor_number ${root_part}`
+
+
+if [ "$OTPUTLIST" != "" ] ; then
+ list=`echo $OTPUTLIST | sed 's/,/ /g' | tr '[:upper:]' '[:lower:]'`
+
+ if [ "$HEADER" = "yes" ] ; then
+
+ root_disk_len=${#root_disk}
+ root_part_len=${#root_part}
+ root_uuid_len=${#root_uuid}
+ root_major_len=${#root_major}
+ if [ ${root_major_len} -lt 5 ] ; then
+ root_major_len=5
+ fi
+ root_minor_len=${#root_minor}
+ if [ ${root_minor_len} -lt 5 ] ; then
+ root_minor_len=5
+ fi
+
+ out=""
+ for item in $list ; do
+ if [ "$item" = "disk" ] ; then
+ out="$out `printf '%-*s' ${root_disk_len} 'DISK'`"
+ elif [ "$item" = "root" ] ; then
+ out="$out `printf '%-*s' ${root_part_len} 'ROOT'`"
+ elif [ "$item" = "uuid" ] ; then
+ out="$out `printf '%-*s' ${root_uuid_len} 'UUID'`"
+ elif [ "$item" = "major" ] ; then
+ out="$out `printf '%-*s' ${root_major_len} 'MAJOR'`"
+ elif [ "$item" = "minor" ] ; then
+ out="$out `printf '%-*s' ${root_minor_len} 'MINOR'`"
+ fi
+ done
+ out=`echo "$out" | sed 's/^[ \t]*//;s/[ \t]*$//'`
+ echo "$out"
+ else
+ root_disk_len=${#root_disk}
+ root_part_len=${#root_part}
+ root_uuid_len=${#root_uuid}
+ root_major_len=${#root_major}
+ root_minor_len=${#root_minor}
+ fi
+
+ out=""
+ for item in $list ; do
+ if [ "$item" = "disk" ] ; then
+ out="$out `printf '%-*s' ${root_disk_len} ${root_disk}`"
+ elif [ "$item" = "root" ] ; then
+ out="$out `printf '%-*s' ${root_part_len} ${root_part}`"
+ elif [ "$item" = "uuid" ] ; then
+ out="$out `printf '%-*s' ${root_uuid_len} ${root_uuid}`"
+ elif [ "$item" = "major" ] ; then
+ out="$out `printf '%-*s' ${root_major_len} ${root_major}`"
+ elif [ "$item" = "minor" ] ; then
+ out="$out `printf '%-*s' ${root_minor_len} ${root_minor}`"
+ fi
+ done
+ out=`echo "$out" | sed 's/^[ \t]*//;s/[ \t]*$//'`
+ echo "$out"
+fi