#!/bin/sh # Copyright (C) 2011 Junjiro R. Okajima # # This program, aufs is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA verbose=0 if [ "$1" = -v ] then verbose=1 shift fi test $# -ne 2 && { echo Invalid argument echo Usage: $(basename $0) '[-v]' aufs_mntpnt branch_path echo '\tprint PIDs which make the branch busy and un-removable.' echo '\t-v prints additional information, the inode number in aufs,' echo '\tthe branch index, and the actual inode number on that branch.' } 1>&2 && exit 1 set -eu f=/etc/default/aufs test ! -e $f && echo $f is not installed 1>&2 && exit 1 . $f mntent=$(FindMntEnt "$1") test ! "$mntent" && echo No such aufs mount point "$1" 1>&2 && exit 1 mntpnt=$(echo $mntent | cut -f2 -d' ') SetDir br "$2" mntopts=$(MntOpts "$1") si=$(echo $mntopts | sed -e 's/^.*,si=\([^,]*\),*.*$/\1/') d=/sys/fs/aufs/si_$si if [ -r $d/br0 ] then # it may be very long and shell may not be able to handle as wildcard bindex=$(find $d -name 'br*' | xargs -r grep -l "^${br}=" | xargs -r basename | cut -c3-) else bi=$(echo $mntpopts | sed -e 's/^.*,br://' | tr ':' '\n' | rev | cut -f2- -d= | rev | grep -n "^${br}=" | cut -f1 -d:) # the origin in aufs is zero. bindex=$(($bi - 1)) fi ######################################## # here we go lsof -FDiR "$mntpnt" | awk -v g_ppid=$$ \ -v g_dev=$(stat -c %D "$mntpnt") \ -v root=$AUFS_ROOT_INO \ ' function pr() { if (inum) { print pid, inum; inum = ""; } } /^p/ { pr(); pid = substr($0, 2); do_print = 1; next; } /^R/ { ppid = substr($0, 2); if (ppid == g_ppid) do_print = 0; next; } /^D/ { dev = substr($0, 4); if (dev != g_dev) do_print = 0; next; } /^i/ && do_print { n = substr($0, 2); if (n != root) inum = inum " " n; } END { pr(); } ' | #tee /dev/tty | while read pid ino do # it may be very long and shell may not be able to handle as parameters echo "$ino" | xargs -r auibusy "$mntpnt" $bindex | { if [ $verbose -eq 1 ] then sed -e s/^/$pid' /' else test $(wc -c) -ne 0 && echo $pid fi } done | uniq