def list(self, params={}): e, out = command("%s ls --target=smartcache" % DMSETUP) if e: return e, out cachedevs = {} devreg = ur"(\S+)\s+\((\d+),\s+(\d+)\)" for row in out.splitlines(): result = re.search(devreg, row) if result: name = result.group(1) cachedevs[name] = {} cachedevs[name]["major"] = result.group(2) cachedevs[name]["minor"] = result.group(3) mount_list = get_mount_list() # 补充udev信息 context = pyudev.Context() disks = context.list_devices(subsystem='block', DEVTYPE='disk') for disk in disks: if 'DM_NAME' in disk.keys() and disk['DM_NAME'] in cachedevs.keys( ): # XXX: 此处使用dev/mapper/XXX为设备名称,而没有使用DEVNAME # 原因是blkid命令下,看不到/dev/dm-X的uuid,且两边的uuid不同步 cachedevs[disk['DM_NAME']]['DEVNAME'] = "/dev/mapper/%s" % str( disk['DM_NAME']) if cachedevs[disk['DM_NAME']]['DEVNAME'] in mount_list.keys(): cachedevs[disk['DM_NAME']]['MOUNT_POINT'] = mount_list[ cachedevs[disk['DM_NAME']]['DEVNAME']] return 0, cachedevs
def create(self, params={}): cache_name = params['cache_name'] cache_dev = params['cache_dev'] data_dev = params['data_dev'] cmd = "%s -p back -b %s %s %s %s" % (SMARTCACHE_CREATE, SMARTCACHE_BLOCKSZ, cache_name, cache_dev, data_dev) return command(cmd)
def CheckDriverConfigure(target_ids): e, target_id = apipal.Platform().driver_configure_get_target_id() if e: logger.run.error("Driver configure get target id failed %s:%s" % (e, target_id)) sys.exit(-1) logger.run.debug("Driver configure get target id %s" % target_id) if target_id == -1 * errno.EINVAL: if len(target_ids) == 0: _target_id = 0 else: target_ids.sort() _target_id = target_ids[-1] + 10 logger.run.info("Start set target id to :%s" % _target_id) e, target_id = apipal.Platform().driver_configure_set_target_id( _target_id) if e: logger.run.error("Driver configure set target id failed %s:%s" % (e, target_id)) sys.exit(-1) elif target_id < 0: logger.run.error("Driver configure get target id inside failed %s:%s" % (e, target_id)) sys.exit(-1) with open("/proc/modules", 'r') as pmodules: modules = [ module.split()[0] for module in pmodules.read().strip().splitlines() ] miss_list = [] for r_m in ["pal", "pal_pile", "pal_cache", "pal_pmt", "pal_raw"]: if r_m not in modules: e, res = command("%s %s" % (MODPROBE, r_m)) logger.run.debug("Modprobe:%s:%s:%s" % (r_m, e, res)) with open("/proc/modules", 'r') as pmodules: modules = [ module.split()[0] for module in pmodules.read().strip().splitlines() ] miss_list = [] for r_m in ["pal", "pal_pile", "pal_cache"]: if r_m not in modules: miss_list.append(r_m) if len(miss_list) != 0: logger.run.error("Miss module : %s" % ",".join(miss_list)) sys.exit(-1) return
def info(self, params={}): e, cache_list = self.list() if e: return e, cache_list if params['cache_name'] not in cache_list.keys(): return -1, "Target cache is not exist" e, out = command("%s table %s" % (DMSETUP, params['cache_name'])) if e: return e, out cache_info = cache_list[params['cache_name']] devreg = ur"\s+ssd dev \((\S+)\), disk dev \((\S+)\) cache mode\((\S+)\)" for line in out.splitlines(): result = re.search(devreg, line) if result: cache_info["cache_dev"] = result.group(1) cache_info["data_dev"] = result.group(2) break return 0, cache_info
def dm_remove(self, params={}): cache_name = params['cache_name'] return command("%s remove %s" % (DMSETUP, cache_name))
def load(self, params={}): cache_dev = params['cache_dev'] data_dev = params['data_dev'] cmd = "%s %s %s" % (SMARTCACHE_LOAD, cache_dev, data_dev) return command(cmd)
def destroy(self, params={}): cache_dev = params['cache_dev'] return command("%s %s -f" % (SMARTCACHE_DESTORY, cache_dev))
def CheckUdev(self): context = pyudev.Context() e, out = command("%s table --target=multipath" % DMSETUP) if e: logger.run.error("get multipath failed:%s" % out) return MS_FINISH # 获取当前认到的所有mp列表 mp_list = {} for line in out.splitlines(): items = line.split() mp_name = items[0].split(":")[0] try: d = pyudev.Devices.from_device_file(context, '/dev/mapper/%s' % mp_name) mp_list[mp_name] = {} mp_list[mp_name]['mm'] = "%s:%s" % (os.major( d.device_number), os.minor(d.device_number)) mp_list[mp_name]['nr_path'] = 0 if len(items) >= 11: mp_list[mp_name]['nr_path'] = int(items[10]) except: pass # 获取当前认到的所有asmdisk列表 lun_list = APISmartScsi().get_lun_list() lun_mms = [] for lun_detail_info in lun_list.values(): lun_info = lun_detail_info['attrs'] lun_d = pyudev.Devices.from_device_file(context, lun_info['filename']) lun_mms.append( "%s:%s" % (os.major(lun_d.device_number), os.minor(lun_d.device_number))) ad_list = {} if os.path.exists('/dev/asmdisks'): asmdisks = os.listdir('/dev/asmdisks') for ad_name in asmdisks: try: asm_d = pyudev.Devices.from_device_file( context, '/dev/asmdisks/%s' % ad_name) asm_mm = "%s:%s" % (os.major( asm_d.device_number), os.minor(asm_d.device_number)) # 过滤掉本地smartscsi映射的磁盘 if asm_mm in lun_mms: continue ad_list[ad_name] = {} ad_list[ad_name]['mm'] = asm_mm except pyudev.DeviceNotFoundByNumberError as e: if str(e).startswith("No block device with number"): logger.run.info("Rm no block device:%s" % ad_name) os.remove(os.path.join("/dev/asmdisks", ad_name)) except Exception as e: pass # 删掉失效mp, 或者已经有路径的mp for mp_name in LoopCheckUdevMachine.TODO_CLEAN_MP.keys(): if mp_name not in mp_list.keys( ) or mp_list[mp_name]['nr_path'] != 0: LoopCheckUdevMachine.TODO_CLEAN_MP.pop(mp_name) # 删掉失效ad, 或者已经有对应mp的ad for ad_name, ad_info in LoopCheckUdevMachine.TODO_CLEAN_AD.items(): if ad_name not in ad_list.keys() or ad_info['info']['mm'] in [ mp_info['mm'] for mp_info in mp_list.values() ]: LoopCheckUdevMachine.TODO_CLEAN_AD.pop(ad_name) # 获取需要清除的mp todo_clean_mp = [] for mp_name, mp_info in mp_list.items(): if mp_info['nr_path'] > 0: continue if mp_name not in LoopCheckUdevMachine.TODO_CLEAN_MP.keys(): LoopCheckUdevMachine.TODO_CLEAN_MP[mp_name] = {} LoopCheckUdevMachine.TODO_CLEAN_MP[mp_name]['time'] = int( time.time()) LoopCheckUdevMachine.TODO_CLEAN_MP[mp_name]['info'] = mp_info if int(time.time()) - LoopCheckUdevMachine.TODO_CLEAN_MP[mp_name][ 'time'] > MAX_CLEAN_TIME: todo_clean_mp.append(mp_name) # 获取需要清除的ad todo_clean_ad = [] for ad_name, ad_info in ad_list.items(): if ad_info['mm'] in [ mp_info['mm'] for mp_info in mp_list.values() ]: continue if ad_name not in LoopCheckUdevMachine.TODO_CLEAN_AD.keys(): LoopCheckUdevMachine.TODO_CLEAN_AD[ad_name] = {} LoopCheckUdevMachine.TODO_CLEAN_AD[ad_name]['time'] = int( time.time()) LoopCheckUdevMachine.TODO_CLEAN_AD[ad_name]['info'] = ad_info if int(time.time()) - LoopCheckUdevMachine.TODO_CLEAN_AD[ad_name][ 'time'] > MAX_CLEAN_TIME: todo_clean_ad.append(ad_name) for mp in todo_clean_mp: logger.run.info("Start auto dmsetup remove %s" % mp) e, out = command("%s remove %s" % (DMSETUP, mp)) if e: logger.run.error("dmsetup remove failed:%s" % out) for ad in todo_clean_ad: logger.run.info("Start auto rm asmdisk %s" % ad) try: os.remove(os.path.join("/dev/asmdisks", ad)) except Exception as e: if e: logger.run.error("remove asmdisk failed:%s" % e) return MS_FINISH