/P`c@sddlZddlZddlZddlZddlmZmZmZmZdZ dZ dZ dZ dZ dZd Zed krendS( iN(tClienttLsmErrort ErrorNumbert LocalDiskcCs$tjj|tjjddS(Ns (tsyststderrtwrite(tmsg((s%/usr/libexec/lsm.d/find_unused_lun.pyt print_stderrscCsy*tj|tj}tj|tSWnStk r}|jtjkrRtS|jtj kryt t j dqnXdS(s The manpage of open(2): There is one exception: on Linux 2.6 and later, O_EXCL can be used without O_CREAT if pathname refers to a block device. If the block device is in use by the system (e.g., mounted), open() fails with the error EBUSY. Even when disk has partitions, when all partitions are not used, this function still treats it as free disk. When specific disk or its partition is used by LVM, if there is no data stored in it, this function still treats it as free disk. s(Permission deny, try sudo or run as rootN( tostopentO_EXCLtclosetTruetOSErrorterrnotEBUSYtFalsetEACCESRRtPERMISSION_DENIED(tblk_pathtfdterr((s%/usr/libexec/lsm.d/find_unused_lun.pyt is_free_disk s    cCs|td}d|}ytj|}Wntk rAdSXt|dkrXdS|d}d|}d|}t| }|jjdsdSWdQXt|}|jjSWdQXdS( s Use `/sys/block/sdX/holders/dm-0/dm/name` to get mpath name, use `/sys/block/sdf/holders/dm-0/dm/uuid` to check whether holder is multipath. s/dev/s/sys/block/%s/holdersiis/sys/block/%s/dm/names/sys/block/%s/dm/uuidsmpath-N( tlenR tlistdirtFileNotFoundErrortNoneR treadt startswithtstrip(Rtblk_nametsysfs_holder_foldertholderst holder_nametsysfs_dm_name_pathtsysfs_dm_uuid_pathtf((s%/usr/libexec/lsm.d/find_unused_lun.pyt get_mpath:s       cCs$t|}|r td|StS(Ns/dev/mapper/%s(R&RR(Rt mpath_name((s%/usr/libexec/lsm.d/find_unused_lun.pytis_free_multipathSs cCs|j}i}i}x'|D]}|jr|||j Return a list of lsm.Volume objects. Unused here means the LUN/volume meets one of following conditions: * the block device representing LUN/Volume could be opened with O_EXCL, which means its block is completely free. * The block device is used as PV of LVM, but not been used. s<Found free disk %s, but not managed by libstoragemgmt plugin( tvolumestvpd83RtlistRR(t vpd83_getRtcodeRt NO_SUPPORTRtvalues(tctvolstvpd83_to_vol_hasht free_vol_dicttvolt disk_pathR*tlsm_err((s%/usr/libexec/lsm.d/find_unused_lun.pytfind_unused_lunZs(    cCsi|jd6|jd6|jd6|jd6||jjd6}tj|j}|r||ds    "     !