o
    bG                     @   s   d dl Z ddlmZ ddlmZ ddlmZ ddlmZ ddlmZm	Z	m
Z
 dd	lmZmZmZ d
d ZG dd deZG dd de	ZG dd deZG dd deZdS )    N   )log)diskbackend)progress)xmlutil   )DeviceDeviceAddressDeviceSeclabel)
XMLBuilderXMLChildPropertyXMLPropertyc                 C   s(   dg}| t jkrt jS ||v rt jS |S )zL
    Sanitize libvirt storage volume format to a valid qemu driver type
    iso)
DeviceDisk
TYPE_BLOCKDRIVER_TYPE_RAW)phystypefmtraw_list r   0/usr/share/virt-manager/virtinst/devices/disk.py_qemu_sanitize_drvtype   s   
r   c                   @   s<   e Zd Zg dZdZedZedddZedZedZ	d	S )
_Host)nameport	transportsockethost./@namez./@portTis_intz./@transportz	./@socketN)
__name__
__module____qualname___XML_PROP_ORDERXML_NAMEr   r   r   r   r   r   r   r   r   r   !   s    r   c                   @   s   e Zd ZdS )_DiskSourceAddressN)r!   r"   r#   r   r   r   r   r&   +   s    r&   c                   @   s   e Zd ZdZg dZdZedZedZedZ	edZ
edZeeZed	Zed
ZedZedddZedddZeeddZdd Zdd Zdd Zdd ZdS )_DiskSourcezp
    Class representing disk <source> block, and various helpers
    that only operate on <source> contents
    )filedevdirvolumepoolprotocolr   hoststypemanaged	namespaceaddresssourcez./@filez./@devz./@dirz./@poolz	./@volumer   z./@protocol./@typez
./@managedTis_yesnoz./@namespacer   	is_singlec                 C   s   ddl m} ||}|jr|j| _|js|js|jr"| js"| j  |jr,|j| jd _|jr6|j| jd _	|jr@|j| jd _|j
ri| jrU| jd jrU|j
| jd _dS |j
| _	| j	drk| j	dd | _	dS dS dS )z
        For a passed in path URI like gluster:// or https://, split it
        up and set the <disk> properties directly
        r   )URIr   /r   N)urir9   schemer-   hostnamer   r   r.   add_newr   pathr   
startswith)selfr;   r9   uriobjr   r   r   set_from_urlK   s,   
z_DiskSource.set_from_urlc                 C   s   t | j}| jr| jd }| jpd}|jr|d|j 7 }|d7 }|jr4||j7 }|jr4|dt|j 7 }| jrH| jdsA|d7 }|| j7 }|S |j	rZ|j	dsU|d7 }||j	7 }|S )z?
        Build a URL from network contents of <source>
        r   unknownz+%sz://:r:   )
r   connr.   r-   r   r   r   strr@   r   )rA   r   retr   r   r   build_url_from_networkf   s*   





z"_DiskSource.build_url_from_networkc                 C   sL   d| _ d| _d| _d| _d| _d| _d| _| jdd D ]}| | qdS )zP
        Unset all XML properties that describe the actual source media
        N)	r(   r)   r*   r+   r,   r   r-   r.   remove_child)rA   hr   r   r   clear_source   s   z_DiskSource.clear_sourcec                 C   s   |j dk}|j }|rd}|| _t|jD ] \}}t| j|d k r&| j  |j| j| _|j| j| _qd}|rHd|jv rG|j	ddd }n|j
ra||j
7 }|jrX||j7 }|dsa|d7 }||j7 }|pid	| _d	S )
z
        For the passed pool + vol object combo representing a network
        volume, set the <source> elements directly
        ziscsi-directiscsir    z-iscsi-iqn.z-iscsi-r:   N)r/   r-   	enumerater.   lenr>   r   r   target_pathsplitsource_namesource_pathendswith)rA   volxmlpoolxmlis_iscsi_directr-   idxpoolhostr?   r   r   r   set_network_from_storage   s.   






