1 From 72fcaed4a9cc3c847278dd4fca88ba0bca88125a Mon Sep 17 00:00:00 2001
2 From: Vu Tran <vu.tran@windriver.com>
3 Date: Thu Sep 29 19:07:25 2016 -0400
4 Subject: CGTS-5173: LVM ocf cleanup refs on stop
6 In LVM ocf script, LVM_stop() fails if any of the created logical volume
7 dm block devices are being held by any process with the following error
9 err ERROR: Logical volume cinder-volumes/volume-96a8becd-a1c1-4508-8b25-9bcbcfeff2fa
10 contains a filesystem in use. Can't deactivate volume group "cinder-volumes"
11 with 1 open logical volume(s)
13 So here we want to have defensive code to scan through any process that
14 holds what dm block devices and causes LVM_stop() to fail. There are
17 * dm block devices are mounted and processes are accessing files located
18 in this mount point. We first need to kill all the processes which are
19 opening files and then umount the dm block devices.
21 * processes just hold/open dm block devices directly. We need to kill
24 Signed-off-by: Sun Austin <austin.sun@intel.com>
26 heartbeat/LVM | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
27 1 file changed, 76 insertions(+)
29 diff --git a/heartbeat/LVM b/heartbeat/LVM
30 index 1efb207..bde381c 100755
33 @@ -367,6 +367,81 @@ LVM_start() {
37 +# Kill provided process that holds lv
39 +log_and_kill_process_hold_lv() {
40 + p_info=$(ps -lfLp ${1} | tail -1)
41 + ocf_log warn "lv ${2} is being held by this process (will be forced killed):"
42 + ocf_log warn ${p_info}
47 +# Scan for processes that hold any lvs and kill them
49 +scan_and_kill_processes_hold_lv() {
52 + # Get list of logical volumes which are busy
53 + lv_paths=$(lvdisplay -c ${vg_name} | awk -F ":" '{print $1}')
54 + for lv_path in ${lv_paths}; do
55 + open_num=$(lvdisplay ${lv_path} | grep "# open" | awk '{print $3}')
56 + if [ ${open_num} -gt 0 ]; then
57 + lv_name=$(lvdisplay ${lv_path} | grep "LV Name" | awk '{print $3}')
58 + lv_block=$(lvdisplay ${lv_path} | grep "Block device" | awk '{print $3}')
61 +${lv_name}|${lv_block}"
62 + lv_block_list="${lv_block_list} ${lv_block}"
66 + # Exit if there is no busy logical volume
67 + [ -z "${lv_list}" ] && exit 0
69 + # Checking to see if any of these busy logical volumes are caused by mount
70 + mountinfo=$(cat /proc/1/mountinfo)
71 + while read -r line; do
72 + mount_majorminor=$(echo ${line} | awk '{print $3}')
73 + mount_point=$(echo ${line} | awk '{print $5}')
75 + for lv in ${lv_block_list}; do
76 + if [ "${lv}" == "${mount_majorminor}" ]; then
77 + lv_name=$(echo "${lv_list}" | grep ${lv} | awk -F "|" '{print $1}')
78 + ocf_log warn "lv ${lv_name} is busy mounted at ${mount_point} (will be forced unmounted)"
79 + processes_holding_mount_point=$(fuser -m ${mount_point} 2>/dev/null)
80 + if [ -n "${processes_holding_mount_point}" ]; then
81 + for p in ${processes_holding_mount_point}; do
82 + log_and_kill_process_hold_lv "${p}" "${lv_name}"
85 + umount ${mount_point}
86 + [ $? -ne 0 ] && ocf_log warn "Cannot umount ${mount_point}"
89 + done <<< "${mountinfo}"
91 + # Now checking to see if any process holding these logical volumes
92 + all_processes=$(ps -e | awk '{print $1}')
93 + for p in ${all_processes}; do
94 + [ ! -d /proc/${p}/fd ] && continue
95 + opened_file_list=$(ls -l /proc/${p}/fd | awk -F "->" '{print $2}')
97 + for f in ${opened_file_list}; do
98 + [ ! -b "${f}" ] && continue
99 + f_majorminor=$(printf "%d:%d" $(stat -c '0x%t 0x%T' ${f}))
101 + for lv in ${lv_block_list}; do
102 + if [ "${lv}" == "${f_majorminor}" ]; then
103 + lv_name=$(echo "${lv_list}" | grep ${lv} | awk -F "|" '{print $1}')
104 + log_and_kill_process_hold_lv "${p}" "${lv_name}"
112 # Disable the LVM volume
115 @@ -395,6 +470,7 @@ LVM_stop() {
119 + scan_and_kill_processes_hold_lv $vg
121 ocf_log warn "$vg still Active"
122 ocf_log info "Retry deactivating volume group $vg"