def scan(self, sr_uuid): """ This function is almost a copy of its base class equivalent. Main differences are: - Fixed erroneous size calculation - Set VDI names automatically - Avoid ScanRecord sync for missing VDIS (stale LUNs) The last one is called in the sub-sub class so we cannot simply extend the base class funcion but we need to override it """ self._init_hbadict() if not self.passthrough: if not self.attached: raise xs_errors.XenError('SRUnavailable') self._loadvdis() # This block is almost SR.scan but without missing sync self._db_update() scanrecord = SR.ScanRecord(self) scanrecord.synchronise_new() scanrecord.synchronise_existing() # Fixing sizes calculation phys_util = 0 for key in self.vdis: vdi_ref = self.session.xenapi.VDI.get_by_uuid(key) if B_util.is_vdi_attached(self.session, vdi_ref): phys_util += self.vdis[key].size self._set_stats(phys_util=phys_util) self._set_vdis_name()
def _query(self, path, id, uuid=None, scsi_id=None): """Overloaded function with mostly duplicated code""" if uuid: self.uuid = uuid else: util.SMlog("RawHBA: uuid should not be generated..") self.uuid = scsiutil.gen_uuid_from_string( scsiutil.getuniqueserial(path) ) if scsi_id: self.SCSIid = scsi_id else: # It is usually unnecessary to calculate it again but scsi_id # is used as a flag in this function and we cannot guarantee # this info is already available at call time self.SCSIid = scsiutil.getSCSIid(path) self.location = self.uuid self.vendor = scsiutil.getmanufacturer(path) self.serial = scsiutil.getserial(path) self.LUNid = id # Handle resize done at the array size. The resize gets reflected # only when the vdi is not in detached state. Do this if we the vdi # is known to xapi try: vdi_ref = self.sr.session.xenapi.VDI.get_by_uuid(self.uuid) # Check if the vbd is not in attached state, do a LUN rescan # to reflect the array LUN dev = [path] if scsi_id: # We want all the devices with this scsi_id dev = scsiutil._genReverseSCSIidmap(scsi_id) if self.sr.srcmd.cmd == "vdi_attach": B_util.refreshdev(dev) elif not B_util.is_vdi_attached(self.sr.session, vdi_ref): B_util.refreshdev(dev) except: pass self.size = scsiutil.getsize(path) self.path = path sm_config = util.default(self, "sm_config", lambda: {}) sm_config['LUNid'] = str(self.LUNid) sm_config['SCSIid'] = self.SCSIid self.sm_config = sm_config
def migrate_VHD_RAW(dest_vdi_uuid, src_vdi_uuid): session = util.get_localAPI_session() # For migration to work, both the vdis should be in detach state. dest_vdi_ref = session.xenapi.VDI.get_by_uuid(dest_vdi_uuid) src_vdi_ref = session.xenapi.VDI.get_by_uuid(src_vdi_uuid) if B_util.is_vdi_attached(session, dest_vdi_ref) or B_util.is_vdi_attached( session, src_vdi_ref): print "Migration NOT complete, one of the vdis is attached to a vm!!!" return False # Migration supported only if the src sr is of type lvmohba or lvmoiscsi src_sr_ref = session.xenapi.VDI.get_SR(src_vdi_ref) src_sr_rec = session.xenapi.SR.get_record(src_sr_ref) if not ((src_sr_rec['type'] == 'lvmoiscsi') or (src_sr_rec['type'] == 'lvmohba')): print("Migration NOT complete, src vdi SR of type %s not supported !!!" \ % src_sr_rec['type']) return False # Migration supported only if the dest sr is of type hba dest_sr_ref = session.xenapi.VDI.get_SR(dest_vdi_ref) dest_sr_rec = session.xenapi.SR.get_record(dest_sr_ref) if not (dest_sr_rec['type'] == 'rawhba'): print( "Migration cannot be completed, dest vdi SR must be of type hba !!!" ) return False # Make sure that the dest vdi can contain the data in src vdi src_vdi_rec = session.xenapi.VDI.get_record(src_vdi_ref) dest_vdi_rec = session.xenapi.VDI.get_record(dest_vdi_ref) if not (int(dest_vdi_rec['virtual_size']) > \ int(src_vdi_rec['physical_utilisation'])): print( "Migration NOT complete, dest vdi virtual-size: %s less than src physical_utilisation %s" % (dest_vdi_rec['virtual_size'], src_vdi_rec['physical_utilisation'])) return False # Create and plug vbds connecting src vdi and dest and dom0 # This way will take care of multipath if any dom0_ref = get_dom0_vm(session) src_vbd_ref = create_vbd(session, dom0_ref, src_vdi_ref) try: print("Plugging src VBD") session.xenapi.VBD.plug(src_vbd_ref) except: session.xenapi.VBD.destroy(src_vbd_ref) print("Migration NOT complete, srv vbd plug failed !!!") return False dest_vbd_ref = create_vbd(session, dom0_ref, dest_vdi_ref) try: print("Plugging dest VBD") session.xenapi.VBD.plug(dest_vbd_ref) except: session.xenapi.VBD.unplug(src_vbd_ref) session.xenapi.VBD.destroy(src_vbd_ref) session.xenapi.VBD.destroy(dest_vbd_ref) print("Migration NOT complete, dest vbd plug failed !!!") return False # Get the tap dev corresponding to the src device # Generate the LV name src_sr_uuid = src_sr_rec['uuid'] dest_sr_uuid = dest_sr_rec['uuid'] vg_name = lvhdutil.VG_PREFIX + src_sr_uuid lv_name = lvhdutil.LV_PREFIX[vhdutil.VDI_TYPE_VHD] + src_vdi_uuid vhd_path = os.path.join(lvhdutil.VG_LOCATION, vg_name, lv_name) # Probe tap-ctl to get the minor number cmd = "tap-ctl list -f %s" % vhd_path args = shlex.split(cmd) (rc, stdout, stderr) = util.doexec(args) output = stdout.split(' ') minor = output[1].split('=')[1] src_dev = "/dev/xen/blktap-2/tapdev" + minor # Generate dest device dest_sympath = "/dev/sm/phy/%s/%s" % (dest_sr_uuid, dest_vdi_uuid) dest_dev = os.path.realpath(dest_sympath) # Perform a dd from input to output device cmd = "dd if=%s of=%s bs=1048576" % (src_dev, dest_dev) print("Performing '%s'" % cmd) args = shlex.split(cmd) (rc, stdout, stderr) = util.doexec(args) if rc != 0: print("Migration NOT complete, could not perform a dd on target") else: session.xenapi.VBD.unplug(src_vbd_ref) session.xenapi.VBD.destroy(src_vbd_ref) session.xenapi.VBD.unplug(dest_vbd_ref) session.xenapi.VBD.destroy(dest_vbd_ref) print("Migration Complete !!!") return True
def migrate_VHD_RAW(dest_vdi_uuid, src_vdi_uuid): session = util.get_localAPI_session() # For migration to work, both the vdis should be in detach state. dest_vdi_ref = session.xenapi.VDI.get_by_uuid(dest_vdi_uuid) src_vdi_ref = session.xenapi.VDI.get_by_uuid(src_vdi_uuid) if B_util.is_vdi_attached(session, dest_vdi_ref) or B_util.is_vdi_attached(session, src_vdi_ref): print "Migration NOT complete, one of the vdis is attached to a vm!!!" return False # Migration supported only if the src sr is of type lvmohba or lvmoiscsi src_sr_ref = session.xenapi.VDI.get_SR(src_vdi_ref) src_sr_rec = session.xenapi.SR.get_record(src_sr_ref) if not ((src_sr_rec['type'] == 'lvmoiscsi') or (src_sr_rec['type'] == 'lvmohba')): print("Migration NOT complete, src vdi SR of type %s not supported !!!" \ % src_sr_rec['type']) return False # Migration supported only if the dest sr is of type hba dest_sr_ref = session.xenapi.VDI.get_SR(dest_vdi_ref) dest_sr_rec = session.xenapi.SR.get_record(dest_sr_ref) if not (dest_sr_rec['type'] == 'rawhba'): print("Migration cannot be completed, dest vdi SR must be of type hba !!!") return False # Make sure that the dest vdi can contain the data in src vdi src_vdi_rec = session.xenapi.VDI.get_record(src_vdi_ref) dest_vdi_rec = session.xenapi.VDI.get_record(dest_vdi_ref) if not (int(dest_vdi_rec['virtual_size']) > \ int(src_vdi_rec['physical_utilisation'])): print("Migration NOT complete, dest vdi virtual-size: %s less than src physical_utilisation %s" % (dest_vdi_rec['virtual_size'], src_vdi_rec['physical_utilisation'])) return False # Create and plug vbds connecting src vdi and dest and dom0 # This way will take care of multipath if any dom0_ref = get_dom0_vm(session) src_vbd_ref = create_vbd(session, dom0_ref, src_vdi_ref) try: print("Plugging src VBD") session.xenapi.VBD.plug(src_vbd_ref) except: session.xenapi.VBD.destroy(src_vbd_ref) print("Migration NOT complete, srv vbd plug failed !!!") return False dest_vbd_ref = create_vbd(session, dom0_ref, dest_vdi_ref) try: print("Plugging dest VBD") session.xenapi.VBD.plug(dest_vbd_ref) except: session.xenapi.VBD.unplug(src_vbd_ref) session.xenapi.VBD.destroy(src_vbd_ref) session.xenapi.VBD.destroy(dest_vbd_ref) print("Migration NOT complete, dest vbd plug failed !!!") return False # Get the tap dev corresponding to the src device # Generate the LV name src_sr_uuid = src_sr_rec['uuid'] dest_sr_uuid = dest_sr_rec['uuid'] vg_name = lvhdutil.VG_PREFIX + src_sr_uuid lv_name = lvhdutil.LV_PREFIX[vhdutil.VDI_TYPE_VHD] + src_vdi_uuid vhd_path = os.path.join(lvhdutil.VG_LOCATION, vg_name, lv_name) # Probe tap-ctl to get the minor number cmd = "tap-ctl list -f %s" % vhd_path args = shlex.split(cmd) (rc,stdout,stderr) = util.doexec(args) output = stdout.split(' ') minor = output[1].split('=')[1] src_dev = "/dev/xen/blktap-2/tapdev" + minor # Generate dest device dest_sympath = "/dev/sm/phy/%s/%s" % (dest_sr_uuid,dest_vdi_uuid) dest_dev = os.path.realpath(dest_sympath) # Perform a dd from input to output device cmd = "dd if=%s of=%s bs=1048576" % (src_dev, dest_dev) print("Performing '%s'" % cmd) args = shlex.split(cmd) (rc,stdout,stderr) = util.doexec(args) if rc != 0: print("Migration NOT complete, could not perform a dd on target") else: session.xenapi.VBD.unplug(src_vbd_ref) session.xenapi.VBD.destroy(src_vbd_ref) session.xenapi.VBD.unplug(dest_vbd_ref) session.xenapi.VBD.destroy(dest_vbd_ref) print("Migration Complete !!!") return True