z$_DiskSource.set_network_from_storageN)r!   r"   r#   __doc__r$   r%   r   r(   r)   r*   r,   r+   r   r   r.   r   r-   r/   r0   r1   r&   r2   rC   rI   rL   r\   r   r   r   r   r'   /   s(    r'   c                   @   s  e Zd ZdZdZdZdZdZdZdZ	dZ
d	Zeee	e
egZd
ZdZeegZdZdZdZdZdZdZdZdZdZdZedd Zedd Zedd ZedddZe	ddd Zed!d" Z ed#d$ Z!g d%Z"d&d' Z#e$d(Z%e$d)Z&e$d*Z'e$d+Z(e)e*d,d-Z+e$d.Z,e$d/Z-e$d0Z.e$d1Z/e$d2d,d3Z0e$d4Z1e$d5Z2e$d6Z3e$d7Z4e$d8d,d3Z5e$d9d,d:Z6e$d;d,d<Z7e$d=d,d<Z8e$d>d,d<Z9e$d?d,d@Z:e$dAZ;e$dBZ<e$dCZ=e$dDZ>e$dEd,d:Z?e$dFd,d:Z@e$dGZAe$dHZBe$dIZCe$dJZDe$dKZEe$dLZFe$dMd,d:ZGe$dNd,d:ZHe$dOd,d:ZIe$dPd,d:ZJe$dQd,d:ZKe$dRd,d:ZLe)eMdSdTZNe$dUd,d:ZOe$dVd,d:ZPe$dWd,d:ZQe$dXZRe$dYZSe$dZZTe$d[ZUe$d\ZVd]d^ ZWd_d` ZXdadb ZYdcdd ZZdedf Z[e\eZe[Z]dgdh Z^didj Z_e\e^e_Z`dkdl Zadmdn Zbdodp Zcdqdr Zddsdt Zedudv Zfdwdx Zgdydz Zhd{d| Zid}d~ Zjdd Zkdd Zldd Zmdd Zndd Zodd Zpdd Zqdd Zrdd Zsdd Ztdd Zudd Zvdd Zwdd Zxdd Zydd Zzdd Z{dd Z|dd Z}dd Z~dd Zdd Zdd ZdS )r   diskphyqemurawnonewritethrough	writeback
directsyncunsafeignoreunmapluncdromfloppyr(   blockr*   r+   networknativec                 C   s   t | |S )a}  
        Check if path exists.

        return True if we are certain, False otherwise. Path may in fact
        exist if we return False, but we can't exhaustively know in all
        cases.

        (In fact if cached storage volume data is out of date, the volume
         may have disappeared behind our back, but that shouldn't have bad
         effects in practice.)
        )r   path_definitely_exists)rF   r?   r   r   r   ro      s   z!DeviceDisk.path_definitely_existsc                 C   s   t d| G dd dt}| }|s|S |  r|S |  s!|S t|r(|S t| |r0|S tj	
|}| jj \}}|sB|S |dkrLt sL|S ||_||_t||||_|j  |S )ad  
        Check if the connection DAC user has search permissions for all the
        directories in the passed path.

        :returns: Class with:
            - List of the directories the user cannot search, or empty list
            - username we checked for or None if not applicable
            - uid we checked for or None if not application
        z$DeviceDisk.check_path_search path=%sc                   @   s   e Zd Zdd ZdS )z0DeviceDisk.check_path_search.<locals>.SearchDatac                 S   s   d | _ d | _g | _d S N)useruidfixlistrA   r   r   r   __init__   s   
z9DeviceDisk.check_path_search.<locals>.SearchData.__init__N)r!   r"   r#   ru   r   r   r   r   
SearchData   s    rv   r   )r   debugobject	is_remoteis_qemu_privilegedr   path_is_urlpath_is_network_volosr?   abspathcapsr   get_qemu_baselabelr   in_testsuiterq   rr   is_path_searchablers   reverse)rF   r?   rv   
searchdatarq   rr   r   r   r   check_path_search   s0   

