Coverage for drivers/verifyVDIsOnSR.py : 0%
Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1#!/usr/bin/python3
2#
3# Copyright (C) Citrix Systems Inc.
4#
5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU Lesser General Public License as published
7# by the Free Software Foundation; version 2.1 only.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU Lesser General Public License for more details.
13#
14# You should have received a copy of the GNU Lesser General Public License
15# along with this program; if not, write to the Free Software Foundation, Inc.,
16# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17#
18# Tool to check all COW-based VDIs (VHD, QCOW2) belonging to a VG/SR.
19# Usage is "./verifyVDIsOnSR.py <sr_uuid>". This tool verifies all the VDIs
20# on a COW-based LVM SR. (FC or iSCSI)
21#
23import os
24import sys
25import util
26import lvutil
29from constants import NS_PREFIX_LVM, VG_LOCATION, VG_PREFIX
30from cowutil import getCowUtil
31from lock import Lock
32from lvmcowutil import LV_PREFIX, LvmCowUtil
33from refcounter import RefCounter
34from vditype import VDI_COW_TYPES
36# Stores the vdi activated, comes handy while deactivating
37VDIs_passed = 0
38VDIs_failed = 0
41def activateVdiChainAndCheck(cowutil, image_info, vg_name):
42 global VDIs_passed
43 global VDIs_failed
44 activated_list = []
45 vdi_path = os.path.join(VG_LOCATION, vg_name, image_info.path)
46 sr_uuid = vg_name[len(VG_PREFIX):]
47 if not activateVdi(
48 sr_uuid,
49 image_info.uuid,
50 vdi_path):
51 # If activation fails, do not run check, also no point on running
52 # check on the VDIs down the chain
53 util.SMlog("VDI activate failed for %s, skipping rest of VDI chain" %
54 vg_name)
55 return activated_list
57 activated_list.append([image_info.uuid, vdi_path])
59 # Do a vhdutil check with -i option, to ignore error in primary
60 if cowutil.check(vdi_path, True) != cowutil.CheckResult.Success:
61 util.SMlog("VDI check for %s failed, continuing with the rest!" % vg_name)
62 VDIs_failed += 1
63 else:
64 VDIs_passed += 1
66 if hasattr(image_info, 'children'):
67 for image_info_sub in image_info.children:
68 activated_list.extend(activateVdiChainAndCheck(cowutil, image_info_sub, vg_name))
70 return activated_list
73def activateVdi(sr_uuid, vdi_uuid, vdi_path):
74 name_space = NS_PREFIX_LVM + sr_uuid
75 lock = Lock(vdi_uuid, name_space)
76 lock.acquire()
77 try:
78 count = RefCounter.get(vdi_uuid, False, name_space)
79 if count == 1:
80 try:
81 lvutil.activateNoRefcount(vdi_path, False)
82 except Exception as e:
83 util.SMlog(" lv activate failed for %s with error %s" %
84 (vdi_path, str(e)))
85 RefCounter.put(vdi_uuid, False, name_space)
86 return False
87 finally:
88 lock.release()
90 return True
93def deactivateVdi(sr_uuid, vdi_uuid, vdi_path):
94 name_space = NS_PREFIX_LVM + sr_uuid
95 lock = Lock(vdi_uuid, name_space)
96 lock.acquire()
97 try:
98 count = RefCounter.put(vdi_uuid, False, name_space)
99 if count > 0:
100 return
101 try:
102 lvutil.deactivateNoRefcount(vdi_path)
103 except Exception as e:
104 util.SMlog(" lv de-activate failed for %s with error %s" %
105 (vdi_path, str(e)))
106 RefCounter.get(vdi_uuid, False, name_space)
107 finally:
108 lock.release()
111def checkAllVDI(sr_uuid):
112 activated_list = []
113 VDIs_total = 0
115 vg_name = VG_PREFIX + sr_uuid
116 for vdi_type in VDI_COW_TYPES:
117 vdi_trees = []
118 pattern = "%s*" % LV_PREFIX[vdi_type]
120 cowutil = getCowUtil(vdi_type)
121 vdis = cowutil.getAllInfoFromVG(pattern, LvmCowUtil.extractUuid, vg_name)
122 VDIs_total += len(vdis)
124 # Build VDI chain, that way it will be easier to activate all the VDIs
125 # that belong to one chain, do check on the same and then deactivate
126 for vdi in vdis:
127 if vdis[vdi].parentUuid:
128 parent_VDI_info = vdis.get(vdis[vdi].parentUuid)
129 if not hasattr(parent_VDI_info, 'children'):
130 parent_VDI_info.children = []
131 parent_VDI_info.children.append(vdis[vdi])
132 else:
133 vdi_trees.append(vdis[vdi])
135 # If needed, activate VDIs belonging to each VDI chain, do a check on
136 # all VDIs and then set the state back.
137 for vdi_chain in vdi_trees:
138 activated_list = activateVdiChainAndCheck(cowutil, vdi_chain, vg_name)
140 #Deactivate the LVs, states are maintained by Refcounter
141 for item in activated_list:
142 deactivateVdi(sr_uuid, item[0], item[1])
144 print("VDIs check passed on %d, failed on %d, not run on %d" %
145 (VDIs_passed, VDIs_failed, VDIs_total - (VDIs_passed + VDIs_failed)))
147if __name__ == '__main__':
148 if len(sys.argv) == 1:
149 print("Usage:")
150 print("/opt/xensource/sm/verifyVDIsOnSR.py <sr_uuid>")
151 else:
152 checkAllVDI(sys.argv[1])