Mini Shell

Direktori : /lib/python3.6/site-packages/blivet/devices/__pycache__/
Upload File :
Current File : //lib/python3.6/site-packages/blivet/devices/__pycache__/lvm.cpython-36.pyc

3

�Mf���@s�ddlmZddlZddlZddlZddlZddlZddlmZm	Z	ddl
mZddlm
Z
ddlZddlZejdd�ddlmZd	d
lmZd	dlmZd	dlmZd	d
lmZd	dlmZd	dlmZd	dlmZmZm Z m!Z!m"Z"d	dl#m$Z$d	dl%m&Z&ddl'Z'e'j(d�Z)ddl*m+Z+m,Z,ddl-m.Z.ddl/m0Z0ddl1m2Z2ddl3m4Z4ddl5m6Z6ddl7m8Z8ddl9m:Z:m;Z;m<Z<Gdd�de=�Z>edd d!d"g�Z?ed#d$d%d&g�Z@e@d'ed(�ed)��ZAGd*d+�d+eB�ZCGd,d-�d-e2�ZDGd.d/�d/e6e4�ZEGd0d1�d1e
�ZFGd2d3�d3e=�ZGGd4d5�d5e=�ZHGd6d7�d7e=�ZIGd8d9�d9e=�ZJGd:d;�d;e=�ZKGd<d=�d=e=�ZLGd>d?�d?e=�ZMGd@dA�dAeEeGeHeIeJeKeLeM�
ZNGdBdC�dCe:�ZOGdDdE�dEe:�ZPGdFdG�dGe;�ZQGdHdI�dIe
�ZRGdJdK�dKe<�ZSdS)L�)�DecimalN)�
namedtuple�defaultdict)�wraps)�Enum�BlockDevz2.0)r�)�lvm)�errors)�util)�log_method_call)�udev)�flags)�Size�KiB�MiB�ROUND_UP�
ROUND_DOWN)�lvs_info)�availabilityZblivet�)�LINUX_SECTOR_SIZE�
ParentList)�Device)�
StorageDevice)�ContainerDevice)�
RaidDevice)�DMDevice)�MDRaidArrayDevice)�Cache�
CacheStats�CacheRequestc@seZdZdZdd�ZdS)�LVPVSpeczM Class for specifying how much space on a PV should be allocated for some LV cCs||_||_dS)N)�pv�size)�selfr#r$�r&�/usr/lib/python3.6/lvm.py�__init__AszLVPVSpec.__init__N)�__name__�
__module__�__qualname__�__doc__r(r&r&r&r'r"?sr"�
PVFreeInfor#r$�free�ThPoolReserveSpec�percent�min�max�z1 GiBz100 GiBc@seZdZdZdS)�NotTypeSpecificz/Exception class for invalid type-specific callsN)r)r*r+r,r&r&r&r'r4Psr4cs�eZdZdZdZdgZedd��Zedd��ZdZ	dZ
edd	��Zdm�fd
d�	Z
�fdd�Ze�fdd��Zedd��Zedd��Zdd�Zedd��Zedd��Zdndd�Zdodd �Zd!d"�Z�fd#d$�Zd%d&�Zd'd(�Zd)d*�Zd+d,�Zd-d.�Zd/d0�Z�fd1d2�Z�fd3d4�Z dpd5d6�Z!ed7d8��Z"ed9d:��Z#e#j$d;d:��Z#ed<d=��Z%e%j$d>d=��Z%ed?d@��Z&e&j$dAd@��Z&dBdC�Z'edDdE��Z(edFdG��Z)edHdI��Z*edJdK��Z+edLdM��Z,edNdO��Z-dqdPdQ�Z.edRdS��Z/edTdU��Z0edVdW��Z1edXdY��Z2edZd[��Z3ed\d]��Z4ed^d_��Z5ed`da��Z6e�fdbdc��Z7e7j$dddc��Z7dr�fdedf�	Z8ds�fdgdh�	Z9�fdidj�Z:dkdl�Z;�Z<S)t�LVMVolumeGroupDevicez An LVM Volume Group Zlvmvg�lvm2cCsdS)NZlvmpvr&)�sr&r&r'�<lambda>YszLVMVolumeGroupDevice.<lambda>cCsdS)NZvg_uuidr&)r7r&r&r'r8ZsTcCsdd�tjj�D�S)NcSsg|]}t|��qSr&)r)�.0�pe_sizer&r&r'�
<listcomp>`sz?LVMVolumeGroupDevice.get_supported_pe_sizes.<locals>.<listcomp>)�blockdevr	�get_supported_pe_sizesr&r&r&r'r=^sz+LVMVolumeGroupDevice.get_supported_pe_sizesNF�cs�g|_d|_d|_tj|�|_|
r.|r.d|_tj|�|_tj|�|_tj|�|_||_	|
|_
|jsltj|_t
t|�j|||	||
|d�tj|�|_d|_td�|_d|_|js�t|j�|_|j|_dS)a�
            :param name: the device name (generally a device node's basename)
            :type name: str
            :keyword exists: does this device exist?
            :type exists: bool
            :keyword parents: a list of parent devices
            :type parents: list of :class:`StorageDevice`
            :keyword sysfs_path: sysfs device path
            :type sysfs_path: str
            :keyword pe_size: physical extent size
            :type pe_size: :class:`~.size.Size`

            For existing VG's only:

            :keyword size: the VG's size
            :type size: :class:`~.size.Size`
            :keyword free -- amount of free space in the VG
            :type free: :class:`~.size.Size`
            :keyword pe_free: number of free extents
            :type pe_free: int
            :keyword pe_count -- total number of extents
            :type pe_count: int
            :keyword pv_count: number of PVs in this VG
            :type pv_count: int
            :keyword uuid: the VG UUID
            :type uuid: str

            For non-existing VGs only:

            :keyword shared: whether to create this VG as shared
            :type shared: bool
        FT)�parents�uuidr$�exists�
sysfs_pathrN)�_lvs�
has_duplicate�	_completer�numeric_type�pv_countr:�pe_count�pe_free�exported�_sharedr	ZLVM_PE_SIZE�superr5r(r.�_reserved_percentr�_reserved_space�_thpool_reserverA�lenr?r$Zsize_policy)r%�namer?r$r.r:rHrIrGr@rArBrJ�shared)�	__class__r&r'r(bs.&


zLVMVolumeGroupDevice.__init__csttt|�j�}|d|j|j|j|j|j|j|j	|j
|j|j|j
tjdd�|jD��tjdd�|jD��d�
7}|S)Na9  free = %(free)s  PE Size = %(pe_size)s  PE Count = %(pe_count)s
  PE Free = %(pe_free)s  PV Count = %(pv_count)s
  modified = %(modified)s  extents = %(extents)s  free space = %(free_space)s
  free extents = %(free_extents)s  reserved percent = %(rpct)s  reserved space = %(res)s
  PVs = %(pvs)s
  LVs = %(lvs)scSsg|]}t|��qSr&)�str)r9�pr&r&r'r;�sz1LVMVolumeGroupDevice.__repr__.<locals>.<listcomp>cSsg|]}t|��qSr&)rT)r9�lr&r&r'r;�s)
r.r:rHrIrG�modified�extents�
free_space�free_extentsZrpct�res�pvs�lvs)rLr5�__repr__r.r:rHrIrG�is_modifiedrXrYrZrMrN�pprintZpformatr\r])r%r7)rSr&r'r^�szLVMVolumeGroupDevice.__repr__c
sRtt|�j}|j|j|j|j|j|j|j	|j
|j|j|j
dd�|jD�d��|S)NcSsg|]
}|j�qSr&)rQ)r9�lvr&r&r'r;�sz-LVMVolumeGroupDevice.dict.<locals>.<listcomp>)r.r:rHrIrGrXrYrZ�reserved_percent�reserved_spaceZlv_names)rLr5�dict�updater.r:rHrIrGrXrYrZrMrNr])r%�d)rSr&r'rd�szLVMVolumeGroupDevice.dictcCs|jjdd�S)z& This device's device-mapper map name �-z--)rQ�replace)r%r&r&r'�map_name�szLVMVolumeGroupDevice.map_namecCsd|j|jfS)z' Device node representing this device. z%s/%s)�_dev_dirri)r%r&r&r'�path�szLVMVolumeGroupDevice.pathcCs,t||j|jd�|js"tjd��d|_dS)z" Update this device's sysfs path. )�statuszdevice has not been createdr>N)rrQrlrAr
�DeviceErrorrB)r%r&r&r'�update_sysfs_path�s
z&LVMVolumeGroupDevice.update_sysfs_pathcCs�|js
dSx|jD]}|jrdSqW|jsfx6tjj�D](}|j|jkr6|j	r6|j	ddkr6dSq6WdSx|j
D]}|jjsndSqnWdS)z* The device's status (True means active). FT��a)rAr]rl�completer�cache�values�vg_namerQ�attrr\�format)r%ra�lv_infor#r&r&r'rl�s zLVMVolumeGroupDevice.statuscCst|j�dkS)Nr)rPr])r%r&r&r'�is_empty�szLVMVolumeGroupDevice.is_emptycCs,|jr|jrtjd|j��tj||d�S)Nz4cannot activate VG %s -- some of its PVs are missing)�orig)rArqr
rmrQr�
_pre_setup)r%ryr&r&r'rz�szLVMVolumeGroupDevice._pre_setupcCs(t||j|j|jd�tjj|j�dS)z  Close, or tear down, a device. )rl�controllableN)rrQrlr{r<r	�vgdeactivate)r%�	recursiver&r&r'�	_teardown�s
zLVMVolumeGroupDevice._teardowncCs�t||j|jd�dd�|jD�}t�}|jr6d|d<tjj|j||j	f|�|jr�t
jjr�ytjj
|j�Wq�tjk
r�}ztj|��WYdd}~Xq�Xntjddjt
jj���dS)	z Create the device. )rlcSsg|]
}|j�qSr&)rk)r9r#r&r&r'r;sz0LVMVolumeGroupDevice._create.<locals>.<listcomp>r>rRNz%Shared LVM is not fully supported: %s�,)rrQrlr?rdrKr<r	Zvgcreater:r�BLOCKDEV_LVM_PLUGIN_SHARED�	availableZvglock_start�LVMErrorr
�join�availability_errors)r%�pv_list�extra�errr&r&r'�_createszLVMVolumeGroupDevice._createcs d|_tt|�j�d|j_dS)NT)rErLr5�_post_creatervrA)r%)rSr&r'r�sz!LVMVolumeGroupDevice._post_createcCstj|�|jdd�dS)NT)ry)r�_pre_destroy�
setup_parents)r%r&r&r'r�s
z!LVMVolumeGroupDevice._pre_destroycCsht||j|jd�|js8x|jD]}tj|j�q WdStjj	|jd�tjj
|j�tjj|j�dS)z Destroy the device. )rlN)rrQrlrqr\r	Zlvm_devices_addrkr<�vgreducer|Zvgremove)r%r#r&r&r'�_destroy szLVMVolumeGroupDevice._destroycCs�g}x(|jD]}|j|j�|jr|j�qW|jj�|jj|jjkrVt	j
j|j�t	j
j
|j|j�x,t|j|�D]\}}|jrv|rv|j�qvWdS)N)r]�appendrlrA�setuprvZupdate_size_infor.�current_sizer<r	�pvmoverkr�rQ�zip�teardown)r%�memberrlrar&r&r'�_remove0s
zLVMVolumeGroupDevice._removecCstjj|j|j�dS)N)r<r	ZvgextendrQrk)r%r�r&r&r'�_addAszLVMVolumeGroupDevice._addcCs||jkrtd��|jrF|jrF|jp,|jrF|j|jkrFtj	d��t
jd|j|j|j�|jj
|�t|dd�}|r�|jj
|�|j�s|jdd�}|jr�|j|jj�|�rxL|D]D}|jjj|jkr�d|jj|jf}tj	|��|jjj|j8_q�WdS)z Add an LV to this VG. zlv is already part of this vgz(new lv is too large to fit in free spacezAdding %s/%s to %s�originNz9not enough space in the '%s' PV for the '%s' LV's extents)rC�
ValueErrorrA�growable�
is_thin_lv�	is_vdo_lvr$rYr
rm�log�debugrQr��getattr�	snapshots�
pv_space_used�cached�extendrrr#rvr.)r%rar��pv_sizes�	size_spec�msgr&r&r'�_add_log_volDs&
*


z!LVMVolumeGroupDevice._add_log_volcCs�||jkrtd��|jj|�t|dd�}|r:|jj|�|jdd�}|jr\|j|j	j�|j
r�|r�x |D]}|jjj
|j7_
qnWdS)z Remove an LV from this VG. z#specified lv is not part of this vgr�N)r]r�rC�remover�r�r�r�r�rrrAr#rvr.r$)r%rar�r�r�r&r&r'�_remove_log_voles

z$LVMVolumeGroupDevice._remove_log_volcstt|�j|�|js$|jr�|jr�tt�}x0dd�|j|gD�D]\}}||j|�qDWt	|j
��dkr�|js�d|j}x6|j
�D]}|ddj||�|f7}q�Wn
d|j}t
j|��|jr�|jjr�t	|j�d|jkr�d|_|jj�s|j|�|j_|j|j_dS)	NcSsg|]}|j|jf�qSr&)�sector_sizerQ)r9rUr&r&r'r;sz4LVMVolumeGroupDevice._add_parent.<locals>.<listcomp>rzTCannot create volume group '%s'. The following disks have inconsistent sector size:
z%s: %d
z, z�Disk %s cannot be added to this volume group. LVM doesn't allow using physical volumes with inconsistent (logical) sector sizes.T)rLr5�_add_parentrArEr�listr\r�rP�keysrQr�r
ZInconsistentPVSectorSizervr?rG�_get_pv_usable_spacer.rt)r%�parentZsector_sizesZssrQr�r�)rSr&r'r�ys(  

z LVMVolumeGroupDevice._add_parentcs,tt|�j|�d|j_d|j_d|j_dS)N)rLr5�_remove_parentrvr.Zcontainer_uuidrt)r%r�)rSr&r'r��sz#LVMVolumeGroupDevice._remove_parentcCsl|jstd��||kr"td|��tj|�s>td||jf��|shtjj||�x|jD]}||j_	qXWdS)z Rename this device
        zdevice has not been createdzdevice is already named '%s'z'%s' is not a valid name for %sN)
rAr�r	�is_lvm_name_valid�typer<Zvgrenamer\rvrt)r%�old_name�new_name�dry_runr#r&r&r'�_rename�s
zLVMVolumeGroupDevice._renamecCs$d}|jr dd�|jD�r d}|S)zB Return True if the VG has changes queued that LVM is unaware of. TcSsg|]}|js|�qSr&)rA)r9rfr&r&r'r;�sz4LVMVolumeGroupDevice.is_modified.<locals>.<listcomp>F)rAr\)r%rWr&r&r'r_�sz LVMVolumeGroupDevice.is_modifiedcCs|jS)N)rO)r%r&r&r'�thpool_reserve�sz#LVMVolumeGroupDevice.thpool_reservecCs&|dk	rt|t�rtd��||_dS)Nz?Invalid thpool_reserve given, must be of type ThPoolReserveSpec)�
isinstancer/r�rO)r%�valuer&r&r'r��scCs�td�}|jdkr(|jtd�|j}n|jtd�kr<|j}|jr�tdd�|jD��r�|tt	|jj
td�|j|jj�|jj	�7}||j7}|j|dd�S)z Reserved space in this VG rz0.01css|]}|jVqdS)N)�is_thin_pool)r9rar&r&r'�	<genexpr>�sz6LVMVolumeGroupDevice.reserved_space.<locals>.<genexpr>g{�G�z�?T)�roundup)
rrMrr$rNrO�anyrCr1r2r0�pmspare_size�align)r%Zreservedr&r&r'rc�s

z#LVMVolumeGroupDevice.reserved_spacecCs|jrtd��||_dS)Nz+Can't set reserved space for an existing VG)rAr�rN)r%r�r&r&r'rc�scCs|jS)z& Reserved space in this VG in percent )rM)r%r&r&r'rb�sz%LVMVolumeGroupDevice.reserved_percentcCs|jrtd��||_dS)Nz-Can't set reserved percent for an existing VG)rAr�rM)r%r�r&r&r'rb�scCs:t|t�r"|j|jd|jj�S|j|j|jj�SdS)Nr)r�rr�r$rvZpe_start)r%r#r&r&r'r��s
z)LVMVolumeGroupDevice._get_pv_usable_spacecCs0td�}x"|jD]}||j|j|�7}qW|S)z? The amount of the space LVM metadata cost us in this VG's PVs r)rr\r$r�)r%Zdiffr#r&r&r'�lvm_metadata_space�sz'LVMVolumeGroupDevice.lvm_metadata_spacecCs"tdd�|jD��}||j8}|S)z The size of this VG css|]}|jVqdS)N)r$)r9r#r&r&r'r�sz,LVMVolumeGroupDevice.size.<locals>.<genexpr>)�sumr\r�)r%r$r&r&r'r$s
zLVMVolumeGroupDevice.sizecCst|j|j�S)z Number of extents in this VG )�intr$r:)r%r&r&r'rXszLVMVolumeGroupDevice.extentscCsTtjd|j|j�tdd�|jD�td��}||j7}|j|}tjd|j|�|S)z& The amount of free space in this VG. z
%s size is %scss|]}|jVqdS)N)�
vg_space_used)r9rar&r&r'r�sz2LVMVolumeGroupDevice.free_space.<locals>.<genexpr>rzvg %s has %s free)r�r�rQr$r�r]rrc)r%�usedr.r&r&r'rYs

zLVMVolumeGroupDevice.free_spacecCst|j|j�S)z( The number of free extents in this VG. )r�rYr:)r%r&r&r'rZ%sz!LVMVolumeGroupDevice.free_extentscs�fdd��jD�S)zw
        :returns: information about sizes and free space in this VG's PVs
        :rtype: list of PVFreeInfo

        cs"g|]}t|�j|�|jj��qSr&)r-r�rvr.)r9r#)r%r&r'r;2sz5LVMVolumeGroupDevice.pv_free_info.<locals>.<listcomp>)r\)r%r&)r%r'�pv_free_info+s
z!LVMVolumeGroupDevice.pv_free_infocCs"tj|�}|j|j|rtntd�S)z5 Align a size to a multiple of physical extent size. )Zrounding)rrFZround_to_nearestr:rr)r%r$r�r&r&r'r�5s
zLVMVolumeGroupDevice.aligncCs|jdd�S)z A list of this VG's PVs N)r?)r%r&r&r'r\:szLVMVolumeGroupDevice.pvscCs|jdd�S)z A list of this VG's LVs N)rC)r%r&r&r'r]?szLVMVolumeGroupDevice.lvscCsdd�|jD�S)NcSsg|]}|jr|�qSr&)r�)r9rVr&r&r'r;Fsz2LVMVolumeGroupDevice.thinpools.<locals>.<listcomp>)rC)r%r&r&r'�	thinpoolsDszLVMVolumeGroupDevice.thinpoolscCsdd�|jD�S)NcSsg|]}|jr|�qSr&)r�)r9rVr&r&r'r;Jsz0LVMVolumeGroupDevice.thinlvs.<locals>.<listcomp>)rC)r%r&r&r'�thinlvsHszLVMVolumeGroupDevice.thinlvscCsdd�|jD�S)NcSsg|]}|jr|�qSr&)r�)r9rVr&r&r'r;Nsz3LVMVolumeGroupDevice.cached_lvs.<locals>.<listcomp>)rC)r%r&r&r'�
cached_lvsLszLVMVolumeGroupDevice.cached_lvscCsFttd�f�}x.|jD]$}|j|j�|jr|j|jj�qWt|�S)z�Size of the pmspare LV LVM creates in every VG that contains some metadata
        (even internal) LV. The size of such LV is equal to the size of the
        biggest metadata LV in the VG.

        r)	�setrr]�add�
metadata_sizer�rr�md_sizer2)r%Zmd_sizesrar&r&r'r�Ps	z!LVMVolumeGroupDevice.pmspare_sizecCs|jr
dS|jp|jS)zWCheck if the vg has all its pvs in the system
        Return True if complete.
        F)rDrErA)r%r&r&r'rq`szLVMVolumeGroupDevice.completecCsdS)z% Is this device directly accessible? Fr&)r%r&r&r'�directkszLVMVolumeGroupDevice.directcs|jr
