Revert "Revert "oran-shell-release: release image for F""
[pti/rtp.git] / meta-starlingx / meta-stx-cloud / recipes-support / cluster-resource-agents / resource-agents / stx / lvm_cleanup_refs_on_stop.patch
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
5
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
8
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)
12
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
15 2 cases:
16
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.
20
21 * processes just hold/open dm block devices directly.  We need to kill
22 these processes.
23
24 Signed-off-by: Sun Austin <austin.sun@intel.com>
25 ---
26  heartbeat/LVM | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
27  1 file changed, 76 insertions(+)
28
29 diff --git a/heartbeat/LVM b/heartbeat/LVM
30 index 1efb207..bde381c 100755
31 --- a/heartbeat/LVM
32 +++ b/heartbeat/LVM
33 @@ -367,6 +367,81 @@ LVM_start() {
34  }
35  
36  #
37 +#    Kill provided process that holds lv
38 +#
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}
43 +  kill -s KILL ${1}
44 +}
45 +
46 +#
47 +#    Scan for processes that hold any lvs and kill them
48 +#
49 +scan_and_kill_processes_hold_lv() {
50 +  vg_name=${1}
51 +
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}')
59 +
60 +      lv_list="${lv_list}
61 +${lv_name}|${lv_block}"
62 +      lv_block_list="${lv_block_list} ${lv_block}"
63 +    fi
64 +  done
65 +
66 +  # Exit if there is no busy logical volume
67 +  [ -z "${lv_list}" ] && exit 0
68 +
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}')
74 +
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}"
83 +          done
84 +        fi
85 +        umount ${mount_point}
86 +        [ $? -ne 0 ] && ocf_log warn "Cannot umount ${mount_point}"
87 +      fi
88 +    done
89 +  done <<< "${mountinfo}"
90 +
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}')
96 +
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}))
100 +
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}"
105 +        fi
106 +      done
107 +    done
108 +  done
109 +}
110 +
111 +#
112  #      Disable the LVM volume
113  #
114  LVM_stop() {
115 @@ -395,6 +470,7 @@ LVM_stop() {
116                         break
117                 fi
118  
119 +               scan_and_kill_processes_hold_lv $vg
120                 res=$OCF_ERR_GENERIC
121                 ocf_log warn "$vg still Active"
122                 ocf_log info "Retry deactivating volume group $vg"
123 -- 
124 2.7.4
125