Coverage for drivers/scsi_host_rescan.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# This module implements a safe way to rescan a scsi host so that:
19# - at any time there is at most 1 rescan happening on a system for a hostid
20# - we have as few rescans as possible
22import lock
23import util
24import os
25import time
26import glob
27from datetime import datetime
28from xmlrpc.client import DateTime
30HOST_LOCK_NAME_FORMAT = 'host%s'
31RESCAN_LOCK_NAME = 'rescan'
32START_TIME_FILE_PATH_FORMAT = '/var/run/host%s_starttime_%s'
35def _rescan_hostID(host):
36 util.SMlog("Performing rescan of host ID %s" % host)
37 path = '/sys/class/scsi_host/host%s/scan' % host
38 if os.path.exists(path):
39 try:
40 scanstring = "- - -"
41 f = open(path, 'w')
42 f.write('%s\n' % scanstring)
43 f.close()
44 # allow some time for undiscovered LUNs/channels to appear
45 time.sleep(2)
46 except Exception as e:
47 util.SMlog("Failed to perform full rescan of host: %s. " \
48 "Error: %s" % (host, str(e)))
49 raise Exception(str(e))
52def rescan(hostid):
53 try:
54 try:
55 # get the current time, call it x
56 curr_time = datetime.utcnow()
58 # acquire common lock
59 l = lock.Lock(RESCAN_LOCK_NAME, HOST_LOCK_NAME_FORMAT % hostid)
60 l.acquire()
62 while(1):
63 # check if starttime_anything exists
64 tryRescan = False
65 files = glob.glob(START_TIME_FILE_PATH_FORMAT % (hostid, '*'))
66 if len(files) == 0:
67 # if not, create starttime_x
68 path = START_TIME_FILE_PATH_FORMAT % (hostid, str(curr_time))
69 path = path.replace(' ', '_')
70 open(path, 'w').close()
72 # release common lock
73 l.release()
75 # perform host rescan
76 _rescan_hostID(hostid)
78 # acquire common lock
79 l.acquire()
81 # remove starttime_x
82 os.unlink(path)
84 # release common lock and exit
85 l.release()
86 break
87 else:
88 # if it does
89 # read the start time
90 start_time = files[0].split(START_TIME_FILE_PATH_FORMAT % (hostid, ''))[1]
91 start_time = DateTime(start_time.replace('__', ' '))
93 while(1):
94 # stick around till start_time exists
95 # drop common lock
96 l.release()
98 # sleep for a sec
99 time.sleep(1)
101 # acquire common lock
102 l.acquire()
104 # check if start time exists
105 if len(glob.glob(START_TIME_FILE_PATH_FORMAT % \
106 (hostid, '*'))) == 0:
107 tryRescan = False
108 if DateTime(str(curr_time)) < start_time:
109 # we are cool, this started before the rescan
110 # drop common lock and go home
111 l.release()
112 else:
113 # try to start a rescan
114 tryRescan = True
115 break
116 # else continue by default
118 if not tryRescan:
119 break
121 except Exception as e:
122 util.SMlog("Failed to perform rescan of host: %s. " \
123 "Error: %s" % (hostid, str(e)))
124 finally:
125 l.release()