zDeviceDisk.check_path_searchc                 C   s   t | j| j}|S )z
        Try to fix any permission problems found by check_path_search

        :returns: Return a dictionary of entries {broken path : error msg}
        )r   set_dirs_searchablers   rq   )r   errdictr   r   r   fix_path_search  s   zDeviceDisk.fix_path_searchFc                 C   s  |sg S g }t dd |  D }|}||v r,|| }||v r n|j}|| ||v sg }|  }	|	D ]K}
|sL||
jj|
jj|
jjfv rL||
j	 q4|
j
jD ].}| }||v rg|
j	|vrg||
j	  n||krlqP|rr|jrrqP|rx|jrxqP||
j	  q4|S )a  
        Return a list of VM names that are using the passed path.

        :param conn: virConnect to check VMs
        :param path: Path to check for
        :param shareable: Path we are checking is marked shareable, so
            don't warn if it conflicts with another shareable source.
        :param read_only: Path we are checking is marked read_only, so
            don't warn if it conflicts with another read_only source.
        c                 s   s     | ]}|j r|j |fV  qd S rp   )backing_store).0volr   r   r   	<genexpr>)  s    z,DeviceDisk.path_in_use_by.<locals>.<genexpr>)dictfetch_all_volsrR   appendfetch_all_domainsr}   kernelinitrddtbr   devicesr^   get_source_path	shareable	read_only)rF   r?   r   r   volsvolmapbackpathr   rH   vmsvmr^   	checkpathr   r   r   path_in_use_by  sH   


zDeviceDisk.path_in_use_byNc                 C   s   ddl m} |du rttd| |sttd| td||  |d d d }	|r2d}
n|	}
|| }||_||_|	|_	|
|_
||_||_|rY| sVttd	||_|S )
z
        Helper for building a StorageVolume instance to pass to DeviceDisk
        for eventual storage creation.

        :param volname: name of the volume to be created
        :param size: size in bytes
        r   )StorageVolumeNz3Size must be specified for non existent volume '%s'zpDon't know how to create storage for path '%s'. Use libvirt APIs to manage the parent directory as a pool first.z!Creating volume '%s' on pool '%s'   r   z3Format attribute not supported for this volume type)storager   
ValueError_RuntimeErrorr   rw   r   r,   capacity
allocationr   backing_formatsupports_formatformat)rF   volnamepoolobjsizesparser   r   r   r   capallocvolinstr   r   r   build_vol_installO  s8   
zDeviceDisk.build_vol_installc                 C   s   g }t ddD ]&}| d|d   d|  }|dkr#| d|d  kr#d}| |8 } |d| qd}|D ]}|dkr9q2|dtd| d  7 }q2|S )zo
        Convert an index in range (1, 1024) to a disk /dev number
        (like hda, hdb, hdaa, etc.)
        r         r   rN   z%ca)rangeinsertord)numdigitsfactoramtgen_tdigitr   r   r   num_to_target~  s   zDeviceDisk.num_to_targetc                 C   sn   d}d}| d dkr| dd } t t| dd D ]\}}|dkr$d}|t|td | d|  7 }q|S )zR
        Convert disk /dev number (like hda, hdb, hdaa, etc.) to an index
        r   xr   Nr   r   r   )rP   reversedr   )tgtr   kicr   r   r   target_to_num  s   "zDeviceDisk.target_to_num)_xmltype_devicesnapshot_policydriver_namedriver_typedriver_cachedriver_discarddriver_detect_zeroes	driver_iodriver_iothreaddriver_queueserror_policyauth_usernameauth_secret_typeauth_secret_uuidr3   targetbusc                 O   sD   t j| g|R i | d | _d| _t| j|  | j| j	| _