dStt|�jS)NT)rJrLr5�	protected)r%)rSr&r'r�pszLVMVolumeGroupDevice.protectedcCs
||_dS)N)Z
_protected)r%r�r&r&r'r�wscs2|rx|jD]}d|j_qWtt|�j|d�dS)N)�	modparent)r\rvrtrLr5�remove_hook)r%r�r#)rSr&r'r�{sz LVMVolumeGroupDevice.remove_hookcs8tt|�j|d�|rdSx|jD]}|j|j_q"WdS)N)�new)rLr5�add_hookr\rQrvrt)r%r�r#)rSr&r'r��s
zLVMVolumeGroupDevice.add_hookcsJtt|�j|�|j|_dd�|jD�|_|j|_|jsF|j	j
t�|_dS)NcSsg|]}d|j�qS)zpv.%d)�id)r9rUr&r&r'r;�sz8LVMVolumeGroupDevice.populate_ksdata.<locals>.<listcomp>)
rLr5�populate_ksdatarQ�vgnamer?ZphysvolsrA�preexistr:�
convert_torZpesize)r%�data)rSr&r'r��sz$LVMVolumeGroupDevice.populate_ksdatacCs
tj|�S)N)r	r�)r%rQr&r&r'�
is_name_valid�sz"LVMVolumeGroupDevice.is_name_valid)NNNNNNNNFr>FF)F)N)F)F)T)T)=r)r*r+r,�_type�	_packages�propertyZ_format_class_nameZ_format_uuid_attrZ_format_immutable�
_renamable�staticmethodr=r(r^rdrirkrnrlrxrzr~r�r�r�r�r�r�r�r�r�r�r�r_r��setterrcrbr�r�r$rXrYrZr�r�r\r]r�r�r�r�rqr�r�r�r�r�r��
__classcell__r&r&)rSr'r5TszB


!
	



r5cs�eZdZdZdZdgZejgZdddd�Z	dVdd
�Z
dd�Zedd��Z
edd��Zedd��Zedd��Zedd��Zedd��Zedd��Zedd��Ze�fd d!��Zed"d#��Zed$d%��Zed&d'��Zed(d)��Zed*d+��Zed,d-��Zed.d/��Zed0d1��Zd2d3�Z�fd4d5�Z�fd6d7�Z d8d9�Z!dW�fd:d;�	Z"dXd<d=�Z#dYd>d?�Z$d@dA�Z%dBdC�Z&dZdDdE�Z'edFdG��Z(edHdI��Z)e�fdJdK��Z*dLdM�Z+dNdO�Z,�fdPdQ�Z-edRdS��Z.edTdU��Z/�Z0S)[�LVMLogicalVolumeBasezAbstract base class for LVM LVs

    Attributes, properties and methods defined in this class are common too all
    LVs.

    Zlvmlvr6r��_set_compression�_set_deduplication)rQ�compression�
deduplicationNFr>rc	s�|s�|ddddddddgtjkr.td|��|rL|tjkrL|
rLtd	��nL|sZ|dkr�|
r�td
d�|
D��sztd��ntd
d�|
D��|kr�td��g�_tj�||||||d�tj�||||||d�|�_	|p�d�_
d�_d�_|�_
d�_td��_td��_d�_�j�sB|	�_ttj|
���_�j�_tj|��_�j�rv�j
jd)��rv�jj�_�j�j8_n:�j
d*k�r��j�r�|�r�|	�r��j�n
td��_g�_|�_�j�r|�r�td��|�s�|
�s�|�r�td��|�r�td��t�fdd��jD���rtd��d�_|�r��j�r�|j t!j"k�r\t#�|j$d|j%|j&d��_n$|j t!j'k�r�t(�|j$d|j%d��_g�_)|
�p�g}
x^|
D]V}t*|t+��r��j)j,|�n6t*|t-��r؈j)j,t+|td���ntd|�j.f���q�Wt/dd��j)D��j0t/�jj1���sVdd�t/d d��j)D��j2t/�jj1��D�}d!|�j.f}t|���j)�rf�j3�|�_4�j�r��j4�r��j
tjk�r�t5j6d"���j
d+k�r�t5j6d'���j7�r�t5j6d(��dS),N�linear�thin�	thin-poolrrzvdo-pool�vdoz
cache-poolz'Invalid or unsupported segment type: %sz3List of PVs has to be given for every non-linear LVcss|]}t|t�VqdS)N)r�r")r9r#r&r&r'r��sz0LVMLogicalVolumeBase.__init__.<locals>.<genexpr>z�Invalid specification of PVs for a linear LV: either no or complete specification (with all space split into PVs has to be givencss|]}|jVqdS)N)r$)r9�specr&r&r'r��szqInvalid specification of PVs for a linear LV: the sum of space assigned to PVs is not equal to the size of the LV)r$�fmtrBr?rAr�raid�mirror�
cache_poolz*Only new LVs can be created from other LVsz&Cannot specify size for a converted LVz(Cannot specify format for a converted LVc3s|]}|j�jkVqdS)N)�vg)r9ra)r%r&r'r��sz+Conversion of LVs only possible inside a VGF)r$rAr\�mode)r$rAr\z$Invalid PV spec '%s' for the '%s' LVcss|]}|jVqdS)N)r#)r9r�r&r&r'r�scSsg|]
}|j�qSr&)rQ)r9�rr&r&r'r;sz1LVMLogicalVolumeBase.__init__.<locals>.<listcomp>css|]}|jVqdS)N)r#)r9r�r&r&r'r�sz&invalid destination PV(s) %s for LV %sz2Stripe size can be specified only for RAID volumes�raid1�RAID1�1rz9Specifying stripe size is not allowed for RAID1 or mirrorz<Creating cached LVs with custom stripe size is not supported)r�r�)r�r�)r�r�r�rr�)8r	�raid_seg_typesr��allr�r�rr(rr@�seg_type�_raid_level�ignore_skip_activationrK�req_growr�req_max_size�req_size�req_percentrArrF�_size�
startswithr�r:�_metadata_size�autoset_md_size�
_internal_lvs�	_from_lvsr��_cache�
cache_type�LVMCacheType�lvmcache�LVMCacher$�	fast_devsr��
lvmwritecache�
LVMWriteCache�	_pv_specsr�r"r�rrQr��issubsetr?�
difference�_assign_pv_space�_stripe_sizer
rmrr)r%rQr?r$r@r�r�rArB�grow�maxsizer0�
cache_requestr\�from_lvs�stripe_sizerR�pv_specZmissingr�r&)r%r'r(�s�











