#!/bin/bash -f # SPDX-License-Identifier: GPL-2.0 # # Copyright (c) 2024 Oracle. All Rights Reserved. # Author: Darrick J. Wong # OPTS="" USAGE="Usage: xfs_property [-V] [mountpoint|device|file] [list [-v]|get name...|set name=value...|remove name...]" # Try to find a loop device associated with a file. We only want to return # one loopdev (multiple loop devices can attach to a single file) so we grab # the last line and return it if it's actually a block device. try_find_loop_dev_for_file() { local x="$(losetup -O NAME -j "$1" 2> /dev/null | tail -n 1)" test -b "${x}" && echo "${x}" } while getopts "V" c do case $c in V) xfs_io -p xfs_info -V status=$? exit ${status} ;; *) echo "${USAGE}" 1>&2 exit 2 ;; esac done set -- extra "$@" shift $OPTIND if [ $# -lt 2 ]; then echo "${USAGE}" 1>&2 exit 2 fi target="$1" shift subcommand="$1" shift db_args=() io_args=() case "$subcommand" in "list") vparam= if [ $# -eq 1 ] && [ "$1" = "-v" ]; then vparam=" -v" fi db_args+=('-c' "attr_list -Z${vparam}") io_args+=('-c' "listfsprops${vparam}") ;; "get"|"remove"|"set") for arg in "$@"; do db_args+=('-c' "attr_${subcommand} -Z ${arg/=/ }") io_args+=('-c' "${subcommand}fsprops ${arg}") done ;; *) echo "${USAGE}" 1>&2 exit 2 esac # See if we can map the arg to a loop device loopdev="$(try_find_loop_dev_for_file "${target}")" test -n "${loopdev}" && target="${loopdev}" # If we find a mountpoint for the device, do a live query; otherwise try # reading the fs with xfs_db. if mountpt="$(findmnt -t xfs -f -n -o TARGET "${target}" 2> /dev/null)"; then exec xfs_io -p xfs_property "${io_args[@]}" "${mountpt}" else exec xfs_db -p xfs_property -x -c 'path /' "${db_args[@]}" "${target}" fi