def scan_srlist(path, dconf): """Scan and report SR, UUID.""" dom = xml.dom.minidom.Document() element = dom.createElement("SRlist") dom.appendChild(element) for val in filter(util.match_uuid, util.ioretry( lambda: util.listdir(path))): fullpath = os.path.join(path, val) if not util.ioretry(lambda: util.isdir(fullpath)): continue entry = dom.createElement('SR') element.appendChild(entry) subentry = dom.createElement("UUID") entry.appendChild(subentry) textnode = dom.createTextNode(val) subentry.appendChild(textnode) from NFSSR import PROBEVERSION if PROBEVERSION in dconf: util.SMlog("Add supported nfs versions to sr-probe") try: supported_versions = get_supported_nfs_versions(dconf.get('server')) supp_ver = dom.createElement("SupportedVersions") element.appendChild(supp_ver) for ver in supported_versions: version = dom.createElement('Version') supp_ver.appendChild(version) textnode = dom.createTextNode(ver) version.appendChild(textnode) except NfsException: # Server failed to give us supported versions pass return dom.toprettyxml()
def _unmap_sxm_mirror(self, vdi_uuid, size): _vdi_name = "%s%s" % (VDI_PREFIX, vdi_uuid) _dev_name = "%s/%s" % (self.sr.DEV_ROOT, _vdi_name) _dmdev_name = "%s%s" % (self.sr.DM_ROOT, _vdi_name) _dm_name = "%s-%s" % (self.sr.CEPH_POOL_NAME, _vdi_name) vdi_name = "%s" % (vdi_uuid) dev_name = "%s/%s" % (self.sr.SR_ROOT, vdi_name) vdi_ref = self.session.xenapi.VDI.get_by_uuid(vdi_uuid) dm = "mirror" if self.session.xenapi.VDI.get_sharable(vdi_ref): sharable = "true" else: sharable = "false" util.SMlog( "Calling cephutills.VDI._unmap_sxm_mirror: vdi_uuid=%s, size=%s, dm=%s, sharable=%s" % (vdi_uuid, size, dm, sharable)) args = { "mode": self.mode, "vdi_uuid": vdi_uuid, "vdi_name": vdi_name, "dev_name": dev_name, "_vdi_name": _vdi_name, "_dev_name": _dev_name, "_dmdev_name": _dmdev_name, "_dm_name": _dm_name, "CEPH_POOL_NAME": self.sr.CEPH_POOL_NAME, "NBDS_MAX": str(NBDS_MAX), "CEPH_USER": self.sr.CEPH_USER, "sharable": sharable, "dm": dm, "size": str(size) } self._call_plugin('unmap', args) self.session.xenapi.VDI.remove_from_sm_config(vdi_ref, 'dm')
def resize_cbt(self, sr_uuid, vdi_uuid, size): """Resize the given VDI to size <size> MB. Size can be any valid disk size greater than [or smaller than] the current value. This operation IS idempotent and should succeed if the VDI can be resized to the specified value or if the VDI is already the specified size. The actual disk size created may be larger than the requested size if the substrate requires a size in multiples of a certain extent size. The SR must be queried for the exact size. This operation does not modify the contents on the disk such as the filesystem. Responsibility for resizing the FS is left to the VM administrator. [Reducing the size of the disk is a very dangerous operation and should be conducted very carefully.] Disk contents should always be backed up in advance. """ try: if self._get_blocktracking_status(): logpath = self._get_cbt_logpath(vdi_uuid) self._cbt_op(vdi_uuid, cbtutil.set_cbt_size, logpath, size) except util.CommandException as ex: util.SMlog("Resizing of log file %s failed, " "disabling CBT. Reason: %s" % (logpath, str(ex))) self._delete_cbt_log() vdi_ref = self.sr.srcmd.params['vdi_ref'] self.sr.session.xenapi.VDI.set_cbt_enabled(vdi_ref, False) alert_name = "VDI_CBT_RESIZE_FAILED" alert_prio_warning = "3" alert_obj = "VDI" alert_uuid = str(vdi_uuid) alert_str = ("Resizing of CBT metadata for disk %s failed." % vdi_uuid) self.sr.session.xenapi.message.create(alert_name, alert_prio_warning, alert_obj, alert_uuid, alert_str)
def resize(self, sr_uuid, vdi_uuid, size): if not self.sr.isMaster: util.SMlog('vdi_resize blocked for non-master') raise xs_errors.XenError('LVMMaster') try: self.size = lvutil._getLVsize(self.path) except: raise xs_errors.XenError('VDIUnavailable', \ opterr='no such VDI %s' % self.path) size_mb = long(size) / (1024 * 1024) try: assert(size_mb >= self.size/(1024 * 1024)) if size == self.size: self.size = lvutil._getLVsize(self.path) self.utilisation = self.size return super(LVMVDI, self).get_params() # Verify there's sufficient space for the VDI stats = lvutil._getVGstats(self.sr.vgname) freespace = stats['physical_size'] - stats['physical_utilisation'] if freespace < long(size) - self.size: raise xs_errors.XenError('SRNoSpace') cmd = ["lvresize", "-L", str(size_mb), self.path] text = util.pread2(cmd) self.size = lvutil._getLVsize(self.path) self.utilisation = self.size self._db_update() return super(LVMVDI, self).get_params() except util.CommandException, inst: raise xs_errors.XenError('LVMResize', \ opterr='lvresize failed error is %d' % inst.code)
def appendCIFSMountOptions(self, mountcmd): """Append options to mount.cifs""" options = [] try: options.append(self.getCacheOptions()) if not cifutils.containsCredentials(self.dconf, prefix="cifs"): options.append('guest') options.append(self.getSMBVersion()) username, domain = (cifutils.splitDomainAndUsername( self.dconf['username'])) if domain: options.append('domain=' + domain) except: util.SMlog("Exception while attempting to append mount options") raise # Extend mountcmd appropriately if options: options = ",".join(str(x) for x in options if x) mountcmd.extend(["-o", options])
def __unmap_VHD(self, vdi_uuid): _vdi_name = "%s%s" % (VDI_PREFIX, vdi_uuid) _dev_name = "%s/%s" % (self.sr.DEV_ROOT, _vdi_name) _dmdev_name = "%s%s" % (self.sr.DM_ROOT, _vdi_name) _dm_name = "%s-%s" % (self.sr.CEPH_POOL_NAME, _vdi_name) vdi_ref = self.session.xenapi.VDI.get_by_uuid(vdi_uuid) sm_config = self.session.xenapi.VDI.get_sm_config(vdi_ref) if sm_config.has_key("dm"): dm = sm_config["dm"] else: dm = "none" if self.session.xenapi.VDI.get_sharable(vdi_ref): sharable = "true" else: sharable = "false" util.SMlog( "Calling cephutills.VDI._unmap_VHD: vdi_uuid=%s, dm=%s, sharable=%s" % (vdi_uuid, dm, sharable)) args = { "mode": self.mode, "vdi_uuid": vdi_uuid, "_vdi_name": _vdi_name, "_dev_name": _dev_name, "_dmdev_name": _dmdev_name, "_dm_name": _dm_name, "CEPH_POOL_NAME": self.sr.CEPH_POOL_NAME, "NBDS_MAX": str(NBDS_MAX), "CEPH_USER": self.sr.CEPH_USER, "sharable": sharable, "dm": dm } self._call_plugin('_unmap', args)
def probe(self): self.uuid = util.gen_uuid() # When multipathing is enabled, since we don't refcount the multipath maps, # we should not attempt to do the iscsi.attach/detach when the map is already present, # as this will remove it (which may well be in use). if self.mpath == 'true' and self.dconf.has_key('SCSIid'): maps = [] try: maps = mpath_cli.list_maps() except: pass if self.dconf['SCSIid'] in maps: raise xs_errors.XenError('SRInUse') self.iscsi.attach(self.uuid) if not self.iscsi._attach_LUN_bySCSIid(self.SCSIid): util.SMlog("Unable to detect LUN") raise xs_errors.XenError('InvalidDev') self._pathrefresh(LVHDoISCSISR) out = LVHDSR.LVHDSR.probe(self) self.iscsi.detach(self.uuid) return out
def _getCEPH_response(self, cmd): dbg_prt("[rbdsr] _getCEPH_response") s = pxssh.pxssh() s.force_password = True password = "" if self.dconf.has_key('chappassword_secret'): password = util.get_secret(self.session, self.dconf['chappassword_secret']) elif self.dconf.has_key('chappassword'): password = self.dconf['chappassword'] user = self.srcmd.dconf['chapuser'] target = self.srcmd.dconf['target'].split(',')[0] port = self.srcmd.dconf['port'] if not s.login(target, user, password): util.SMlog('ssh login failed with last message %s' % s) else: s.sendline(cmd) s.prompt() result = s.before.split('\n') # remove the last one which is a blank dbg_prt( "[rbdsr] ceph_response cmd : [%s], result : [%s], result_len : %d", cmd, result, len(result)) return result[1:]
def load(self, sr_uuid): driver = SR.driver('hba') self.hbasr = driver(self.original_srcmd, sr_uuid) pbd = None try: pbd = util.find_my_pbd(self.session, self.host_ref, self.sr_ref) except: pass try: if not self.dconf.has_key('SCSIid') and self.dconf.has_key('device'): # UPGRADE FROM MIAMI: add SCSIid key to device_config util.SMlog("Performing upgrade from Miami") if not os.path.exists(self.dconf['device']): raise SCSIid = scsiutil.getSCSIid(self.dconf['device']) self.dconf['SCSIid'] = SCSIid del self.dconf['device'] if pbd <> None: device_config = self.session.xenapi.PBD.get_device_config(pbd) device_config['SCSIid'] = SCSIid device_config['upgraded_from_miami'] = 'true' del device_config['device'] self.session.xenapi.PBD.set_device_config(pbd, device_config) except: pass if not self.dconf.has_key('SCSIid') or not self.dconf['SCSIid']: print >>sys.stderr,self.hbasr.print_devs() raise xs_errors.XenError('ConfigSCSIid') self.SCSIid = self.dconf['SCSIid'] self._pathrefresh(LVHDoHBASR) LVHDSR.LVHDSR.load(self, sr_uuid)
def generate_config(self, sr_uuid, vdi_uuid): util.SMlog("LVHDoISCSIVDI.generate_config") if not lvutil._checkLV(self.path): raise xs_errors.XenError('VDIUnavailable') if self.sr.sm_config['allocation'] == "xlvhd": lvutil.flushLV(self.path) dict = {} self.sr.dconf['localIQN'] = self.sr.iscsi.localIQN self.sr.dconf['multipathing'] = self.sr.mpath self.sr.dconf['multipathhandle'] = self.sr.mpathhandle dict['device_config'] = self.sr.dconf if dict['device_config'].has_key('chappassword_secret'): s = util.get_secret(self.session, dict['device_config']['chappassword_secret']) del dict['device_config']['chappassword_secret'] dict['device_config']['chappassword'] = s dict['sr_uuid'] = sr_uuid dict['vdi_uuid'] = vdi_uuid dict['allocation'] = self.sr.sm_config['allocation'] dict['command'] = 'vdi_attach_from_config' # Return the 'config' encoded within a normal XMLRPC response so that # we can use the regular response/error parsing code. config = xmlrpclib.dumps(tuple([dict]), "vdi_attach_from_config") return xmlrpclib.dumps((config, ), "", True)
def getSRInfoForSectors(self, sr_info, range): srinfo = '' try: # write header, name_labael and description in that function # as its common to all # Fill up the first sector if 0 in range: srinfo = getSector(buildHeader(SECTOR_SIZE)) if 1 in range: uuid = getXMLTag(UUID_TAG) % sr_info[UUID_TAG] second = self.SECTOR2_FMT % (XML_HEADER, uuid) srinfo += getSector(second) if 2 in range: # Fill up the SR name_label srinfo += getSector( getSectorAlignedXML( NAME_LABEL_TAG, xml.sax.saxutils.escape(sr_info[NAME_LABEL_TAG]))) if 3 in range: # Fill the name_description srinfo += getSector( getSectorAlignedXML( NAME_DESCRIPTION_TAG, xml.sax.saxutils.escape( sr_info[NAME_DESCRIPTION_TAG]))) return srinfo except Exception, e: util.SMlog("Exception getting SR info with parameters: sr_info: %s," \ "range: %s. Error: %s" % (sr_info, range, str(e))) raise
def refresh(self): """Get the LV information for the VG using "lvs" """ util.SMlog("LVMCache: refreshing") #cmd = lvutil.cmd_lvm([lvutil.CMD_LVS, "--noheadings", "--units", # "b", "-o", "+lv_tags", self.vgPath]) #text = util.pread2(cmd) cmd = [ lvutil.CMD_LVS, "--noheadings", "--units", "b", "-o", "+lv_tags", self.vgPath ] stateFileAttach = os.getenv('THIN_STATE_FILE_ATTACH', None) if stateFileAttach == "true": cmd.append("--offline") text = lvutil.cmd_lvm(cmd) self.lvs.clear() self.tags.clear() for line in text.split('\n'): if not line: continue fields = line.split() lvName = fields[0] lvInfo = LVInfo(lvName) lvInfo.size = long(fields[3].replace("B", "")) lvInfo.active = (fields[2][4] == 'a') if (fields[2][5] == 'o'): lvInfo.open = 1 lvInfo.readonly = (fields[2][1] == 'r') self.lvs[lvName] = lvInfo if len(fields) >= 5: tags = fields[4].split(',') for tag in tags: self._addTag(lvName, tag) self.initialized = True
def refresh_HostID(HostID, scanstring): LUNs = glob.glob('/sys/class/scsi_disk/%s*' % HostID) li = [] for l in LUNs: chan = re.sub(":[0-9]*$", '', os.path.basename(l)) if chan not in li: li.append(chan) fullrescan = True if len(li) and scanstring == "- - -": fullrescan = False for c in li: if not refresh_scsi_channel(c): fullrescan = True if fullrescan: util.SMlog("Rescanning HostID %s with %s" % (HostID, scanstring)) path = '/sys/class/scsi_host/host%s/scan' % HostID if os.path.exists(path): try: f = open(path, 'w') f.write('%s\n' % scanstring) f.close() except: pass # Host Bus scan issued, now try to detect channels if util.wait_for_path("/sys/class/scsi_disk/%s*" % HostID, 5): # At least one LUN is mapped LUNs = glob.glob('/sys/class/scsi_disk/%s*' % HostID) li = [] for l in LUNs: chan = re.sub(":[0-9]*$", '', os.path.basename(l)) if chan not in li: li.append(chan) for c in li: refresh_scsi_channel(c)
self.vdis[vdi.parent].read_only = True if geneology.has_key(vdi.parent): geneology[vdi.parent].append(uuid) else: geneology[vdi.parent] = [uuid] if not vdi.hidden: self.virtual_allocation += (vdi.size) # now remove all hidden leaf nodes from self.vdis so that they are not # introduced into the Agent DB when SR is synchronized. With the # asynchronous GC, a deleted VDI might stay around until the next # SR.scan, so if we don't ignore hidden leaves we would pick up # freshly-deleted VDIs as newly-added VDIs for uuid in self.vdis.keys(): if not geneology.has_key(uuid) and self.vdis[uuid].hidden: util.SMlog("Scan found hidden leaf (%s), ignoring" % uuid) del self.vdis[uuid] def _getsize(self): return util.get_fs_size(self.path) def _getutilisation(self): return util.get_fs_utilisation(self.path) def _replay(self, logentry): # all replay commands have the same 5,6,7th arguments # vdi_command, sr-uuid, vdi-uuid back_cmd = logentry[5].replace("vdi_", "") target = self.vdi(logentry[7]) cmd = getattr(target, back_cmd) args = []
vdi = vdiInfo[vdi.parentUuid] vdi.refcount += 1 pathsNotInUse = [] for uuid, vdi in vdiInfo.iteritems(): if vdi.hidden: util.SMlog("Setting refcount for %s to %d" % (uuid, vdi.refcount)) RefCounter.set(uuid, vdi.refcount, 0, ns) if vdi.refcount == 0 and vdi.lvActive: path = os.path.join("/dev", lvmCache.vgName, vdi.lvName) pathsNotInUse.append(path) return pathsNotInUse if __name__ == "__main__": # used by the master changeover script from lvmcache import LVMCache try: cmd = sys.argv[1] srUuid = sys.argv[2] if cmd == "fixrefcounts": vgName = VG_PREFIX + srUuid lvmCache = LVMCache(vgName) setInnerNodeRefcounts(lvmCache, srUuid) else: util.SMlog("Invalid usage") print "Usage: %s fixrefcounts <sr_uuid>" % sys.argv[0] except: util.logException("setInnerNodeRefcounts")
def _loadvdis(self): if self.cmd not in NEEDS_LOADVDIS: return 0 if self.vdis: return self._init_hbadict() count = 0 self.physical_size = 0 root_dev_id = util.getrootdevID() xapi_session = self.session.xenapi known_scsid = {} # dict of ids processed within the following loop for key in self.hbadict.iterkeys(): # We need a fresh sm_config everytime because it is modified # inside this loop sm_config = xapi_session.SR.get_sm_config(self.sr_ref) # The way we create vdi_path and the following check are # not clear at all vdi_path = os.path.join("/dev", key) if vdi_path not in self.devs: continue scsi_id = scsiutil.getSCSIid(vdi_path) if scsi_id == root_dev_id: util.SMlog("Skipping root device %s" % scsi_id) continue # Avoid false positives: this SR can already contain this # SCSIid during scan. scsi_key = "scsi-" + scsi_id if scsi_key in sm_config: # if we know about this scsid we can skip this specific dev if scsi_key in known_scsid: util.SMlog("This SCSI id (%s) is already added" % scsi_id) continue else: # marked as known to avoid adding it again to sm_config known_scsid[scsi_key] = "" elif util.test_SCSIid(self.session, None, scsi_id): util.SMlog("This SCSI id (%s) is used by another SR" % scsi_id) continue # getuniqueserial invokes again getSCSIid -> Fix! uuid = scsiutil.gen_uuid_from_string( scsiutil.getuniqueserial(vdi_path)) # We could have checked the SCSIid but the dictionary has # uuid as key. # We have already checked known_scsid, though. This block is # supposed to be always False if uuid in self.vdis: util.SMlog("Warning: unexpected code block reached with" " uuid = %s" % scsi_id) continue obj = self.vdi(uuid) path = self.mpathmodule.path(scsi_id) ids = self.devs[vdi_path] obj._query(vdi_path, ids[4], uuid, scsi_id) self.vdis[uuid] = obj self.physical_size += obj.size count += 1 # If we know about it no need to add to sm_config if scsi_key in known_scsid: continue # Prepare multipathing and make the other SRs know this SCSIid # is reserved. # Its counterpart is vdi_delete try: xapi_session.SR.add_to_sm_config(self.sr_ref, scsi_key, uuid) known_scsid[scsi_key] = "" except: util.SMlog("Warning: add_to_sm_config failed unexpectedly") return count
if options: options = ",".join(str(x) for x in options if x) try: util.ioretry(lambda: util.pread( ["mount.cifs", self.remoteserver, mountpoint, "-o", options]), errlist=[errno.EPIPE, errno.EIO], maxretry=2, nofail=True) except util.CommandException, inst: raise SMBException("mount failed with return code %d" % inst.code) finally: try: os.unlink(self.credentials) except OSError: util.SMlog("Error when trying to delete " "credentials files /tmp/<uuid>") # Sanity check to ensure that the user has at least RO access to the # mounted share. Windows sharing and security settings can be tricky. try: util.listdir(mountpoint) except util.CommandException: try: self.unmount(mountpoint, True) except SMBException: util.logException('SMBSR.unmount()') raise SMBException("Permission denied. " "Please check user privileges.") def getMountOptions(self): """Creates option string based on parameters provided"""
def scan(srobj): systemrootID = util.getrootdevID() hbadict = srobj.hbadict hbas = srobj.hbas dom = xml.dom.minidom.Document() e = dom.createElement("Devlist") dom.appendChild(e) if not os.path.exists(DEVPATH): return dom.toprettyxml() devs = srobj.devs vdis = {} for key in hbadict: hba = hbadict[key] path = os.path.join("/dev",key) realpath = path obj = srobj.vdi("") try: obj._query(realpath, devs[realpath][4]) except: continue # Test for root dev or existing PBD if len(obj.SCSIid) and len(systemrootID) and util.match_scsiID(obj.SCSIid, systemrootID): util.SMlog("Ignoring root device %s" % realpath) continue elif util.test_SCSIid(srobj.session, None, obj.SCSIid): util.SMlog("SCSIid in use, ignoring (%s)" % obj.SCSIid) continue elif not devs.has_key(realpath): continue ids = devs[realpath] obj.adapter = ids[1] obj.channel = ids[2] obj.id = ids[3] obj.lun = ids[4] obj.hba = hba['procname'] obj.numpaths = 1 if vdis.has_key(obj.SCSIid): vdis[obj.SCSIid].numpaths += 1 vdis[obj.SCSIid].path += " [%s]" % key elif obj.hba == 'mpp': mppdict = _genMPPHBA(obj.adapter) if mppdict.has_key(key): item = mppdict[key] adapters = '' for i in item: if len(adapters): adapters += ', ' obj.numpaths += 1 adapters += i if len(adapters): obj.mpp = adapters vdis[obj.SCSIid] = obj else: vdis[obj.SCSIid] = obj for key in vdis: obj = vdis[key] d = dom.createElement("BlockDevice") e.appendChild(d) for attr in ['path','numpaths','SCSIid','vendor','serial','size','adapter','channel','id','lun','hba','mpp']: try: aval = getattr(obj, attr) except AttributeError: if attr in ['mpp']: continue raise xs_errors.XenError('InvalidArg', \ opterr='Missing required field [%s]' % attr) entry = dom.createElement(attr) d.appendChild(entry) textnode = dom.createTextNode(str(aval)) entry.appendChild(textnode) for key in hbas.iterkeys(): a = dom.createElement("Adapter") e.appendChild(a) entry = dom.createElement('host') a.appendChild(entry) textnode = dom.createTextNode(key) entry.appendChild(textnode) entry = dom.createElement('name') a.appendChild(entry) textnode = dom.createTextNode(hbas[key]) entry.appendChild(textnode) entry = dom.createElement('manufacturer') a.appendChild(entry) textnode = dom.createTextNode(getManufacturer(hbas[key])) entry.appendChild(textnode) id = key.replace("host","") entry = dom.createElement('id') a.appendChild(entry) textnode = dom.createTextNode(id) entry.appendChild(textnode) _add_host_parameters_to_adapter(dom, a, 'fc_host', id, ['node_name', 'port_name', 'port_state', 'speed', 'supported_speeds']) _add_host_parameters_to_adapter(dom, a, 'iscsi_host', id, ['hwaddress', 'initiatorname', 'ipaddress', 'port_speed', 'port_state']) return dom.toprettyxml()
def resizePV(dev): try: cmd_lvm([CMD_PVRESIZE, dev]) except util.CommandException as inst: util.SMlog("Failed to grow the PV, non-fatal")
self.lvmCache.deactivateNoRefcount(lvName) except Exception, e2: msg = 'failed to close/deactivate %s: %s' \ % (lvName, e2) if not e: util.SMlog(msg) raise e2 else: util.SMlog('WARNING: %s (error ignored)' % msg) except: util.logException("journaler.create") try: self.lvmCache.remove(lvName) except Exception, e: util.SMlog('WARNING: failed to clean up failed journal ' \ ' creation: %s (error ignored)' % e) raise JournalerException("Failed to write to journal %s" \ % lvName) def remove(self, type, id): """Remove the entry of type "type" for "id". Error if the entry doesn't exist.""" val = self.get(type, id) if not val: raise JournalerException("No journal for '%s:%s'" % (type, id)) lvName = self._getNameLV(type, id, val) mapperDevice = self._getLVMapperName(lvName) if len(mapperDevice) > LVM_MAX_NAME_LEN: lvName = self._getNameLV(type, id) self.lvmCache.remove(lvName)
def refresh_scsi_channel(channel): DEV_WAIT = 5 util.SMlog("Refreshing channel %s" % channel) util.wait_for_path('/dev/disk/by-scsibus/*-%s*' % channel, DEV_WAIT) LUNs = glob.glob('/dev/disk/by-scsibus/*-%s*' % channel) try: rootdevs = util.dom0_disks() except: util.SMlog("Failed to query root disk, failing operation") return False # a) Find a LUN to issue a Query LUNs command li = [] Query = False for lun in LUNs: try: hbtl = lun.split('-')[-1] h = hbtl.split(':') l = util.pread2(["/usr/bin/sg_luns", "-q", lun]).split('\n') li = [] for i in l: if len(i): li.append(int(i[0:4], 16)) util.SMlog("sg_luns query returned %s" % li) Query = True break except: pass if not Query: util.SMlog("Failed to detect or query LUN on Channel %s" % channel) return False # b) Remove stale LUNs current = glob.glob('/dev/disk/by-scsibus/*-%s:%s:%s*' % (h[0], h[1], h[2])) for cur in current: lunID = int(cur.split(':')[-1]) newhbtl = ['', h[0], h[1], h[2], str(lunID)] if os.path.realpath(cur) in rootdevs: # Don't touch the rootdev if lunID in li: li.remove(lunID) continue # Check if LUN is stale, and remove it if not lunID in li: util.SMlog("Stale LUN detected. Removing HBTL: %s" % newhbtl) scsi_dev_ctrl(newhbtl, "remove") util.wait_for_nopath(cur, DEV_WAIT) continue else: li.remove(lunID) # Check if the device is still present if not os.path.exists(cur): continue # Query SCSIid, check it matches, if not, re-probe cur_SCSIid = os.path.basename(cur).split("-%s:%s:%s" % (h[0], h[1], h[2]))[0] real_SCSIid = getSCSIid(cur) if cur_SCSIid != real_SCSIid: util.SMlog("HBTL %s does not match, re-probing" % newhbtl) scsi_dev_ctrl(newhbtl, "remove") util.wait_for_nopath(cur, DEV_WAIT) scsi_dev_ctrl(newhbtl, "add") util.wait_for_path( '/dev/disk/by-scsibus/%s-%s' % (real_SCSIid, hbtl), DEV_WAIT) pass # c) Probe for any LUNs that are not present in the system for l in li: newhbtl = ['', h[0], h[1], h[2], str(l)] newhbtlstr = "%s:%s:%s:%s" % (h[0], h[1], h[2], str(l)) util.SMlog("Probing new HBTL: %s" % newhbtl) scsi_dev_ctrl(newhbtl, "add") util.wait_for_path('/dev/disk/by-scsibus/*-%s' % newhbtlstr, DEV_WAIT) return True
def mpexec(cmd): util.SMlog("mpath cmd: %s" % cmd) (rc, stdout, stderr) = util.doexec(mpathcmd, cmd) if stdout != "multipathd> ok\nmultipathd> " \ and stdout != "multipathd> " + cmd + "\nok\nmultipathd> ": raise MPathCLIFail
def reset(sid, explicit_unmap=False, delete_nodes=False): util.SMlog("Resetting LUN %s" % sid) if (mpp_luncheck.is_RdacLun(sid)): _resetMPP(sid, explicit_unmap) else: _resetDMP(sid, explicit_unmap, delete_nodes)
def _snapshot(self, snap_type): util.SMlog("FileVDI._snapshot for %s (type %s)" % (self.uuid, snap_type)) args = [] args.append("vdi_clone") args.append(self.sr.uuid) args.append(self.uuid) dest = None dst = None if snap_type == self.SNAPSHOT_DOUBLE: dest = util.gen_uuid() dst = os.path.join(self.sr.path, "%s.%s" % (dest, self.vdi_type)) args.append(dest) if self.hidden: raise xs_errors.XenError('VDIClone', opterr='hidden VDI') depth = vhdutil.getDepth(self.path) if depth == -1: raise xs_errors.XenError('VDIUnavailable', \ opterr='failed to get VHD depth') elif depth >= vhdutil.MAX_CHAIN_SIZE: raise xs_errors.XenError('SnapshotChainTooLong') # Test the amount of actual disk space if ENFORCE_VIRT_ALLOC: self.sr._loadvdis() reserved = self.sr.virtual_allocation sr_size = self.sr._getsize() num_vdis = 2 if snap_type == self.SNAPSHOT_SINGLE: num_vdis = 1 if (sr_size - reserved) < ((self.size + VDI.VDIMetadataSize( \ vhdutil.VDI_TYPE_VHD, self.size)) * num_vdis): raise xs_errors.XenError('SRNoSpace') newuuid = util.gen_uuid() src = self.path newsrc = os.path.join(self.sr.path, "%s.%s" % (newuuid, self.vdi_type)) newsrcname = "%s.%s" % (newuuid, self.vdi_type) if not self._checkpath(src): raise xs_errors.XenError('VDIUnavailable', \ opterr='VDI %s unavailable %s' % (self.uuid, src)) # wkcfix: multiphase util.start_log_entry(self.sr.path, self.path, args) # We assume the filehandle has been released try: try: util.ioretry(lambda: os.rename(src, newsrc)) except util.CommandException, inst: if inst.code != errno.ENOENT: # failed to rename, simply raise error util.end_log_entry(self.sr.path, self.path, ["error"]) raise try: util.ioretry(lambda: self._snap(src, newsrcname)) if snap_type == self.SNAPSHOT_DOUBLE: util.ioretry(lambda: self._snap(dst, newsrcname)) # mark the original file (in this case, its newsrc) # as hidden so that it does not show up in subsequent scans util.ioretry(lambda: self._mark_hidden(newsrc)) except util.CommandException, inst: if inst.code != errno.EIO: raise
if not ce.reason.endswith(': File exists'): raise # If we've got no active sessions, and the deamon is already running, # we're ok to restart the daemon if iscsilib.is_iscsi_daemon_running(): if not iscsilib._checkAnyTGT(): iscsilib.restart_daemon() # Start the updatempppathd daemon if not _is_mpp_daemon_running(): cmd = ["service", "updatempppathd", "start"] util.pread2(cmd) if not _is_mpath_daemon_running(): util.SMlog("Warning: multipath daemon not running. Starting daemon!") cmd = ["service", "multipathd", "start"] util.pread2(cmd) for i in range(0, 120): if mpath_cli.is_working(): util.SMlog("MPATH: dm-multipath activated.") return time.sleep(1) util.SMlog("Failed to communicate with the multipath daemon!") raise xs_errors.XenError('MultipathdCommsFailure') def deactivate(): util.SMlog("MPATH: multipath deactivate called")
CEPH_USER ] cmdout = util.pread2(cmd) rbds_list = json.loads(cmdout) for img_count, rbd in enumerate(rbds_list): cmdout = util.pread2([ "rbd", "image-meta", "list", rbd['image'], "--pool", POOL_NAME, "--format", "json", "--name", CEPH_USER ]) if len(cmdout) != 0: vdi_info = json.loads(cmdout) try: if 'VDI_LABEL' in vdi_info: util.SMlog( "rbd_meta_migration: update metadata of poolname = %s, rbdimage = %s : %s" % (POOL_NAME, rbd['image'], vdi_info)) tag = ":" + NAME_LABEL_TAG if tag not in vdi_info: util.SMlog( "rbd_meta_migration: poolname = %s, rbdimage = %s METADATA VDI_LABEL(%s) => %s" % (POOL_NAME, rbd['image'], vdi_info['VDI_LABEL'], tag)) util.pread2([ "rbd", "image-meta", "set", rbd['image'], tag, str(vdi_info['VDI_LABEL']), "--pool", POOL_NAME, "--name", CEPH_USER ]) tag = ":" + NAME_DESCRIPTION_TAG
def list_maps(): cmd = "list maps" util.SMlog("mpath cmd: %s" % cmd) (rc, stdout, stderr) = util.doexec(mpathcmd, cmd) util.SMlog("mpath output: %s" % stdout) return map(lambda x: x.split(' ')[0], stdout.split('\n')[2:-1])
VGs = {} for dev in root.split(','): try: sr_uuid = _get_sr_uuid(dev, [prefix]).strip(' \n') if len(sr_uuid): if VGs.has_key(sr_uuid): VGs[sr_uuid] += ",%s" % dev else: VGs[sr_uuid] = dev except Exception, e: util.logException("exception (ignored): %s" % e) continue if sr_alloc == 'xlvhd': for vg in VGs.keys(): if not os.path.isfile('%s/%s' % (config_dir, VG_PREFIX + vg)): util.SMlog('vg=%s VGs[vg]=%s' % (vg, VGs[vg])) setvginfo(vg, VG_PREFIX + vg, VGs[vg].split(','), "file://local/dev/null", local_allocator=None) return VGs # Converts an SR list to an XML document with the following structure: # <SRlist> # <SR> # <UUID>...</UUID> # <Devlist>...</Devlist> # <size>...</size> # <!-- If includeMetadata is set to True, the following additional nodes
def synchronise_new(self): """Add XenAPI records for new disks""" for location in self.new: vdi = self.get_sm_vdi(location) util.SMlog("Introducing VDI with location=%s" % (vdi.location)) vdi._db_introduce()
def cmd_lvm(cmd, sr_alloc=None, pread_func=util.pread2, *args): """ Construct and run the appropriate lvm command depending on the SR's allocation type; 'thick' or 'xlvhd'. For PV commands, the full path to the device is required. Input: cmd -- (list) lvm command cmd[0] -- (str) lvm command name cmd[1:] -- (str) lvm command parameters sr_alloc -- (str) SR's allocation type; 'thick' or 'xlvhd' if it's not supplied, the function will figure it out Default: None pread_func -- (function) the flavor of util.pread to use to execute the lvm command Default: util.pread2() *args -- extra arguments passed to cmd_lvm will be passed to 'pread_func' Return: stdout -- (str) stdout after running the lvm command. Raise: util.CommandException """ if type(cmd) is not list: util.SMlog("CMD_LVM: Argument 'cmd' not of type 'list'") return None if not len(cmd): util.SMlog("CMD_LVM: 'cmd' list is empty") return None lvm_cmd, lvm_args = cmd[0], cmd[1:] if lvm_cmd not in LVM_COMMANDS: util.SMlog("CMD_LVM: '{}' is not a valid lvm command".format(lvm_cmd)) return None for arg in lvm_args: if not util.is_string(arg): util.SMlog("CMD_LVM: Not all lvm arguments are of type 'str'") return None if sr_alloc is None: if lvm_cmd not in PV_COMMANDS: for arg in lvm_args: try: filename = extract_vgname(arg) except: util.logException('CMD_LVM') return None if filename: break else: # if for loop doesn't break util.SMlog("CMD_LVM: Could not find VG " "name in lvm argument list") util.SMlog([lvm_cmd] + lvm_args) return None else: for arg in lvm_args: if os.path.exists(arg): try: filename = getSCSIid(arg) except: util.logException('CMD_LVM') return None break else: # if for loop doesn't break util.SMlog("CMD_LVM: Could not find PV " "name in lvm argument list") util.SMlog([lvm_cmd] + lvm_args) return None sr_alloc = get_sr_alloc(filename) if sr_alloc == 'xlvhd': stdout = pread_func(['/bin/xenvm', lvm_cmd] + lvm_args, *args) elif sr_alloc == 'thick': stdout = pread_func([os.path.join(LVM_BIN, lvm_cmd)] + lvm_args, *args) else: util.SMlog("CMD_LVM: ERROR: 'sr_alloc' neither 'xlvhd' nor 'thick'") return None return stdout