$&

zLVMLogicalVolumeBase.__init__cCs<|js
dSx,|jD]"}|jj|j|jt|j��|_qWdS)N)�
is_raid_lvr�
raid_levelZget_base_member_sizer$r�rP)r%r�r&r&r'rsz%LVMLogicalVolumeBase._assign_pv_spacecCs|jjS)N)r�r\)r%r&r&r'�membersszLVMLogicalVolumeBase.memberscCs|jS)N)r)r%r&r&r'r!szLVMLogicalVolumeBase.from_lvscCs<|j}|jdkr2x |jD]}|jtjkr|j}qW|tjkS)Nrr)r�r�int_lv_type�LVMInternalLVtyper�r	r�)r%r�rar&r&r'r&s

zLVMLogicalVolumeBase.is_raid_lvcCsn|jdk	r|jS|j}|jr@x"|jD]}|jtjkr$|j}Pq$W|tjkrZtj	j
|�|_ntj	j
d�|_|jS)Nr�)r�r�r�rrrr�r	r�Zraid_levelsr)r%r�rar&r&r'r1s

zLVMLogicalVolumeBase.raid_levelcCs|jr|jdSdSdS)z#This Logical Volume's Volume Group.rN)�_parents)r%r&r&r'r�Fs
zLVMLogicalVolumeBase.vgcCsl|jr^|jr@x |jD]}|jtjkr|jSqWtjd|j	�dSdd�|jD�}t
|�pZdSn
t
|j�SdS)Nz<An existing cached LV '%s' has no internal LV of type originrcSs"g|]}|jr|jtjkr|�qSr&)�is_internal_lvrr�image)r9�int_lvr&r&r'r;^sz5LVMLogicalVolumeBase.num_raid_pvs.<locals>.<listcomp>)rAr�rrrr��num_raid_pvsr��warningrQrPr)r%raZ	image_lvsr&r&r'rNs
z!LVMLogicalVolumeBase.num_raid_pvscCs&dd�|jD�}ttdd�|D���S)Ncss$|]}|jr|jtjkr|VqdS)N)rrrr�)r9rr&r&r'r�fsz0LVMLogicalVolumeBase.log_size.<locals>.<genexpr>css|]}|jVqdS)N)r$)r9rar&r&r'r�hs)rrr�)r%Zlog_lvsr&r&r'�log_sizedszLVMLogicalVolumeBase.log_sizecCs2|jr,dd�|jD�}ttdd�|D���S|jS)za Size of the meta data space this LV has available (see also :property:`metadata_vg_space_used`) css$|]}|jr|jtjkr|VqdS)N)rrr�meta)r9rr&r&r'r�nsz5LVMLogicalVolumeBase.metadata_size.<locals>.<genexpr>css|]}|jVqdS)N)r$)r9rar&r&r'r�ps)rrr�r�)r%Zmd_lvsr&r&r'r�jsz"LVMLogicalVolumeBase.metadata_sizecs8tt|�j}|jr$|jd|ji�n|jd|ji�|S)N�vgspacer0)rLr�rdrArer�r�)r%rf)rSr&r'rdts
zLVMLogicalVolumeBase.dictcCs|jo|jj�S)N)rZhas_redundancy)r%r&r&r'�mirrored~szLVMLogicalVolumeBase.mirroredcCs|j|jS)z5 Space occupied by this LV, not including snapshots. )�data_vg_space_used�metadata_vg_space_used)r%r&r&r'r��sz"LVMLogicalVolumeBase.vg_space_usedcCs�|jrv|jrvtd�}g}xF|jD]<}|jtjkr<||j7}q |jtjtjfkrRq q |j	|�q W|t
dd�|D��S|jr�|jj
}ntd�}|jj|j
dd�}|jr�dd�}y|jj||j|d�}||Stjk
r�||SXn||Sd	S)
zE Space occupied by the data part of this LV, not including snapshots rcss|]}|jVqdS)N)r%)r9rar&r&r'r��sz:LVMLogicalVolumeBase.data_vg_space_used.<locals>.<genexpr>T)r�cSstd�S)Nr)r)�xr&r&r'r8�sz9LVMLogicalVolumeBase.data_vg_space_used.<locals>.<lambda>)�superblock_size_funcN)rArrrrrr�r"r�r�r�r�rrr$r�r�rr�	get_spacerr
�	RaidError)r%Z
image_lvs_sum�complex_int_lvsra�
cache_sizeZrounded_size�zero_superblockZraided_sizer&r&r'r%�s.
z'LVMLogicalVolumeBase.data_vg_space_usedcCs�|jrv|jrvtd�}g}xF|jD]<}|jtjkr4q q |jtjtjfkrR||j7}q |j	|�q W|t
dd�|D��S|jr�|jj
}ntd�}|j|j}|r�|jr�dd�}y|jj||j|d�}||Stjk
r�||SX||S)zL Space occupied by the metadata part(s) of this LV, not including snapshots rcss|]}|jVqdS)N)r&)r9rar&r&r'r��sz>LVMLogicalVolumeBase.metadata_vg_space_used.<locals>.<genexpr>cSstd�S)Nr)r)r'r&r&r'r8�sz=LVMLogicalVolumeBase.metadata_vg_space_used.<locals>.<lambda>)r()rArrrrrr"r�r�r�r�r�rrr�r�r!rrr)rr
r*)r%Zmeta_lvs_sumr+raZcache_mdZ
non_raid_baser-Zraided_spacer&r&r'r&�s.


z+LVMLogicalVolumeBase.metadata_vg_space_usedcCs|jS)z}
        :returns: space occupied by this LV on its VG's PVs (if we have and idea)
        :rtype: list of LVPVSpec

        )r)r%r&r&r'r��sz"LVMLogicalVolumeBase.pv_space_usedcCs|jS)N)r�)r%r&r&r'�	container�szLVMLogicalVolumeBase.containercCsd|jj|jjdd�fS)z& This device's device-mapper map name z%s-%srgz--)r�ri�_namerh)r%r&r&r'ri�szLVMLogicalVolumeBase.map_namecCsd|j|jfS)z' Device node representing this device. z%s/%s)rjri)r%r&r&r'rk�szLVMLogicalVolumeBase.pathcCs0t||j|jd�|js"tjd��tjj|j	�S)z9 Return the dm-X (eg: dm-0) device node for this device. )rlzdevice has not been created)
rrQrlrAr
rmr<�dmZnode_from_nameri)r%r&r&r'�get_dm_node�s
z LVMLogicalVolumeBase.get_dm_nodecs.|jdk	rd|jj|jfStt|�j�SdS)z This device's name. Nz%s-%s)r�rQr/rLr��	_get_name)r%)rSr&r'r2�s
zLVMLogicalVolumeBase._get_namecsD|jr0|jd|jj�r0|t|jj�dd�}tt|�j|�dS)zNSet the device's name.

            :param value: the new device name
        z%s-rN)r�r�rQrPrLr��	_set_name)r%r�)rSr&r'r3�szLVMLogicalVolumeBase._set_namecCsZ|jjr|j|jjkrdS|jjr8|jr8|j|jjksR|jrV|jrV|j|jjkrVdSdS)z� Check to make sure the size of the device is allowed by the
            format used.

            Returns:
            0  - ok
            1  - Too large
            -1 - Too small
        rr���)rv�max_sizer$�min_sizer�r�)r%r&r&r'�
check_size
s	zLVMLogicalVolumeBase.check_sizecs�tj�otdd�|jjD��}tt|�j|d�s4dS|r�tj	d|j
�d}tj�}xDtj�||kr�|jr|tj	d|j
�dStj	d|j
�tj
d	�qTWtj	d
|j
�dS)Ncss|]}|jjVqdS)N)rvrl)r9r#r&r&r'r�"sz2LVMLogicalVolumeBase._pre_setup.<locals>.<genexpr>)ryFz%waiting for lvm auto-activation of %s�z%s has been auto-activatedz%s not active yet; sleeping...g�?z*lvm auto-activation timeout reached for %sT)r	Zlvmetad_socket_existsr�r�r\rLr�rzr�r�rQ�timerlZsleep)r%ryZ
auto_activateZtimeout�start)rSr&r'rzs zLVMLogicalVolumeBase._pre_setupcCs.t||j|j|jd�tjj|jj|j�dS)z  Close, or tear down, a device. )rlr{N)	rrQrlr{r<r	Zlvdeactivater�r/)r%r}r&r&r'r~=s
zLVMLogicalVolumeBase._teardowncCsFytj||d�Wn.tjk
r@|r:tjd|jj�n�YnXdS)N)r}z!vg %s teardown failed; continuing)r�_post_teardownr
ZStorageErrorr�r�r�rQ)r%r}r&r&r'r;Csz#LVMLogicalVolumeBase._post_teardowncCstj|�|jjdd�dS)NT)ry)rr�r�r�)r%r&r&r'r�Os
z!LVMLogicalVolumeBase._pre_destroycCstj|jj|j�dS)z; Run lvchange as needed to ensure the lv is not read-only. N)r	Zensure_lv_is_writabler�rQ�lvname)r%r&r&r'�set_rwTszLVMLogicalVolumeBase.set_rwcCs�|jstd��|jstd��|jd|jj�rF|t|jj�dd�}|jd|jj�rp|t|jj�dd�}||kr�td|��tj|j�s�td||jf��|s�t	jj
|jj||�dS)z Rename this device
        zdevice has not been createdzdevice is not in a volume groupz%s-rNzdevice is already named '%s'z'%s' is not a valid name for %s)rAr�r�r�rQrPr	r�r�r<Zlvrename)r%r�r�r�r&r&r'r�XszLVMLogicalVolumeBase._renamecCs|jS)z( The LV's name (not including VG name). )r/)r%r&r&r'r<pszLVMLogicalVolumeBase.lvnamecCs|jjS)z) Test if vg exits and if it has all pvs. )r�rq)r%r&r&r'rquszLVMLogicalVolumeBase.completecs&tdd�|jD��}tt|�jo$|S)Ncss|]}|js|VqdS)N)r�)r9r7r&r&r'r�~sz.LVMLogicalVolumeBase.isleaf.<locals>.<genexpr>)r�r�rLr��isleaf)r%Znon_thin_snapshots)rSr&r'r>zszLVMLogicalVolumeBase.isleafcCs||jkr|jj|�dS)N)rr�)r%rr&r&r'�add_internal_lv�s
z$LVMLogicalVolumeBase.add_internal_lvcCs4||jkr|jj|�nd|j|jf}t|��dS)Nz?the specified internal LV '%s' doesn't belong to this LV ('%s'))rr��lv_namerQr�)r%rr�r&r&r'�remove_internal_lv�s


z'LVMLogicalVolumeBase.remove_internal_lvcs�tt|�j|�|jj|_|j|_|j|_|jo@|j	o@|j	|j
k|_|js�|j|_
|jrb|j|_n$|jrx|jjt�|_n|jjt�|_|jr�|jjt�|_n|jr�|j	jt�|_dS)N)rLr�r�r�rQr�r<rAr�Ztarget_sizer��resizer�rr�r0r�r�rr$r�Z	maxSizeMB)r%r�)rSr&r'r��s"

z$LVMLogicalVolumeBase.populate_ksdatacCs
t|j�S)N)�boolrr)r%r&r&r'r��szLVMLogicalVolumeBase.cachedcCsn|jrh|jrhxX|jD]N}|jtjkr|jdkrHt||j|j	dd�|_q|jdkrt
||jdd�|_qW|jS)NrrT)r$r�rA�
writecache)r$rA)rArrrrr�r�rr$r�r
)r%rar&r&r'rr�s

zLVMLogicalVolumeBase.cache)NNNNNFr>NNNNNNrF)F)N)F)F)1r)r*r+r,r�r�r�BLOCKDEV_LVM_PLUGIN�_external_dependenciesZconfig_actions_mapr(rr�rrrrr�rr!r�rdr$r�r%r&r�r.rirkr1r2r3r7rzr~r;r�r=r�r<rqr>r?rAr�r�rrr�r&r&)rSr'r��s^
k