d S )NF)r   ru   _source_volume_errstorage_was_createdr   StorageBackendStubrF   _get_xmlpathr   r   _storage_backend)rA   argskwargsr   r   r   ru     s   
zDeviceDisk.__init__r4   z	./@devicez./driver/@namez./driver/@typeTr7   z./auth/@usernamez./auth/secret/@typez./auth/secret/@uuidz./@snapshotz./driver/@copy_on_read)is_onoffz./@sgioz./@rawioz./target/@busz./target/@devz./target/@removablez./target/@rotation_rater   z
./readonly)is_boolz./shareablez./transientz./transient/@shareBackingr5   z./driver/@cachez./driver/@discardz./driver/@detect_zeroesz./driver/@ioz./driver/@iothreadz./driver/@queuesz./driver/@error_policyz./serialz./wwnz./source/@startupPolicyz./blockio/@logical_block_sizez./blockio/@physical_block_sizez./iotune/read_bytes_secz./iotune/read_iops_secz./iotune/total_bytes_secz./iotune/total_iops_secz./iotune/write_bytes_secz./iotune/write_iops_secz./source)relative_xpathz./geometry/@cylsz./geometry/@headsz./geometry/@secsz./geometry/@transz./source/reservations/@managedz"./source/reservations/source/@typez"./source/reservations/source/@pathz"./source/reservations/source/@modec                 C   s>   | j js| j jrtjS | j s| j S | j jrtj	S | j
S rp   )r3   r,   r+   r   TYPE_VOLUMEr   is_stubget_dev_typer-   TYPE_NETWORK	TYPE_FILErt   r   r   r   _get_default_type   s   

zDeviceDisk._get_default_typec                 C   s>   |   rd S | j r| j| jkr| jS | jj r| jS d S rp   )	is_emptyrF   is_xenr/   r   DRIVER_NAME_PHYsupportconn_disk_driver_name_qemuDRIVER_NAME_QEMUrt   r   r   r   _get_default_driver_name	  s   z#DeviceDisk._get_default_driver_namec                 C   s&   | j | jkrdS | j }t| j|S )a`  
        Set driver type from passed parameters

        Where possible, we want to force /driver/@type = "raw" if installing
        a QEMU VM. Without telling QEMU to expect a raw file, the emulator
        is forced to autodetect, which has security implications:

        https://lists.gnu.org/archive/html/qemu-devel/2008-04/msg00675.html
        N)r   r   r   get_driver_typer   r/   )rA   drvtyper   r   r   _get_default_driver_type  s   

z#DeviceDisk._get_default_driver_typec                 C   s   | j r| j S |  S rp   )r   r   rt   r   r   r   	_get_type&  s   zDeviceDisk._get_typec                 C   
   || _ d S rp   )r   rA   valr   r   r   	_set_type*     
zDeviceDisk._set_typec                 C   s   | j r| j S | jS rp   )r   DEVICE_DISKrt   r   r   r   _get_device.  s   zDeviceDisk._get_devicec                 C   r   rp   )r   r   r   r   r   _set_device2  r   zDeviceDisk._set_devicec                 C   s   t | j|||}|| _d S rp   )r   StorageBackendrF   r   )rA   r?   
vol_objectparent_poolbackendr   r   r   _change_backend;  s   

zDeviceDisk._change_backendc                 C   s   | j  r|   d S d S rp   )r   r   _resolve_storage_backendrt   r   r   r   set_backend_for_existing_path@  s   
z(DeviceDisk.set_backend_for_existing_pathc              
   C   s   d}d}d}d| _ |  }| jtjkr| j }|tjkrSz| j	| jj
}|| jj}W n$ tyR } zt|| _ tjd| jj
| jjdd W Y d}~nd}~ww |du r_|du r_|  }|ro|so|sot| j|\}}}| ||| dS )zU
        Convert the relevant <source> XML values into self._storage_backend
        Nz$Error fetching source pool=%s vol=%sT)exc_info)r   r   r/   r   r   r3   rI   r   rF   storagePoolLookupByNamer,   storageVolLookupByNamer+   	ExceptionrG   r   rw   r   r   manage_pathr   )rA   r?   r   r   typedummyr   r   r   r   H  s:   