()	 


r�c@s4eZdZdZdZdZdZdZdZdZ	e
dd	��Zd
S)rrr�ro���ccCs�|jd
|jd|jd|jd|jd|jdi}|d
dkrL|ddkrF|jS|jS|d
dkr||ddkrj|jS|ddkr||jSx$|j�D]\}}|d
|kr�|Sq�W|jS)N�T�C�D�erV�L�i�I�orrIr�)rKrLrM)rN)rVrO)rPrQ)rR)rL)r�r"r�rr�r��items�unknown)�clsZlv_attrr@Zattr_letters�lv_typeZlettersr&r&r'�get_type�s&
zLVMInternalLVtype.get_typeN)r)r*r+r�r"r�rr�r�rT�classmethodrWr&r&r&r'r�src@sbeZdZdd�Zdd�Zedd��Zedd��Zed	d
��Zej	dd
��Zee
jd�d
d���Zej	e
jd�dd���Zee
jd�dd���Z
ee
jd�dd���Zedd��Zej	dd��Zedd��Zedd��Zdd�Zdd�Zdd �Zd!d"�Zd#d$�Zed%d&��Zd:d(d)�Zd;d+d,�Zd-d.�Zed/d0��Zed1d2��Zd<d4d5�Zd=d6d7�Zed8d9��Zd*S)>�LVMInternalLogicalVolumeMixincCs&||_||_||_|r"|jj|�dS)N)�_vg�
_parent_lv�_lv_typer?)r%r��	parent_lvrVr&r&r'r(�s
z&LVMInternalLogicalVolumeMixin.__init__cCs|jr|jrtd��dS)Nz%an internal LV should have no parents)r[rr�)r%r&r&r'�_init_check�sz)LVMInternalLogicalVolumeMixin._init_checkcCst|jp|j�S)N)rCr[r\)r%r&r&r'r�sz,LVMInternalLogicalVolumeMixin.is_internal_lvcCs|jr|jjS|jSdS)N)r[r�rZ)r%r&r&r'r��sz LVMInternalLogicalVolumeMixin.vgcCs|jS)N)r[)r%r&r&r'r]�sz'LVMInternalLogicalVolumeMixin.parent_lvcCs8|jr|jj|�||_|jr4|jj|�|jj|_dS)N)r[rAr?r�rZ)r%r]r&r&r'r]srcCs|jS)N)r\)r%r&r&r'r	sz)LVMInternalLogicalVolumeMixin.int_lv_typecCs
||_dS)N)r\)r%rVr&r&r'rscCs|jtjtjtjfkS)N)r\rr"r�r�)r%r&r&r'�takes_extra_spacesz/LVMInternalLogicalVolumeMixin.takes_extra_spacecCs4tjdtjdtjdtjdtjdtjdi}|j|j�S)Nz	_[tc]dataz_[trc]meta(_[0-9]+)?�_mlogz_[rm]image(_[0-9]+)?z_c?origz_cache(_?pool)?)	rr�r"r�rr�r��getr\)r%�suffixesr&r&r'�name_suffixs
z)LVMInternalLogicalVolumeMixin.name_suffixcCsdS)NTr&)r%r&r&r'�readonly%sz&LVMInternalLogicalVolumeMixin.readonlycCstd��dS)Nz%Cannot make an internal LV read-write)r�)r%r�r&r&r'rd)scCsdS)NZ
lvminternallvr&)r%r&r&r'r�-sz"LVMInternalLogicalVolumeMixin.typecCs@tjj|�r8|jtjkr8|jr&|jjStj	d|j
�SndSdS)Nz	_[rc]metaF)r�	resizable�__get__r\rr"r[r��re�searchr<)r%r&r&r're1s
z'LVMInternalLogicalVolumeMixin.resizablecCsN|jtjk	rtjd|j��|jr,|jjs:tj	d|j�rDtjd��t
��dS)Nz$The internal LV %s cannot be resizedz	_[rc]metaz;RAID and cache pool metadata LVs cannot be resized directly)r\rr"r
rmr<r[r�rgrhr4)r%r&r&r'rB<s
z$LVMInternalLogicalVolumeMixin.resizecCsdS)NTr&)r%rQr&r&r'r�Gsz+LVMInternalLogicalVolumeMixin.is_name_validcCs|jrtd��dS)Nz%an internal LV should have no parents)rr�)r%r&r&r'�_check_parentsLsz,LVMInternalLogicalVolumeMixin._check_parentscCsdS)Nr&)r%r&r&r'�_add_to_parentsQsz-LVMInternalLogicalVolumeMixin._add_to_parentscCs@t|t�std��|js6||jjkr,||_q<td��nt��dS)Nznew size must of type Sizez/Internal LV cannot be bigger than its parent LV)r�rr�r_r]r$r�r4)r%�newsizer&r&r'�	_set_sizeWs

z'LVMInternalLogicalVolumeMixin._set_sizecCs |js|jjS|j|jjSdS)N)r_r[r5r$r�rY)r%r&r&r'r5dsz&LVMInternalLogicalVolumeMixin.max_sizeFcCs|jjrtjd��dS)Nz*An internal LV cannot be set up separately)r[rAr
rm)r%ryr&r&r'r�nsz#LVMInternalLogicalVolumeMixin.setupNcCs|jjrtjd��dS)Nz-An internal LV cannot be torn down separately)r[rAr
rm)r%r}r&r&r'r�ssz&LVMInternalLogicalVolumeMixin.teardowncCs|jjrtjd��dS)Nz-An internal LV cannot be destroyed separately)r[rAr
rm)r%r&r&r'�destroyxsz%LVMInternalLogicalVolumeMixin.destroycCsdS)NFr&)r%r&r&r'r�}sz&LVMInternalLogicalVolumeMixin.growablecCs
d|jS)z9Name of the internal LV as displayed by the lvm utilitiesz[%s])r<)r%r&r&r'�display_lvname�sz,LVMInternalLogicalVolumeMixin.display_lvnameTcCstj||d�|jj|�dS)N)r�)rr�r[r?)r%r�r&r&r'r��sz&LVMInternalLogicalVolumeMixin.add_hookcCs"|r|jj|�tj||d�dS)N)r�)r[rArr�)r%r�r&r&r'r��sz)LVMInternalLogicalVolumeMixin.remove_hookcCsdS)NFr&)r%r&r&r'r��sz$LVMInternalLogicalVolumeMixin.direct)F)N)T)T) r)r*r+r(r^r�rr�r]r�r�requires_propertyrr_rcrdr�rerBr�rirjrlr5r�r�rmr�rnr�r�r�r&r&r&r'rY�s@	






	rYc@s�eZdZd&dd�Zdd�Zedd��Zed	d
��Zedd��Zed
d��Z	dd�Z
ejd�dd��Z
ejd�dd��Zdd�Ze
d'dd��Ze
d(dd��Zdd�Zdd�Ze
d d!��Zd"d#�Ze
d$d%��ZdS))�LVMSnapshotMixinNFcCs||_||_dS)N)r��vorigin)r%r�rqr&r&r'r(�szLVMSnapshotMixin.__init__cCs�|js
dS|jr&t|jt�r&td��|jr<|jr<td��t|jt�rrt|jdt�rr|jj	|jdkrrtd��|j
r�|jr�|jr�|jr�td��dS)Nz,lvm snapshot origin must be a logical volumez-only existing vorigin snapshots are supportedrz.lvm snapshot and origin must be in the same vgz.thin snapshot size is determined automatically)�is_snapshot_lvr�r��LVMLogicalVolumeDevicer�rqrAr?r5r�r�r$)r%r&r&r'r^�szLVMSnapshotMixin._init_checkcCst|jp|j�S)N)rCr�rq)r%r&r&r'rr�szLVMSnapshotMixin.is_snapshot_lvcCs|jr
dSdSdS)NZlvmthinsnapshotZlvmsnapshot)r�)r%r&r&r'r��szLVMSnapshotMixin.typecCs|jr
dSt��dS)NF)r�r4)r%r&r&r're�szLVMSnapshotMixin.resizablecCsdS)NFr&)r%r&r&r'�format_immutable�sz!LVMSnapshotMixin.format_immutablecst���fdd��}|S)z=Decorator for methods that are specific only to old snapshotscs"|jrt��n�|f|�|�SdS)N)r�r4)r%�args�kwargs)�methr&r'�	decorated�sz9LVMSnapshotMixin.old_snapshot_specific.<locals>.decorated)r)rwrxr&)rwr'�old_snapshot_specific�sz&LVMSnapshotMixin.old_snapshot_specificrrcCs�t||j|jd�|jj�y|jj�Wntjk
r@YnXy|j�Wntjk
rdYnXt	j
�tjj
|jj|j�dS)z1 Merge the snapshot back into its origin volume. )rlN)rrQrlr�r�r�r�r
ZFSErrorr
�settler<r	Zlvsnapshotmerger<)r%r&r&r'�merge�s
zLVMSnapshotMixin.mergecCsN|jr|jrdStj|jj�}d|_t|d�rDd|_d|_|j	|_
||_dS)a Update the snapshot's format to reflect the origin's.

            .. note::
                This should only be called for non-existent snapshot devices.
                Once a snapshot exists its format is distinct from that of its
                origin.

        NF�
mountpoint)r�rq�copy�deepcopyrvrA�hasattrr|Z_chrooted_mountpointrk�deviceZ_format)r%r�r&r&r'�_update_format_from_origin�s

z+LVMSnapshotMixin._update_format_from_origincCs(|jrt��ntjd|j�|j�dS)Nzcopying %s origin's format)rAr4r��inforQr�)r%r�r&r&r'�_set_formatszLVMSnapshotMixin._set_formatcCsT|jrP|jjrPy|jj�Wn0tjk
rN}ztjd|�WYdd}~XnXdS)Nz failed to activate origin LV: %s)r�rlr�r<r�r��error)r%ry�lvmerrr&r&r'r�s
zLVMSnapshotMixin.setupcCsdS)Nr&)r%r}r&r&r'r�szLVMSnapshotMixin.teardowncCsn|js8t||j|jd�tjj|jj|jj	|j
|j�n2d}|jjsL|jj	}tjj
|jj|jj	|j
|d�dS)z Create the device. )rlN)�	pool_name)r�rrQrlr<r	Zlvsnapshotcreater�r�r<r/r$�poolZthsnapshotcreate)r%r�r&r&r'r�s zLVMSnapshotMixin._createcCstj|�|jjj|j_dS)N)rr�r�rvrA)r%r&r&r'r�-s
zLVMSnapshotMixin._post_createcCs.t||j|jd�tjj|jj|jdd�dS)z Destroy the device. )rlT)�forceN)rrQrlr<r	�lvremover�r/)r%r&r&r'r�3szLVMSnapshotMixin._destroycCs<|jr$|j|kr|jrdSt��n|j|kr2dSt��dS)NT)r�r�rAr4)r%�depr&r&r'�
depends_on<s
zLVMSnapshotMixin.depends_oncCszt||j|j|jd�td�}|jrvtjj|j�rvtj|j|j�}tjj|�rvtjj|�rvt	tj
|d��}t|t�}|S)N)rArkrBrr$)rrArkrBr�os�isdirrZget_cow_sysfs_pathr�Zget_sysfs_attrr)r%r$Zcow_sysfs_pathZblocksr&r&r'�read_current_sizeHs
z"LVMSnapshotMixin.read_current_size)NF)F)F)r)r*r+r(r^r�rrr�rertryrror{r�r�r�r�r�r�r�r�r�r&r&r&r'rp�s&


	rpc@seZdZd,dd�Zdd�Zdd�Zdd	�Zed
d��Zedd
��Z	edd��Z
edd��Zedd��Zee
jd�dd���Zee
jd�dd���Ze
jd�dd��Ze
jd�dd��Zee
jd�dd���Zd-d d!�Zd"d#�Zd$d%�Zd&d'�Zed(d)��Zd*d+�ZdS).�LVMThinPoolMixinNcCs,|p
td�|_|ptd�|_||_g|_dS)Nr)rr��_chunk_size�_profilerC)r%r��
chunk_size�profiler&r&r'r(XszLVMThinPoolMixin.__init__cCs@|jrtjj|j�rtd��|jr<tjj|j�r<td��dS)Nzinvalid metadatasize valuezinvalid chunksize value)r�r<r	Zis_valid_thpool_md_sizer�r�Zis_valid_thpool_chunk_size)r%r&r&r'r^^szLVMThinPoolMixin._init_checkcCs |jrt|j�dkrtd��dS)Nrz&two LVs required to create a thin pool)rrPr�)r%r&r&r'�_check_from_lvsesz LVMThinPoolMixin._check_from_lvscCs2|j\}}||_tj|_||_tj|_|j|_dS)N)rr]rr�rr"r$)r%�data_lv�metadata_lvr&r&r'�_convert_from_lvsjs
z"LVMThinPoolMixin._convert_from_lvscCs
|jdkS)Nz	thin-pool)r�)r%r&r&r'r�tszLVMThinPoolMixin.is_thin_poolcCs|jS)N)r�)r%r&r&r'r�xszLVMThinPoolMixin.profilecCs|jS)N)r�)r%r&r&r'r�|szLVMThinPoolMixin.chunk_sizecCsdS)NZlvmthinpoolr&)r%r&r&r'r��szLVMThinPoolMixin.typecCsdS)NFr&)r%r&r&r're�szLVMThinPoolMixin.resizabler�cCstdd�|jD�td��S)Ncss|]}|jVqdS)N)�pool_space_used)r9rVr&r&r'r��sz.LVMThinPoolMixin.used_space.<locals>.<genexpr>r)r�r]r)r%r&r&r'�
used_space�szLVMThinPoolMixin.used_spacecCs|j|jS)N)r$r�)r%r&r&r'rY�szLVMThinPoolMixin.free_spacecCsD||jkrtd��|jj|�tjd|j|j|j�|jj|�dS)z Add an LV to this pool. zlv is already part of this vgzAdding %s/%s to %sN)	rCr�r�r�r�r�rQr$r�)r%rar&r&r'r��s

zLVMThinPoolMixin._add_log_volcCs.||jkrtd��|jj|�|jj|�dS)z Remove an LV from this pool. z#specified lv is not part of this vgN)rCr�r�r�r�)r%rar&r&r'r��s
z LVMThinPoolMixin._remove_log_volcCs|jdd�S)z A list of this pool's LVs N)rC)r%r&r&r'r]�szLVMThinPoolMixin.lvsFcCs0|jdkr|rdStjd|r"dnd�|jtd�krJtjd�d|_dS|jdksX|rttj|j�|_tjd|j�|j}|jj	}tt
jj|j|jd��|_tjd	|jjd
��|jj
|jdd�|_tjd
|jjd
��|j|kr�tjd�n>|j|j||jj	|}tjd|jjd
�|jd
��||_dS)z� If self._metadata_size not set already, it calculates the recommended value
        and sets it while subtracting the size from self.size.

        rNz&Auto-setting thin pool metadata size%sz (enforced)r>zAThin pool size not bigger than 0, just setting metadata size to 0z Using recommended chunk size: %s�dz!Recommended metadata size: %s MiBrT)r�z(Rounded metadata size to extents: %s MiBzRounded metadata size unchangedz$Adjusting size from %s MiB to %s MiB)r�r�r�r�rr�r	Zrecommend_thpool_chunk_sizer�r�r<Zget_thpool_meta_sizer�r�r$)r%�enforced�old_md_sizeZold_pmspare_size�new_sizer&r&r'r�s0


z LVMThinPoolMixin.autoset_md_sizecCs(|jr$tdd�|jD��r$tjd��dS)Ncss|]}|jVqdS)N)rA)r9rar&r&r'r��sz/LVMThinPoolMixin._pre_create.<locals>.<genexpr>z&Component LVs need to be created first)rr�r
rm)r%r&r&r'�_pre_create�szLVMThinPoolMixin._pre_createcCs�t||j|jd�|jr"|jj}nd}|jr�t�}|r>||d<|jrVtt|j��|d<t	j
dd�|jD��}t	j
dd�|jD��}tj
j|jj|j|j|jf|�n$tj
j|jj|j|j|j|j|d�dS)	z Create the device. )rlNr�Z	chunksizecss|]}|jtjkr|VqdS)N)rrr�)r9rar&r&r'r��sz+LVMThinPoolMixin._create.<locals>.<genexpr>css|]}|jtjkr|VqdS)N)rrr")r9rar&r&r'r��s)r�r�r�)rrQrlr�rrdr�rTr��six�nextrr<r	Zthpool_convertr�r<Zthpoolcreater$r�)r%Zprofile_namer�r��meta_lvr&r&r'r��s"
"zLVMThinPoolMixin._createcCst�S)N)r�)r%r&r&r'�dracut_setup_args�sz"LVMThinPoolMixin.dracut_setup_argscCsdS)z% Is this device directly accessible? Fr&)r%r&r&r'r��szLVMThinPoolMixin.directcCsHtj||�d|_d|_|jjt�|_|jjt�|_|j	rD|j	j
|_	dS)NZnoneT)r�r�r|Z	thin_poolr�r�rr�rr�rQ)r%r�r&r&r'r��sz LVMThinPoolMixin.populate_ksdata)NNN)F)r)r*r+r(r^r�r�r�r�r�r�r�rerror�rYr�r�r]rr�r�r�r�r�r&r&r&r'r�Ws.

	
'r�cs�eZdZdd�Zdd�Zdd�Zedd��Zed	d
��Zedd��Z	ee
jd
�dd���Zee
jd
�dd���Z
edd��Zdd�Z�fdd�Zdd�Zd!�fdd�	Zd"�fdd�	Zdd �Z�ZS)#�LVMThinLogicalVolumeMixincCsdS)Nr&)r%r&r&r'r(sz"LVMThinLogicalVolumeMixin.__init__cCsdS)Nr&)r%r&r&r'r^sz%LVMThinLogicalVolumeMixin._init_checkcCs^t|jttf�r2t|j�dkr&td��|jd}n|j}|sRt|t�sR|jrZtd��dS)z.Check that this device has parents as expectedrz*constructor requires a single thin-pool LVrz#constructor requires a thin-pool LVN)r�r?r�rrPr�rsr�)r%r.r&r&r'ri
sz(LVMThinLogicalVolumeMixin._check_parentscCs
|jdkS)Nr�)r�)r%r&r&r'r�sz$LVMThinLogicalVolumeMixin.is_thin_lvcCs|jjS)N)r�r�)r%r&r&r'r�szLVMThinLogicalVolumeMixin.vgcCsdS)NZ	lvmthinlvr&)r%r&r&r'r� szLVMThinLogicalVolumeMixin.typer�cCs
|jdS)Nr)r?)r%r&r&r'r�$szLVMThinLogicalVolumeMixin.poolcCs|jj|jdd�S)a The total space used within the thin pool by this volume.

            This should probably align to the greater of vg extent size and
            pool chunk size. If it ends up causing overcommit in the amount of
            less than one chunk per thin lv, so be it.
        T)r�)r�r�r$)r%r&r&r'r�)s	z)LVMThinLogicalVolumeMixin.pool_space_usedcCstd�S)Nr)r)r%r&r&r'r�4sz'LVMThinLogicalVolumeMixin.vg_space_usedcCs@t|t�std��|jj|�}|jjtj|��}tj||�dS)Nznew size must of type Size)	r�rr�r�r�rrFrrl)r%rkr&r&r'rl8s

z#LVMThinLogicalVolumeMixin._set_sizecstt|�j�dS)N)rLr�r�)r%)rSr&r'r�Bsz%LVMThinLogicalVolumeMixin._pre_createcCs4t||j|jd�tjj|jj|jj|j|j	�dS)z Create the device. )rlN)
rrQrlr<r	Z
thlvcreater�r�r<r$)r%r&r&r'r�Hsz!LVMThinLogicalVolumeMixin._createTcs&|r|jj|�tt|�j|d�dS)N)r�)r�r�rLr�r�)r%r�)rSr&r'r�Nsz%LVMThinLogicalVolumeMixin.remove_hookcs6tt|�j|d�|rdS||jjkr2|jj|�dS)N)r�)rLr�r�r�r]r�)r%r�)rSr&r'r�Us
z"LVMThinLogicalVolumeMixin.add_hookcCs tj||�d|_|jj|_dS)NT)r�r�Zthin_volumer�r<r�)r%r�r&r&r'r�^sz)LVMThinLogicalVolumeMixin.populate_ksdata)T)T)r)r*r+r(r^rir�r�r�r�rror�r�r�rlr�r�r�r�r�r�r&r&)rSr'r�s"


	r�c@s*eZdZejejgZed�Zd*dd�Z	e
dd��Ze
d	d
��Ze
dd��Ze
d
d��Ze
dd��Zejd�dd��Zejd�dd��Ze
ejd�dd���Ze
ejd�dd���Ze
ejd�dd���Ze
dd��Ze
ejd�dd���Zd d!�Zd"d#�Zd$d%�Zejd�d&d'��Zejd�d(d)��ZdS)+�LVMVDOPoolMixinz5 GiBTrNcCsJ||_||_||_||_g|_|jrF|j|jkrFtd|j|jf��dS)Nz,Requested size %s is smaller than minimum %s)	r�r��index_memory�write_policyrCrAr$r6r�)r%r�r�r�r�r&r&r'r(iszLVMVDOPoolMixin.__init__cCstdd�|jD��tj�BS)Ncss|]
}|VqdS)Nr&)r9rfr&r&r'r�xsz=LVMVDOPoolMixin.type_external_dependencies.<locals>.<genexpr>)r�rFrs�type_external_dependencies)rUr&r&r'r�vsz*LVMVDOPoolMixin.type_external_dependenciescCstdd�|j�D��S)Ncss|]}|js|VqdS)N)r�)r9rNr&r&r'r�|sz@LVMVDOPoolMixin.unavailable_type_dependencies.<locals>.<genexpr>)r�r�)rUr&r&r'�unavailable_type_dependencieszsz-LVMVDOPoolMixin.unavailable_type_dependenciescCs
|jdkS)Nzvdo-pool)r�)r%r&r&r'�is_vdo_pool~szLVMVDOPoolMixin.is_vdo_poolcCsdS)NZ
lvmvdopoolr&)r%r&r&r'r��szLVMVDOPoolMixin.typecCsdS)NFr&)r%r&r&r're�szLVMVDOPoolMixin.resizabler�cCsD||jkrtd��|jj|�tjd|j|j|j�|jj|�dS)z Add an LV to this VDO pool. z#lv is already part of this VDO poolzAdding %s/%s to %sN)	rCr�r�r�r�r�rQr$r�)r%rar&r&r'r��s

zLVMVDOPoolMixin._add_log_volcCs.||jkrtd��|jj|�|jj|�dS)z" Remove an LV from this VDO pool. z)specified lv is not part of this VDO poolN)rCr�r�r�r�)r%rar&r&r'r��s
zLVMVDOPoolMixin._remove_log_volcCs|js
dS|jdS)Nr)r)r%r&r&r'�_vdopool_data_lv�sz LVMVDOPoolMixin._vdopool_data_lvcCs|jdd�S)z A list of this VDO pool's LVs N)rC)r%r&r&r'r]�szLVMVDOPoolMixin.lvscCs|js
dS|jdS)Nr)rC)r%r&r&r'�vdo_lv�szLVMVDOPoolMixin.vdo_lvcCsdS)z% Is this device directly accessible? Fr&)r%r&r&r'r��szLVMVDOPoolMixin.directcCs|jr|jS|jS)N)rAr��	_min_size)r%r&r&r'r6�szLVMVDOPoolMixin.min_sizecCs>t|t�std��||jkr.td||jf��tj||�dS)Nznew size must of type Sizez,Requested size %s is smaller than minimum %s)r�r�AttributeErrorr6r�rrl)r%rkr&r&r'rl�s


zLVMVDOPoolMixin._set_sizecCsBt||j|j|jd�|jtd�kr*|jS|jr:|jj�Std�S)N)rArkrBr)rrArkrBr$rr�r�)r%r&r&r'r��s

z!LVMVDOPoolMixin.read_current_sizec
Csb|jstjd��|jr$tj|j�}ntjj}tjj	|j
j|jj|j|j
|jj
|j|j|j|�	dS)z Create the device. z,Cannot create new VDO pool without a VDO LV.N)r�r
rmr�r<Zlvm_get_vdo_write_policy_strZLVMVDOWritePolicyZAUTOr	Zvdo_pool_creater�rQr<r$r�r�r�)r%r�r&r&r'r��s
zLVMVDOPoolMixin._createcCs`|jstd��||kr*td|r"dnd��|s\|rHtjj|jj|j�ntjj|jj|j�dS)Nzdevice has not been createdz*compression is already %s on this VDO pool�enabled�disabled)	rAr�r<r	Zvdo_enable_compressionr�rQr<Zvdo_disable_compression)r%Znew_compressionZold_compressionr�r&r&r'r��sz LVMVDOPoolMixin._set_compressioncCs`|jstd��||kr*td|r"dnd��|s\|rHtjj|jj|j�ntjj|jj|j�dS)Nzdevice has not been createdz,deduplication is already %s on this VDO poolr�r�)	rAr�r<r	Zvdo_enable_deduplicationr�rQr<Zvdo_disable_deduplication)r%Znew_deduplicationZold_deduplicationr�r&r&r'r��sz"LVMVDOPoolMixin._set_deduplication)TTrN)r)r*r+rrE�BLOCKDEV_LVM_PLUGIN_VDOrFrr�r(rXr�r�r�r�r�rerror�r�r�r]r�r�r6rlr�r�r�r�r&r&r&r'r�ds0


			r�cs�eZdZejejgZdd�Zdd�Zdd�Z	e