z#DeviceDisk._resolve_storage_backendc                 C   s&   | j  r| j  s|   | j  S )a  
        Source path is a single string representation of the disk source
        storage. For regular storage this is a FS path. For type=network
        this is a reconstructed URL. In some cases like rbd:// this may
        be an entirely synthetic URL format
        )r   r   get_pathr   rt   r   r   r   r   j  s
   

zDeviceDisk.get_source_pathc                 C   sH   | j  r
tdt| j|\}}}| ||| | | 	  d S )Nz=Can't change disk path if storage creation info has been set.)
r   will_create_storager   DevErrorr   r  rF   r   _set_xmlpathr   )rA   newpathr   r   r   r   r   set_source_pathv  s   

zDeviceDisk.set_source_pathc                 C   sD   t d|d t d|d | d || | |   d S )Nzdisk.set_vol_object: volxml=
%sr   z disk.set_vol_object: poolxml=
%s)r   rw   XMLDescr   r  r   )rA   r   r   r   r   r   set_vol_object  s   zDeviceDisk.set_vol_objectc                 C   s:   t d|j|jd t| j|| _| 	| 
  d S )Nz)disk.set_vol_install: name=%s poolxml=
%sr   )r   rw   r   r,   r  r   ManagedStorageCreatorrF   r   r  r   )rA   vol_installr   r   r   set_vol_install  s   zDeviceDisk.set_vol_installc                 C   
   | j  S rp   )r   get_vol_objectrt   r   r   r   r    r   zDeviceDisk.get_vol_objectc                 C   r  rp   )r   get_vol_installrt   r   r   r   r    r   zDeviceDisk.get_vol_installc                 C   r  rp   )r   get_parent_poolrt   r   r   r   r    r   zDeviceDisk.get_parent_poolc                 C   r  rp   )r   get_sizert   r   r   r   r    r   zDeviceDisk.get_sizec                 C   s6   d| _ |jr|j| _|j| _|j| _| j|| d S Nrm   )r/   	auth_typer   r   r   r3   r\   rA   rW   rX   r   r   r    _set_source_network_from_storage  s   z+DeviceDisk._set_source_network_from_storagec                 C   s\   | j  s
| j  r| j  }| j  }| || d S | j  r,| j| j   d S d S rp   )	r   r  r  get_vol_xmlget_parent_pool_xmlr  r	  r3   rC   r  r   r   r    _set_network_source_from_backend  s   



z+DeviceDisk._set_network_source_from_backendc                 C   s4   | j }|tjkr
dS |tjkrdS |tjkrdS d S )Nr)   r*   r(   )r/   r   r   TYPE_DIRr   )rA   	disk_typer   r   r   _disk_type_to_object_prop_name  s   


z)DeviceDisk._disk_type_to_object_prop_namec                 C   s4   | j jr| j jS | j jr| j jS | j jr| j jS d S rp   )r3   r(   r)   r*   rt   r   r   r   r     s   zDeviceDisk._get_xmlpathc                 C   sB   | j   | j dkr|   d S |  }|sd S t| j ||S r  )r3   rL   r   r   r  r"  setattr)rA   r   propnamer   r   r   r    s   
zDeviceDisk._set_xmlpathc                 C   s&   t | j|  | | || _dS )zK
        Set a path to manually clone (as in, not through libvirt)
        N)r   CloneStorageCreatorrF   r   r  r   )rA   r^   r   r   r   r   set_local_disk_to_clone  s
   