dd��Ze
d	d
��Ze
dd��Ze
d
d��Ze
dd��Ze
dd��Ze
dd��Ze
ejd�dd���Zdd�Z�fdd�Zdd�Zdd�Zd%�fd!d"�	Zd&�fd#d$�	Z�ZS)'�LVMVDOLogicalVolumeMixincCsdS)Nr&)r%r&r&r'r(sz!LVMVDOLogicalVolumeMixin.__init__cCsdS)Nr&)r%r&r&r'r^sz$LVMVDOLogicalVolumeMixin._init_checkcCs^t|jttf�r2t|j�dkr&td��|jd}n|j}|sRt|t�sR|jrZtd��dS)z.Check that this device has parents as expectedrz)constructor requires a single vdo-pool LVrz"constructor requires a vdo-pool LVN)r�r?r�rrPr�rsr�)r%r.r&r&r'risz'LVMVDOLogicalVolumeMixin._check_parentscCstdd�|jD��tj�BS)Ncss|]
}|VqdS)Nr&)r9rfr&r&r'r�szFLVMVDOLogicalVolumeMixin.type_external_dependencies.<locals>.<genexpr>)r�rFrsr�)rUr&r&r'r�sz3LVMVDOLogicalVolumeMixin.type_external_dependenciescCstdd�|j�D��S)Ncss|]}|js|VqdS)N)r�)r9rNr&r&r'r�szILVMVDOLogicalVolumeMixin.unavailable_type_dependencies.<locals>.<genexpr>)r�r�)rUr&r&r'r�sz6LVMVDOLogicalVolumeMixin.unavailable_type_dependenciescCstd�S)Nr)r)r%r&r&r'r�sz&LVMVDOLogicalVolumeMixin.vg_space_usedcCs
|jdkS)Nr�)r�)r%r&r&r'r�#sz"LVMVDOLogicalVolumeMixin.is_vdo_lvcCs|jjS)N)r�r�)r%r&r&r'r�'szLVMVDOLogicalVolumeMixin.vgcCsdS)NZlvmvdolvr&)r%r&r&r'r�,szLVMVDOLogicalVolumeMixin.typecCsdS)NFr&)r%r&r&r're0sz"LVMVDOLogicalVolumeMixin.resizabler�cCs
|jdS)Nr)r?)r%r&r&r'r�4szLVMVDOLogicalVolumeMixin.poolcCs@t|t�std��|jj|�}|jjtj|��}tj||�dS)Nznew size must of type Size)	r�rr�r�r�rrFrrl)r%rkr&r&r'rl9s

z"LVMVDOLogicalVolumeMixin._set_sizecstt|�j�dS)N)rLr�r�)r%)rSr&r'r�Csz$LVMVDOLogicalVolumeMixin._pre_createcCsdS)Nr&)r%r&r&r'r�Isz LVMVDOLogicalVolumeMixin._createcCsdS)Nr&)r%r&r&r'r�Nsz!LVMVDOLogicalVolumeMixin._destroyTcs&|r|jj|�tt|�j|d�dS)N)r�)r�r�rLr�r�)r%r�)rSr&r'r�Ssz$LVMVDOLogicalVolumeMixin.remove_hookcs6tt|�j|d�|rdS||jjkr2|jj|�dS)N)r�)rLr�r�r�r]r�)r%r�)rSr&r'r�Zs
z!LVMVDOLogicalVolumeMixin.add_hook)T)T)r)r*r+rrEr�rFr(r^rirXr�r�r�r�r�r�r�rerror�rlr�r�r�r�r�r�r&r&)rSr'r��s&
r�cs�eZdZd(dd�Zdd�Zdd�Zdd	�Zed
d��Zedd
��Z	edd��Z
edd��Zedd��Zdd�Z
d)dd�Zdd�Zdd�Z�fdd�Zd*�fd d!�	Zd+�fd"d#�	Zd$d%�Zed&d'��Z�ZS),�LVMCachePoolMixinNcCs|p
td�|_||_||_dS)Nr)rr��_cache_mode�
_attach_to)r%r��
cache_mode�	attach_tor&r&r'r(eszLVMCachePoolMixin.__init__cCsZ|js
dS|jr&tj|j�r&td��|jr>|jr>td��|jrV|jjrVtd��dS)Nzinvalid metadatasize valuez=at least one fast PV must be specified to create a cache poolz1cache pool can be attached only to an existing LV)�
is_cache_poolr�r	Zis_valid_cache_md_sizer�rArr�)r%r&r&r'r^jszLVMCachePoolMixin._init_checkcCs"|jrt|j�dkrtjd��dS)Nrz'two LVs required to create a cache pool)rrPr
rm)r%r&r&r'r�wsz!LVMCachePoolMixin._check_from_lvscCs2|j\}}||_tj|_||_tj|_|j|_dS)N)rr]rr�rr"r$)r%r�r�r&r&r'r�|s
z#LVMCachePoolMixin._convert_from_lvscCs
|jdkS)Nz
cache-pool)r�)r%r&r&r'r��szLVMCachePoolMixin.is_cache_poolcCs|jS)N)r�)r%r&r&r'r��szLVMCachePoolMixin.profilecCsdS)NZlvmcachepoolr&)r%r&r&r'r��szLVMCachePoolMixin.typecCsdS)NFr&)r%r&r&r're�szLVMCachePoolMixin.resizablecCsdS)NTr&)r%r&r&r'rt�sz"LVMCachePoolMixin.format_immutablecCsnt||j|j|jd�|jtd�kr*|jS|jrftjj|j	�}|dkr\t
jd|j	�td�St|j�Std�S)N)rArkrBrz/Failed to get size for existing cache pool '%s')rrArkrBr$rrrrrarQr�r�)r%rwr&r&r'r��s

z#LVMCachePoolMixin.read_current_sizeFcCs�tjd�|jtd�kr,tjd�d|_dS|j}|jdks@|r^tjj|j�|_tjd|j�|jj	|jdd�|_tjd|jj
d	��|j|kr�tjd
�n2|j|j|}tjd|jj
d	�|j
d	��||_dS)z� If self._metadata_size not set already, it calculates the recommended value
        and sets it while subtracting the size from self.size.

        z%Auto-setting cache pool metadata sizerzBCache pool size not bigger than 0, just setting metadata size to 0Nz#Using recommended metadata size: %sT)r�z(Rounded metadata size to extents: %s MiBrzRounded metadata size unchangedz$Adjusting size from %s MiB to %s MiB)r�r�r�rr�r<r	�cache_get_default_md_sizer�r�r�r$)r%r�r�r�r&r&r'r�s"


z!LVMCachePoolMixin.autoset_md_sizecCs(|jr$tdd�|jD��r$tjd��dS)Ncss|]}|jVqdS)N)rA)r9rar&r&r'r��sz0LVMCachePoolMixin._pre_create.<locals>.<genexpr>z&Component LVs need to be created first)rr�r
rm)r%r&r&r'r��szLVMCachePoolMixin._pre_createcCst||j|jd�|jrZytjj|j�}Wq`tjk
rV}ztj	|�WYdd}~Xq`Xntj
}|jr�t�}|j
r||j|d<tjdd�|jD��}tjdd�|jD��}tjj|jj|j|j|jf|�n.tjj|jj|j|j|j|ddd	�|jD��|j�r|jj|�dS)
z Create the device. )rlNZ	cachemodecss|]}|jtjkr|VqdS)N)rrr�)r9rar&r&r'r��sz,LVMCachePoolMixin._create.<locals>.<genexpr>css|]}|jtjkr|VqdS)N)rrr")r9rar&r&r'r��srcSsg|]}|jj�qSr&)r#rk)r9r�r&r&r'r;�sz-LVMCachePoolMixin._create.<locals>.<listcomp>)rrQrlr�r<r	�cache_get_mode_from_strr�r
rmZLVM_CACHE_DEFAULT_MODErrdr�r�r�rZcache_pool_convertr�r<Zcache_create_poolr$r�rr��attach_cache)r%r�rNr�r�r�r&r&r'r��s*
"zLVMCachePoolMixin._createcs|jr
dStt|�j�dS)N)r�rLr�r�)r%)rSr&r'r��szLVMCachePoolMixin._post_createTcs:|jr$t|j|jd|j|jd�|j_tt|�j|d�dS)NF)r$rAr\r�)r�)	r�rr$rr�rrLr�r�)r%r�)rSr&r'r��szLVMCachePoolMixin.add_hookcs$|jrd|j_tt|�j|d�dS)N)r�)r�rrLr�r�)r%r�)rSr&r'r��szLVMCachePoolMixin.remove_hookcCst�S)N)r�)r%r&r&r'r�	sz#LVMCachePoolMixin.dracut_setup_argscCsdS)z% Is this device directly accessible? Fr&)r%r&r&r'r�	szLVMCachePoolMixin.direct)NN)F)T)T)r)r*r+r(r^r�r�r�r�r�r�rertr�rr�r�r�r�r�r�r�r�r&r&)rSr'r�ds$



r�cs�eZdZdZdZdZdedd�Zd	d
�Zdd�Zd
d�Z	dd�Z
e	dd��Ze	dd��Ze	dd��Z
e	dd��Ze�fdd��Zee	�fdd���Ze	dd��Zeeje�Zee	dd ���Zee	�fd!d"���Zee	�fd#d$���Ze	d%d&��Zdfd'd(�Ze	dgd)d*��Ze	dhd+d,��Ze	d-d.��Zee	�fd/d0���Zee	�fd1d2���Zee	d3d4���Z ee	�fd5d6���Z!did7d8�Z"e	d9d:��Z#e	d;d<��Z$e	d=d>��Z%e	d?d@��Z&e	dAdB��Z'e	dCdD��Z(e	dEdF��Z)ee	dGdH���Z*ee	�fdIdJ���Z+ee	dKdL���Z,ee	�fdMdN���Z-ee	�fdOdP���Z.e	dQdR��Z/e	dSdT��Z0e	dUdV��Z1e	djdWdX��Z2e	dkdYdZ��Z3e	d[d\��Z4e	d]d^��Z5e	dld_d`��Z6dadb�Z7dcdd�Z8�Z9S)mrsz An LVM Logical Volume TNFr>rcCst|ttf�r|d}n|}|s$|r(d}||_tj||||�tj|||�tj||||�tj|�t	j||||�t
j||||||||||	|
|||
|||�tj|||||�tj|�tj
|�tj
|�tj
|�tj
|�t	j
|�|j�r|j�|j�|j�|j�dS)a"
            :param name: the device name (generally a device node's basename)
            :type name: str
            :keyword exists: does this device exist?
            :type exists: bool
            :keyword size: the device's size
            :type size: :class:`~.size.Size`
            :keyword parents: a list of parent devices
            :type parents: list of :class:`StorageDevice`
            :keyword fmt: this device's formatting
            :type fmt: :class:`~.formats.DeviceFormat` or a subclass of it
            :keyword sysfs_path: sysfs device path
            :type sysfs_path: str
            :keyword uuid: the device UUID
            :type uuid: str
            :keyword seg_type: segment type (eg: "linear", "raid1", "thin-pool", "thin",...)
            :type seg_type: str

            For non-existent LVs only:

            :keyword grow: whether to grow this LV
            :type grow: bool
            :keyword maxsize: maximum size for growable LV
            :type maxsize: :class:`~.size.Size`
            :keyword percent: percent of VG space to take
            :type percent: int
            :keyword cache_request: parameters of requested cache (if any)
            :type cache_request: :class:`~.devices.lvm.LVMCacheRequest`
            :keyword pvs: list of PVs to allocate extents from (size could be specified for each PV)
            :type pvs: list of :class:`~.devices.StorageDevice` or :class:`LVPVSpec` objects (tuples)
            :keyword shared: whether to activate the newly create LV in shared mode
            :type shared: bool

            For internal LVs only:

            :keyword parent_lv: parent LV of this internal LV
            :type parent_lv: :class:`LVMLogicalVolumeDevice`
            :keyword int_type: type of this internal LV
            :type int_type: :class:`LVMInternalLVtype`

            For snapshots only:

            :keyword origin: origin of this snapshot
            :type origin: :class:`~.StorageDevice`
            :keyword bool vorigin: is this a vorigin snapshot?

            For thin pools (seg_type="thin-pool") only:

            :keyword metadata_size: the size of the metadata LV
            :type metadata_size: :class:`~.size.Size`
            :keyword chunk_size: chunk size for the pool
            :type chunk_size: :class:`~.size.Size`
            :keyword profile: (allocation) profile for the pool or None (unspecified)
            :type profile: :class:`~.devicelibs.lvm.ThPoolProfile` or NoneType

            For new LVs created from other LVs:

            :keyword from_lvs: LVs to create the new LV from (in the (data_lv, metadata_lv) order)
            :type from_lvs: tuple of :class:`LVMLogicalVolumeDevice`

            For VDO pools only:

            :keyword compression: whether to enable compression on the VDO pool
            :type compression: bool
            :keyword dudplication: whether to enable dudplication on the VDO pool
            :type dudplication: bool
            :keyword index_memory: amount of index memory (in bytes) or 0 for default
            :type index_memory: int
            :keyword write_policy: write policy for the volume or None for default
            :type write_policy: str

            For cache pools only:

            :keyword metadata_size: the size of the metadata LV
            :type metadata_size: :class:`~.size.Size`
            :keyword cache_mode: mode for the cache or None for default (writethrough)
            :type cache_mode: str
            :keyword attach_to: for non-existing cache pools a logical volume the pool should
                                be attached to when created
            :type attach_to: :class:`LVMLogicalVolumeDevice`

            For RAID LVs only:

            :keyword stripe_size: size of the RAID stripe
            :type stripe_size: :class:`~.size.Size`

        rN)r�r�rr�rYr(rpr�r�r�r�r�r�r^rr�r�rirj)r%rQr?r$r@r�r�rArBrrr0rr\r]Zint_typer�rqr�r�r�rr�r�r�r�r�r�rrRr�r&r&r'r(	s8`