z"DeviceDisk.set_local_disk_to_clonec                 C   s   t |   S rp   )boolr   rt   r   r   r   r     s   zDeviceDisk.is_emptyc                 C      | j | jkS rp   )deviceDEVICE_CDROMrt   r   r   r   is_cdrom     zDeviceDisk.is_cdromc                 C   r(  rp   )r)  DEVICE_FLOPPYrt   r   r   r   	is_floppy  r,  zDeviceDisk.is_floppyc                 C   r(  rp   )r)  r   rt   r   r   r   is_disk  r,  zDeviceDisk.is_diskc                 C   s&   |   s|  r
dS | jdv rdS dS )NT)r(   rl   r*   r+   rm   F)r.  r+  r/   rt   r   r   r   can_be_empty  s
   
zDeviceDisk.can_be_emptyc                 C   s   | j   S )zd
        If true, this disk needs storage creation parameters or things
        will error.
        )r   existsrt   r   r   r   wants_storage_creation  s   z!DeviceDisk.wants_storage_creationc                 C   sN   | j  sdS t|}| j |}d| _|sdS |  j}| d|| dS )z
        Build storage (if required)

        If storage doesn't exist (a non-existent file 'path', or 'vol_install'
        was specified), we create it.
        NT)	r   r
  r   ensure_metercreater   r  r,   r   )rA   meterr   r   r   r   r   build_storage  s   


zDeviceDisk.build_storagec                 C   sl   |   r| jrt| j|  sttd| j d S | j s/| j	 s/ttd| 
  | j  d S )Nz Device type '%s' requires a pathzDMust specify storage creation parameters for non-existent path '%s'.)r   r   r   r0  r   r   r)  r   r1  r
  r   validatert   r   r   r   r7    s"   

zDeviceDisk.validatec                 C   r  )aq  
        reports if disk size conflicts with available space

        returns a two element tuple:
            1. first element is True if fatal conflict occurs
            2. second element is a string description of the conflict or None
        Non fatal conflicts (sparse disk exceeds available space) will
        return (False, "description of collision")
        )r   is_size_conflictrt   r   r   r   r8  *  s   

zDeviceDisk.is_size_conflictc                 C   s    | j | j|  | j| jd}|S )z
        check if specified storage is in use by any other VMs on passed
        connection.

        :returns: list of colliding VM names
        )r   r   )r   rF   r   r   r   )rA   rH   r   r   r   is_conflict_disk6  s
   zDeviceDisk.is_conflict_diskc                 C   s<   |   }|  | _|  | _|  | _|r| | dS dS )z
        Fills in the values of type, driver_type, and driver_name for
        the associated backing storage. This needs to be manually called
        if changing an existing disk's media.
        N)r   r   r/   r   r   r   r   r  )rA   r?   r   r   r   sync_path_propsG  s   


zDeviceDisk.sync_path_propsc                 C   s`   dd }| j dkr|dS | j dkr|dS | j dks|  r#|dS | j d	kr,|d
S |dS )z
        Returns the suggested disk target prefix (hd, xvd, sd ...) for the
        disk.
        :returns: str prefix, or None if no reasonable guess can be made
        c                 S   s   dddddd}| ||  fS )Nr   r      )vdxvdfdhdsdr   )prefixnummapr   r   r   _return_  s   z-DeviceDisk.get_target_prefix.<locals>._returnvirtior<  xenr=  fdcr>  ider?  r@  )r   r.  )rA   rC  r   r   r   get_target_prefixW  s   



zDeviceDisk.get_target_prefixc                    sh     \ fddD    fdd}| }|r&|_|S ttdd  jd )a  
        Generate target device ('hda', 'sdb', etc..) for disk, excluding
        any targets in 'skip_targets'.
        Sets self.target, and returns the generated value.

        :param skip_targets: list of targets to exclude
        :returns: generated target
        c                    s   g | ]}|r|  r|qS r   )r@   )r   t)rA  r   r   
<listcomp>~  s    z.DeviceDisk.generate_target.<locals>.<listcomp>c                     sX   d } t  D ]}|d  }|v r| qs!|  S | s%|} q| r*| S d S )Nr   )r   r   remove)first_foundr   r   maxnoderA  rA   skip_targetsr   r   
get_target  s   
z.DeviceDisk.generate_target.<locals>.get_targetz4Only %(number)s disk for bus '%(bus)s' are supportedz5Only %(number)s disks for bus '%(bus)s' are supported)numberr   )rH  sortr   r   ngettextr   )rA   rO  rP  rH   r   rM  r   generate_targett  s    	
zDeviceDisk.generate_targetc                 C   sv   | j |krdS |  d }|| _ | j  ||  d krdS dd |jjD }| jr1|| j d| _| | dS )zk
        Change the bus value for an existing disk, which has some
        follow on side effects.
        Nr   c                 S   s   g | ]}|j qS r   r   )r   r^   r   r   r   rJ    s    z)DeviceDisk.change_bus.<locals>.<listcomp>)	r   rH  r2   clearr   r^   r   rK  rT  )rA   guestnewbus	oldprefixusedr   r   r   
change_bus  s   

zDeviceDisk.change_busc                 C   s   |   rdS |j rdS |j sdS |  r| rdS |  r-| r-|j s-dS |j	 r4dS |j
 r;dS | j rBdS dS )NrF  rE  rG  rD  scsir@  sata)r.  r}   is_xenpvis_hvmr/  supports_virtiodiskr+  supports_virtioscsiis_x86is_armis_q35rF   is_bhyve)rA   rW  r   r   r   _default_bus  s*   




zDeviceDisk._default_busc                 C   s  | j s|  | _ | js|  | _| js|  | _| js |  | _| js)| 	|| _| 
 r0d| _d}| j rO|  rO| j rO| j rO| j jdkrOd}| j rn|  rn| j| jkrnd}| jsg| j| _| jsn| j| _|rv| jsvd| _| jsdd |jjD }| | d S d S )NTFr   rh   c                 S   s   g | ]}|j r|j qS r   rU  )r   dr   r   r   rJ    s    z+DeviceDisk.set_defaults.<locals>.<listcomp>)r   r   r   r   r   r   r   r   r   rf  r+  r   rF   is_qemur/  r   r
  r  r   r/   r   r   CACHE_MODE_NONEr   IO_MODE_NATIVEr   r   r   r^   rT  )rA   rW  discard_unmapused_targetsr   r   r   set_defaults  sL   





zDeviceDisk.set_defaults)FF)NNN)r!   r"   r#   r%   r   r   r   ri  CACHE_MODE_WRITETHROUGHCACHE_MODE_WRITEBACKCACHE_MODE_DIRECTSYNCCACHE_MODE_UNSAFECACHE_MODESDISCARD_MODE_IGNOREDISCARD_MODE_UNMAPDISCARD_MODESr   
DEVICE_LUNr*  r-  r   r   r   r   r   rj  staticmethodro   r   r   r   r   r   r   r$   ru   r   r   r   r   r   r   r'   r3   r   r   r   r   driver_copy_on_readsgiorawior   r   	removablerotation_rater   r   	transienttransient_shareBackingr   r   r   r   r   r   r   serialwwnstartup_policylogical_block_sizephysical_block_size
iotune_rbs
iotune_ris
iotune_tbs
iotune_tis
iotune_wbs
iotune_wisr
   	seclabelsgeometry_cylsgeometry_headsgeometry_secsgeometry_transreservations_managedreservations_source_typereservations_source_pathreservations_source_moder   r   r   r   r   propertyr/   r   r   r)  r   r   r   r   r  r  r  r  r  r  r  r  r  r"  r   r  r&  r   r+  r.  r/  r0  r2  r6  r7  r8  r9  r:  rH  rT  r[  rf  rm  r   r   r   r   r      s   

+

6.


	

"			'r   )r}   loggerr   rN   r   r   r   r)  r   r	   r
   
xmlbuilderr   r   r   r   r   r&   r'   r   r   r   r   r   <module>   s   
 