zLVMLogicalVolumeDevice.__init__cCsxg}|jr|jt�|jr$|jt�|jr4|jt�|jrD|jt�|j	rT|jt
�|jrd|jt�|j
rt|jt�|S)z7Method to get type classes for this particular instance)rr�rYrrrpr�r�r�r�r�r�r�r�r�r�)r%�retr&r&r'�_get_type_classes�	s 






z(LVMLogicalVolumeDevice._get_type_classescOs�|j�}x�|D]�}t||�ryrtt||�t�rvt|�dkr\t|j��dkr\t||�j|�}q�t||�j|f|�|�}nt||�|f|�|�}Wnt	k
r�wYqXd|fSqWdS)z?Try to call a type-specific method for this particular instancerTFN)FN)
r�rr�r�r�rPr�rf�__set__r4)r%rQrurvZclssrUr�r&r&r'�_try_specific_call�	s

z)LVMLogicalVolumeDevice._try_specific_callcst���fdd��}|S)Ncs4|j�jf|�|�\}}|r |S�|f|�|�SdS)zIDecorator that makes sure the type-specific code is executed if availableN)r�r))r%rurv�foundr�)rwr&r'rx�	sz7LVMLogicalVolumeDevice.type_specific.<locals>.decorated)r)rwrxr&)rwr'�
type_specific�	s
z$LVMLogicalVolumeDevice.type_specificcCs@tj|�}|d|j|j|j|jd�7}|jr<|d|j7}|S)Nze  VG device = %(vgdev)r
  segment type = %(type)s percent = %(percent)s
  VG space used = %(vgspace)s)Zvgdevr0r�r#z  parent LV = %r
)rr^r�r�r�r�r])r%r7r&r&r'r^�	s
zLVMLogicalVolumeDevice.__repr__cCsNt|jttf�r2t|j�dkr&td��|jd}n|j}t|t�sJtd��dS)z.Check that this device has parents as expectedrz2constructor requires a single LVMVolumeGroupDevicerz+constructor requires a LVMVolumeGroupDeviceN)r�r?r�rrPr�r5)r%r.r&r&r'ri�	s
z%LVMLogicalVolumeDevice._check_parentscCs|jdj|�dS)zAdd this device to its parentsrN)rr�)r%r&r&r'rj�	sz&LVMLogicalVolumeDevice._add_to_parentscCstd|j��dS)z$Check the LVs to create this LV fromz2Cannot create a new LV of type '%s' from other LVsN)r�r�)r%r&r&r'r��	sz&LVMLogicalVolumeDevice._check_from_lvscCstd|j��dS)z<Convert the LVs to create this LV from into its internal LVsz2Cannot create a new LV of type '%s' from other LVsN)r�r�)r%r&r&r'r��	sz(LVMLogicalVolumeDevice._convert_from_lvscs8tt|�j}|jr |jtj��|jr4|jtj��|S)N)	rLr��external_dependenciesr�rer�r�r�r�)r%Zdeps)rSr&r'r�
sz,LVMLogicalVolumeDevice.external_dependenciescstt|�jS)z#This Logical Volume's Volume Group.)rLrsr�)r%)rSr&r'r�	
szLVMLogicalVolumeDevice.vgcCs�t|t�std��|jj|�}tjd|j|�|jrt||j	krt||jj
|jkrttjd||jj
|j�td��t
j||�dS)Nznew size must be of type Sizeztrying to set lv %s size to %szfailed to set size: %s shortz%not enough free space in volume group)r�rr�r�r�r�r�rQrAr$rYr�r�r�rl)r%rkr&r&r'rl
s
$z LVMLogicalVolumeDevice._set_sizecCs@|jj|jdd�|jj|jjdd�}|jj}|r<t||�S|S)z" The maximum size this lv can be. T)r�F)r�r�r$rYrvr5r1)r%Zmax_lvZ
max_formatr&r&r'r5!
szLVMLogicalVolumeDevice.max_sizecstt|�jS)N)rLrsr6)r%)rSr&r'r6*
szLVMLogicalVolumeDevice.min_sizecstt|�jS)z5 Space occupied by this LV, not including snapshots. )rLrsr�)r%)rSr&r'r�/
sz$LVMLogicalVolumeDevice.vg_space_usedcCs2tj||�x dd�|jD�D]}|j�qWdS)Ncss|]}|js|VqdS)N)rA)r9r7r&r&r'r�8
sz5LVMLogicalVolumeDevice._set_format.<locals>.<genexpr>)r�r�r�r�)r%r��snapshotr&r&r'r�5
sz"LVMLogicalVolumeDevice._set_formatcCstj||d�dS)N)ry)rr�)r%ryr&r&r'r�;
sz$LVMLogicalVolumeDevice.setup_parentscCstj||�S)N)rr�)r%ryr&r&r'r�?
szLVMLogicalVolumeDevice.setupcCstj||�S)N)rr�)r%r}r&r&r'r�C
szLVMLogicalVolumeDevice.teardowncCs
tj|�S)N)rrm)r%r&r&r'rmG
szLVMLogicalVolumeDevice.destroycstt|�jS)N)rLrsr�)r%)rSr&r'r�K
szLVMLogicalVolumeDevice.growablecstt|�jS)N)rLrsrd)r%)rSr&r'rdP
szLVMLogicalVolumeDevice.readonlycCs|jS)N)r<)r%r&r&r'�display_lv_nameU
sz&LVMLogicalVolumeDevice.display_lv_namecstt|�jS)N)rLrsr�)r%)rSr&r'r�Z
szLVMLogicalVolumeDevice.poolcCs�t||j||j|jd�|jp&|jdk}|jrltjj	rRt
jj|j
j|j|dd�q�tjddjtjj���nt
jj|j
j|j|d�dS)	z Open, or set up, a device. )ryrlr{rT)�ignore_skiprRz%Shared LVM is not fully supported: %sr)r�N)rrQrlr{rrr�rKrr�r�r<r	Z
lvactivater�r/r
r�r�r�)r%ryr�r&r&r'�_setup_
s
zLVMLogicalVolumeDevice._setupcCs�tj|�ytjj|jj�}Wn4tjk
rR}ztj	d|jj|�dSd}~XnXt
|j�}|j}||}|j
|kr�d|j|j
|f}tj|�||_
dS)Nz*Failed to get free space for the %s VG: %szJ%s LV's size (%s) exceeds the VG's usable free space (%s),shrinking the LV)r�r�r<r	Zvginfor�rQr�r�r�r�extent_sizeZ
free_countr$r )r%Zvg_infor�r�Zextents_freeZcan_user�r&r&r'r�l
s



z"LVMLogicalVolumeDevice._pre_createcs�t||j|jd�|js�dd�|jD�}|p.d}t�}|jrTtt|jj	d���|d<|j
rbd|d<tjj
|jj|j|jf|j|d	�|���nd
d�|jjD�}|jr�dd�|jD�}nVt��x8|jjD],}|jr�|jjrȈtdd
�|jjD��O�q�W�fdd�|jjD�}tj|�}|jjdk�rntjj|jj�}tjj|jj|j|j|jj|jj|dtj||�|�	n,tjj|jj|j|j|jjtj||�|�dS)z Create the device. )rlcSsg|]}|jj�qSr&)r#rk)r9r�r&r&r'r;�
sz2LVMLogicalVolumeDevice._create.<locals>.<listcomp>NrZ
stripesizeZsyZactivate)r�r�cSsg|]
}|j�qSr&)rk)r9r#r&r&r'r;�
scSsg|]}|jj�qSr&)r#rk)r9r�r&r&r'r;�
scss|]}|jVqdS)N)rQ)r9r#r&r&r'r��
sz1LVMLogicalVolumeDevice._create.<locals>.<genexpr>csg|]}|j�kr|j�qSr&)rQrk)r9r#)�all_fast_pvs_namesr&r'r;�
srrr)rrQrlrrrrdrrTr�r�rKr<r	Zlvcreater�r/r$r��fast_pvsr�r]r�r\rZ
dedup_listr�r�r�Zcache_create_cached_lvr�Zwritecache_create_cached_lv)r%r\r�r�Zslow_pvsrar�r&)r�r'r��
s4
 zLVMLogicalVolumeDevice._createcCsDtj|�|jr"dd�|jD�}n|jj}x|D]}d|j_q0WdS)NcSsg|]
}|j�qSr&)r#)r9r�r&r&r'r;�
sz7LVMLogicalVolumeDevice._post_create.<locals>.<listcomp>)r�r�rr�r\rvr.)r%Zused_pvsr#r&r&r'r��
s

z#LVMLogicalVolumeDevice._post_createcCs*t||j|jd�tjj|jj|j�dS)z Destroy the device. )rlN)rrQrlr<r	r�r�r/)r%r&r&r'r��
szLVMLogicalVolumeDevice._destroycCsnt||j|jd�|jjdd�tjsR|jjr8|jj	�|j
jrJ|j
j	�tj�t
jj|jj|j|j�dS)N)rlT)ry)rrQrlr�r�rZallow_online_fs_resizeZoriginal_formatrAr�rvr
rzr<r	Zlvresizer/r$)r%r&r&r'rB�
s

zLVMLogicalVolumeDevice.resizecCsdS)Nr&)r%rar&r&r'r��
sz#LVMLogicalVolumeDevice._add_log_volcCsdS)Nr&)r%rar&r&r'r��
sz&LVMLogicalVolumeDevice._remove_log_volcCsgS)Nr&)r%r&r&r'r]�
szLVMLogicalVolumeDevice.lvscstt|�jS)z% Is this device directly accessible? )rLr�r>)r%)rSr&r'r��
szLVMLogicalVolumeDevice.directcCs|jS)N)r�)r%r&r&r'r��
szLVMLogicalVolumeDevice.typecstt|�jS)N)rLrsre)r%)rSr&r're�
sz LVMLogicalVolumeDevice.resizablecstt|�jS)N)rLrsrt)r%)rSr&r'rt�
sz'LVMLogicalVolumeDevice.format_immutablecCstj||�p||jkS)N)rr�r)r%r�r&r&r'r��
sz!LVMLogicalVolumeDevice.depends_oncCs
tj|�S)N)rr�)r%r&r&r'r�sz(LVMLogicalVolumeDevice.read_current_sizecCstd|jj|jfg�S)Nzrd.lvm.lv=%s/%s)r�r�rQr/)r%r&r&r'r�sz(LVMLogicalVolumeDevice.dracut_setup_argscCsD|r|jj|�|jr2x|jD]}d|_d|_qWtj||d�dS)N)r�)r�r�rr]rr�r�)r%r�rar&r&r'r�s
z"LVMLogicalVolumeDevice.remove_hookcCsHtj||d�|rdS||jjkr.|jj|�|jrD|j�|j�dS)N)r�)r�r�r�r]r�rr�r�)r%r�r&r&r'r�szLVMLogicalVolumeDevice.add_hookcCstj||�dS)N)r�r�)r%r�r&r&r'r�$sz&LVMLogicalVolumeDevice.populate_ksdatacCsptj|�sdStddg�}tdddddd	d
ddd
g
�}x|D]}|j|�r<dSq<Wx|D]}||krXdSqXWdS)NFr�r�Z_cdataZ_cmetaZ_mimager`Z_pmspareZ_rimageZ_rmetaZ_tdataZ_tmetaZ_voriginT)r	r�r�r�)r%rQZreserved_prefixesZreserved_substrings�prefixZ	substringr&r&r'r�(s



z$LVMLogicalVolumeDevice.is_name_validcCsdS)Nr&)r%r�r&r&r'r=sz&LVMLogicalVolumeDevice.autoset_md_sizecCsP|js|js|jr"tjd|j��tjj|j	j|j
|j
�t||jdd�|_
dS)Nz)Cannot attach a cache pool to the '%s' LVT)r$rA)r�rrrr
rmrQr<r	Zcache_attachr�r<rr$r)r%Z
cache_pool_lvr&r&r'r�Asz#LVMLogicalVolumeDevice.attach_cachecCs�|js|js|jr"tjd|j��ytjj|j	j|j
|j
�Wn6tjk
rt}ztjd|j�|�WYdd}~XnXt||j
dd�|_dS)Nz'Cannot attach writecache to the '%s' LVz!Failed to attach writecache to %sT)r$rA)r�rrrr
rmrQr<r	Zwritecache_attachr�r<r�r
r$r)r%Z
writecache_lvr�r&r&r'�attach_writecacheGs$z(LVMLogicalVolumeDevice.attach_writecache)NNNNNFr>NNNNNNNNFNNNNFFrNNNrF)F)F)N)F)T)T)F):r)r*r+r,Z
_resizabler�r(r�r�r�r^rirjr�r�r�r�r�rlrZ	_get_sizer$r5r6r�r�r�r�r�rmr�rdr�r�r�r�r�r�r�rBr�r�r]r�r�rertr�r�r�r�r�r�r�rr�r�r�r&r&)rSr'rs
	s�


	


1rsc@s�eZdZdZddd�Zdd�Zedd	��Zed
d��Zedd
��Z	edd��Z
edd��Zedd��Zedd��Z
edd��Zedd��Zedd��Zdd�ZdS)rrrNFc	Cs�||_|rf|rfttjj|��}|||_|jj|krN|j||jj8_|jj|j�|_||_	n||_||_	||_
d|_g|_|s�|p�d|_xD|D]<}t
|t�r�|jj|�q�t
|t�r�|jjt|td���q�W|j�dS)a�
        :param cached_lv: the LV the cache functionality of which to provide
        :type cached_lv: :class:`LVMLogicalVolumeDevice`
        :param size: size of the cache (useful mainly for non-existing caches
                     that cannot determine their size dynamically)
        :type size: :class:`~.size.Size`
        :param md_size: size of the metadata part (LV) of the cache (for
                        non-existing caches that cannot determine their metadata
                        size dynamically) or None to use the default (see note below)
        :type md_size: :class:`~.size.Size` or NoneType
        :param bool exists: whether the cache exists or not
        :param pvs: PVs to allocate the cache on/from (ignored for existing)
        :type pvs: list of :class:`LVPVSpec`
        :param str mode: desired mode for non-existing cache (ignored for existing)

        .. note::
            If :param:`md_size` is None for a an unexisting cache, the default
            is used and it is subtracted from the requested :param:`size` so
            that the whole cache (data+metadata) fits in the space of size
            :param:`size`.

        N�writethroughr)�
_cached_lvrr<r	r�r�r�r�r��_md_size�_exists�_moderr�r"r�rr)	r%�	cached_lvr$r�rAr\r�Zdefault_md_sizerr&r&r'r(Xs*




zLVMCache.__init__cCs�|j|jtdd�|jD��}x`dd�|jD�D]L}|jjj|krV||_td�}Pq2|jjjdkr2|jjj|_||jjj8}q2W|dkr�td|��dS)Ncss|]}|jVqdS)N)r$)r9r�r&r&r'r��sz,LVMCache._assign_pv_space.<locals>.<genexpr>css|]}|js|VqdS)N)r$)r9r�r&r&r'r��srz9Not enough free space in the PVs for this cache: %s short)	r$r�r�rr#rvr.rr�)r%�space_to_assignr�r&r&r'r�s zLVMCache._assign_pv_spacecCs|j}|r|jS|jSdS)N)�statsr$r�)r%r�r&r&r'r$�sz
LVMCache.sizecCs|jr|jr|jjS|jSdS)N)rAr�r�r�)r%r&r&r'r��szLVMCache.md_sizecCs|j|jS)N)r$r�)r%r&r&r'r��szLVMCache.vg_space_usedcCs|jS)N)r�)r%r&r&r'rA�szLVMCache.existscCsr|jrj|jjrjytjj|jjj|jj�}Wn4tj	k
r^}zt
jd|jj|�dSd}~XqnXt|�SndSdS)Nz&Failed to get cache stats for '%s': %s)
r�r�rlr<r	�cache_statsr�rQr<r�r�r��
LVMCacheStats)r%r�r�r&r&r'r��s
zLVMCache.statscCs||js|jSytjj|jjj|jj�}Wn@tj	k
rh}z"t
jd|jj|�tjjtj
j�Sd}~XnXtjj|j�SdS)Nz&Failed to get cache stats for '%s': %s)r�r�r<r	r�r�r�rQr<r�r�r�Zcache_get_mode_strZLVMCacheModeZUNKNOWNr�)r%r�r�r&r&r'r��sz
LVMCache.modecCs|jr|jjSdSdS)N)r�r�rQ)r%r&r&r'�backing_device_name�szLVMCache.backing_device_namecCs2|jr*|jjj}d|tjj||jj�fSdSdS)Nz%s-%s)r�r�r�rQr<r	�cache_pool_namer<)r%rtr&r&r'�cache_device_name�s
zLVMCache.cache_device_namecCsdd�|jD�S)NcSsg|]
}|j�qSr&)r#)r9r�r&r&r'r;�sz%LVMCache.fast_pvs.<locals>.<listcomp>)r)r%r&r&r'r��szLVMCache.fast_pvscCs|jS)z�
        :returns: space to be occupied by the cache on its LV's VG's PVs (one has to love LVM)
        :rtype: list of LVPVSpec

        )r)r%r&r&r'r��szLVMCache.pv_space_usedcCs4|jjj}tjj||jj�}tjj||jjd�|S)NF)r�r�rQr<r	r�r<Zcache_detach)r%rtr�r&r&r'�detach�s
zLVMCache.detach)NNFNN)r)r*r+r�r(rr�r$r�r�rAr�r�r�r�r�r�r�r&r&r&r'rRs
0	
	rc@s�eZdZdZddd�Zdd�Zedd	��Zed
d��Zedd
��Z	edd��Z
edd��Zedd��Zedd��Z
edd��Zedd��Zdd�ZdS)r
rDFNcCs~||_||_||_g|_|sz|jj|j�|_xD|D]<}t|t�rN|jj|�q2t|t	�r2|jjt|t
d���q2W|j�dS)Nr)r�r�r�rr�r�r�r"r�rrr)r%r�r$rAr\rr&r&r'r(�s


zLVMWriteCache.__init__cCs�|jtdd�|jD��}x`dd�|jD�D]L}|jjj|krP||_td�}Pq,|jjjdkr,|jjj|_||jjj8}q,W|dkr�tjd|��dS)Ncss|]}|jVqdS)N)r$)r9r�r&r&r'r�sz1LVMWriteCache._assign_pv_space.<locals>.<genexpr>css|]}|js|VqdS)N)r$)r9r�r&r&r'r�srz9Not enough free space in the PVs for this cache: %s short)	r$r�rr#rvr.rr
rm)r%r�r�r&r&r'rszLVMWriteCache._assign_pv_spacecCs|jS)N)r�)r%r&r&r'r$szLVMWriteCache.sizecCstd�S)Nr)r)r%r&r&r'r�szLVMWriteCache.md_sizecCs|jS)N)r$)r%r&r&r'r�szLVMWriteCache.vg_space_usedcCs|jS)N)r�)r%r&r&r'rA"szLVMWriteCache.existscCsdS)Nr&)r%r&r&r'r�&szLVMWriteCache.statscCs|jr|jjSdSdS)N)r�r�rQ)r%r&r&r'r�*sz!LVMWriteCache.backing_device_namecCs2|jr*|jjj}d|tjj||jj�fSdSdS)Nz%s-%s)rAr�r�rQr<r	r�r<)r%rtr&r&r'r�1s
zLVMWriteCache.cache_device_namecCsdd�|jD�S)NcSsg|]
}|j�qSr&)r#)r9r�r&r&r'r;;sz*LVMWriteCache.fast_pvs.<locals>.<listcomp>)r)r%r&r&r'r�9szLVMWriteCache.fast_pvscCs|jS)z�
        :returns: space to be occupied by the cache on its LV's VG's PVs (one has to love LVM)
        :rtype: list of LVPVSpec

        )r)r%r&r&r'r�=szLVMWriteCache.pv_space_usedcCs\ytjj|jjj|jjd�Wn8tjk
rV}ztj	d|jj�|�WYdd}~XnXdS)NFz#Failed to detach writecache from %s)
r<r	Zwritecache_detachr�r�rQr<r�r
rm)r%r�r&r&r'r�FszLVMWriteCache.detach)FN)r)r*r+r�r(rr�r$r�r�rAr�r�r�r�r�r�r&r&r&r'r
�s
	r
c@s�eZdZdd�Zedd��Zedd��Zedd��Zed	d
��Zedd��Z	ed
d��Z
edd��Zedd��Zedd��Z
edd��Zedd��Zedd��ZdS)r�cCsdt|j�|_t|j�|_|j|_t|j�|_t|j	�|_
|j|_|j
|_|j|_|j|_|j|_dS)zp
        :param stats_data: cache stats data
        :type stats_data: :class:`blockdev.LVMCacheStats`

        N)r�
block_size�_block_sizer,�_cache_sizeZ
cache_used�_cache_used�
md_block_size�_md_block_sizer�r��md_used�_md_used�	read_hits�
_read_hits�read_misses�_read_misses�
write_hits�_write_hits�write_misses�
_write_misses)r%Z
stats_datar&r&r'r(OszLVMCacheStats.__init__cCs|jS)N)r�)r%r&r&r'r�aszLVMCacheStats.block_sizecCs|jS)N)r�)r%r&r&r'r$eszLVMCacheStats.sizecCs|jS)N)r�)r%r&r&r'r�iszLVMCacheStats.usedcCs|j|jS)N)r�r�)r%r&r&r'�hitsmszLVMCacheStats.hitscCs|j|jS)N)r�r�)r%r&r&r'�missesqszLVMCacheStats.missescCs|jS)N)r�)r%r&r&r'r�vszLVMCacheStats.md_block_sizecCs|jS)N)r�)r%r&r&r'r�zszLVMCacheStats.md_sizecCs|jS)N)r�)r%r&r&r'r�~szLVMCacheStats.md_usedcCs|jS)N)r�)r%r&r&r'r��szLVMCacheStats.read_hitscCs|jS)N)r�)r%r&r&r'r��szLVMCacheStats.read_missescCs|jS)N)r�)r%r&r&r'r��szLVMCacheStats.write_hitscCs|jS)N)r�)r%r&r&r'r��szLVMCacheStats.write_missesN)r)r*r+r(r�r�r$r�r�r�r�r�r�r�r�r�r�r&r&r&r'r�Msr�c@seZdZdZdZdS)rrrN)r)r*r+rr	r&r&r&r'r�src@s\eZdZdZdejfdd�Zedd��Zedd��Z	ed	d
��Z
edd��Zed
d��ZdS)�LVMCacheRequestz1Class representing the LVM cache creation requestNcCsf||_|pd|_||_g|_xD|D]<}t|t�r>|jj|�q"t|t�r"|jjt|td���q"WdS)a�
        :param size: requested size of the cache
        :type size: :class:`~.size.Size`
        :param pvs: PVs to allocate the cache on/from
        :type pvs: list of (:class:`~.devices.storage.StorageDevice` or :class:`LVPVSpec`)
        :param str mode: requested mode for the cache (``None`` means the default is used)
        :param cache_type: type of the cache to use (writecache or "normal" cache)
        :type cache_type: enum :class:`LVMCacheType`
        r�rN)	r�r��_cache_typerr�r"r�rr)r%r$r\r�rrr&r&r'r(�s




zLVMCacheRequest.__init__cCs|jS)N)r�)r%r&r&r'r$�szLVMCacheRequest.sizecCsdd�|jD�S)NcSsg|]
}|j�qSr&)r#)r9r�r&r&r'r;�sz-LVMCacheRequest.fast_devs.<locals>.<listcomp>)r)r%r&r&r'r�szLVMCacheRequest.fast_devscCs|jS)z�
        :returns: space to be occupied by the cache on its LV's VG's PVs (one has to love LVM)
        :rtype: list of LVPVSpec

        )r)r%r&r&r'�pv_space_requests�sz!LVMCacheRequest.pv_space_requestscCs|jS)N)r�)r%r&r&r'r��szLVMCacheRequest.modecCs|jS)N)r�)r%r&r&r'r�szLVMCacheRequest.cache_type)
r)r*r+r,rrr(r�r$rr�r�rr&r&r&r'r��s	r�)TZdecimalrr}r`rgr�r9�collectionsrr�	functoolsr�enumrr�ZgiZrequire_versionZ
gi.repositoryrr<Z
devicelibsr	r>r
rZstorage_logrr
rr$rrrrrZstatic_data.lvm_inforZtasksrZloggingZ	getLoggerr��librrr�rZstoragerr.rr�rr0rZmdrrrrr r!�objectr"r-r/ZDEFAULT_THPOOL_RESERVE�	Exceptionr4r5r�rrYrpr�r�r�r�r�rsrr
r�rr�r&r&r&r'�<module>s�
H#-<9-ag'J]F