i'dWc@sLdZddkZddkZddklZddklZddklZddk l Z ddk l Z l Z ddklZdd klZdd klZdd klZlZlZlZlZlZdd klZdd klZddk l!Z!ddk"l#Z#dZ$dZ%dZ&dZ'dZ(dZ)dZ*dZ+dZ,dZ-dZ.dZ/dZ0dZ1dZ2de fd YZ3d!e fd"YZ4d#e fd$YZ5d%e fd&YZ6d'e fd(YZ7d)efd*YZ8d+e8fd,YZ9d-e8fd.YZ:d/e fd0YZ;d1e<fd2YZ=dS(3ss logical.py -- library containing class definitions for logical DOC objects, including Zpool, Filesystem, and Zvol iN(tetree(tNVList(tNV_UNIQUE_NAME(tPopen(t DataObjectt ParsingError(tDataObjectDict(tINSTALL_LOGGER_NAME(tvdevs(tbe_listtbe_initt be_destroyt be_activatetbe_mountt be_unmount(t ShadowLogical(t ShadowZpool(tSize(tset_vdevs/usr/sbin/beadms /usr/sbin/dfs/usr/sbin/dumpadms/usr/sbin/lofiadms/usr/sbin/mkfiles/usr/sbin/mounts/usr/sbin/newfss/usr/sbin/swaps/usr/sbin/umounts /usr/sbin/zfss/usr/sbin/zpooltsolarissboot-environmentsbe-names be-mountpointtLogicalcBskeZdZdZdZedZedZeed dZ dZ dZ dZ RS( s! logical DOC node definition cCs;tt|i|t|_t|_t||_dS(N(tsuperRt__init__tFalsetnoswaptnodumpRt _children(tselftname((s ../logical.pyRFs  cCsQtid}|idt|ii|idt|ii|S(NtlogicalRR(RtElementtsettstrRtlowerR(Rtelement((s ../logical.pytto_xmlOscCs|idjotStS(s; Returns True if the element has the tag 'logical' R(ttagtTrueR(tclsR"((s ../logical.pyt can_handleUsc Cs|id}|id}td}|dj oOy%htd6td6|i|_Wqtj otddqXn|dj oOy%htd6td6|i|_ Wqtj otddqXn|S( NRRRttruetfalses$Logical element's noswap attribute s must be either 'true' or 'false's$Logical element's nodump attribute ( tgetRtNoneR%RR!RtKeyErrorRR(R&R"RRR((s ../logical.pytfrom_xml]s   % %cCsV|o|otdnt|}||_||_||_|i||S(sk add_zpool() - method to create a Zpool object and add it as a child of the Logical object s:Zpool cannot be marked as the boot pool and the root pool.(t ExceptiontZpooltis_roottis_boott mountpointtinsert_children(Rt zpool_nameR0R1R2t new_zpool((s ../logical.pyt add_zpoolss     cCs|id|idtdS(sC delete_zpool() - method to delete a specific Zpool object Rt class_typeN(tdelete_childrenRR/(Rtzpool((s ../logical.pyt delete_zpoolscCs(tt|i}t||_|S(s method to override the parent's version of __copy__. We want the _children list to be a shadow list instead of a flat list (RRt__copy__RR(Rtnew_copy((s ../logical.pyR;scCsd|i|ifS(NsLogical: noswap=%s; nodump=%s(RR(R((s ../logical.pyt__repr__sN(t__name__t __module__t__doc__RR#t classmethodR'R-RR+R6R:R;R=(((s ../logical.pyRBs    R/cBsOeZdZdddZdZedZedZe dZ e dZ dZ e dZ e d Ze d Ze d Zd Zd ZddZgddZedZedZdZdZdZddZdZdeidedZ dZ!dZ"dZ#RS(s zpool DOC node definition cCsvtt|i|d|_t|_t|_||_t|t p|g|_ n ||_ t ||_ dS(Ntcreate( RR/RtactionRR0R1R2t isinstancetlistt vdev_listRR(RRRFR2((s ../logical.pyRs     cCstid}|id|i|id|i|idt|ii|idt|ii|i dj o|id|i n|S(NR9RRCR0R1R2( RRRRRCR R0R!R1R2R+(RR"((s ../logical.pyR#scCs4|idjotS|iddjotStS(s{ Returns True if element has: - the tag 'zpool' - a name attribute otherwise return False R9RN(R$RR*R+R%(R&R"((s ../logical.pyR's c CsG|id}|id}|id}|id}|id}t|}|dj o ||_n|dj oOy%htd6td6|i|_Wqtj ot dd qXn|dj oOy%htd6td6|i|_ Wq)tj ot d d q)Xn|dj o ||_ n|S( NRRCR0R1R2R(R)s'Zpool element's is_root attribute must sbe either 'true' or 'false's'Zpool element's is_boot attribute must ( R*R/R+RCR%RR!R0R,RR1R2(R&R"RRCR0R1R2R9((s ../logical.pyR-s.    % %  cCsQ|idt}|o1x.|D]"}d|ijo |idSq Wn|iS(s property to return the pool's realname (the name it will be the next time it's exported) as set in the pool object's PoolOptions R7trealname(t get_childrent PoolOptionst data_dictR(Rtpool_options_listt pool_options((s ../logical.pyRGscCsItd|ig}ti|dtidtidti}|idjS(s: property to check for the existance of the zpool REtstdouttstderrt check_resulti(tZPOOLRRt check_calltSTOREtANYt returncode(Rtcmdtp((s ../logical.pytexistss c Cs|djotd|n|ipdStddd|dd d |ig }ti|d tid tid t}|i i S(sD private method to return all datasets of a particular type t filesystemtvolumetsnapshotsdataset_type not supported: %sREs-Hs-ts-oRs-rRMRNtlogger(s filesystemRYssnapshotN( t ValueErrorRWR+tZFSRRRQRRtILNRMt splitlines(Rt dataset_typeRURV((s ../logical.pyt_get_dataset_namess    cCs7g}x*|idD]}|it|qW|S(sC method to return all filesystems which belong to the pool RX(Ratappendt Filesystem(Rtfs_listtfs((s ../logical.pyt filesystems s cCs7g}x*|idD]}|it|qW|S(s? method to return all volumes which belong to the pool RY(RaRbtZvol(Rtvol_listtvol((s ../logical.pytvolumess cCs |idS(sA method to return all snapshots which belong to the pool RZ(Ra(R((s ../logical.pyt snapshotsscCs|ioti|iSdS(s method to return a dictionary representing this pool's vdev(s) and each vdev's devices. dictionary is keyed by vdev name ('none' if it's not named) and each value is a list of disk aliases. N(RWRt_get_vdev_mappingR(R((s ../logical.pyR"s cCs|idt}|p#tdt}|i|n=d}x3|D]!}d|ijo |}PqIqIW|d}|i|id<||_dS(sW method to set name of Zpool object with 'temp_name' and set Zpool object's 'realname' property with current name. Upon creation, pool will be named 'temp_name', but because it will be set up with the 'realname' pool property, upon export of the pool, zfs will rename it to 'realname'. R7RGiN(RHRIR+tdictR3RJRt_name(Rt temp_nameRKRLtentry((s ../logical.pyt set_temp_name+s  cCsStdd||f|ig}|p)ti|dtidtidtndS(s/ method to set a property for the pool Rs%s=%sRMRNR[N(RPRRRQRRR^(Rtpropnamet propvaluetdry_runRU((s ../logical.pyRKstallc Cstd||ig}ti|dtidtidt}t}xC|iidD].}|i i \}}}}|||td d |ig}t i |dt i dt i d tqjnd S( s method to create the zpool from the vdevs options - optional list of pool and/or dataset options to pass to the create flag RBs-fs-Bs-Rs-msInvalid entry in vdev_list: RMRNR[tinheritR2N(RPR1R0RbtextendR2R+RRFt RuntimeErrorR RRQRRR^R](RRttoptionstaltrootRU((s ../logical.pyRBhs,  cCsv|iohtdg}|o|idn|i|i|p)ti|dtidtidtqrndS(s% method to destroy the zpool tdestroys-fRMRNR[N(RWRPRbRRRQRRR^(RRttforceRU((s ../logical.pyRs  cCsT|ioFtd|ig}|p)ti|dtidtid|qPndS(ss method to export the zpool. Allow logger to be passed in to to overrride default install logger. texportRMRNR[N(RWRPRRRQRR(RRtR[RU((s ../logical.pyRs  cCs&t|}||_|i||S(sg add_vdev() - method to create a Vdev object and add it as a child of the Zpool object (tVdevt redundancyR3(RtlabelRtnew_vdev((s ../logical.pytadd_vdevs   cCs|id|idtdS(sA delete_vdev() - method to delete a specific Vdev object RR7N(R8RR(Rtvdev((s ../logical.pyt delete_vdevsc Cs|ipdS|idjodSttdt|}|iidjp|iidjo d}nd|iid|}|iidjp|iidjo d}n|iid|}|iidjp|iidjo d}n|iid|}d|id|}t i t } | i d||i |||f|pt|i ||||ndS( s set_vdev() - method to update the zpool's metadata with disk's installed target path information (specified in disk's vdev_label.) Ntats /dev/dsk/tst:t/scUpdating path '%s' in label of zpool '%s' with: new path: %s new devpath: %s new devid: %s(RWt vdev_labelR+tchrtordtinttctdtdevpathtdevidtloggingt getLoggerR^tdebugRR( RRttdisktslicetlettertnew_patht new_devpatht new_devidtcur_pathR[((s ../logical.pyRs( & & &  cCs&t|}||_|i||S(sq add_filesystem - method to create a Filesystem object and add it as a child of the Zpool object (RcR2R3(Rtfs_nameR2tnew_filesystem((s ../logical.pytadd_filesystems   cCs|id|idtdS(sM delete_filesystem() - method to delete a specific Filesystem object RR7N(R8RRc(RRX((s ../logical.pytdelete_filesystemsRcCst|}|oF|djo ||_qYt|id}t|||_n|dj o ||_n||_|i||S(se add_zvol - method to create a Zvol object and add it as a child of the Zpool object tmaxtbBN(RgtsizeR trstripR+tusetcreate_failure_okR3(Rt zvol_nameRt size_unitsRRtnew_zvol((s ../logical.pytadd_zvols       cCs|id|idtdS(sA delete_zvol() - method to delete a specific Zvol object RR7N(R8RRg(Rtzvol((s ../logical.pyt delete_zvolscCs(tt|i}t||_|S(s method to override the parent's version of __copy__. We want the _children list to be a shadow list instead of a flat list (RR/R;RR(RR<((s ../logical.pyR;scCsd|i|if}|d|i7}|d|i7}|idj o|d|i7}n|idj o|dt|i7}n|S(NsZpool: name=%s; action=%ss ; is_root=%ss ; is_boot=%ss; mountpoint=%ss ; vdev_list=(RRCR0R1R2R+RFR (RR((s ../logical.pyR=&sN($R>R?R@R+RR#RAR'R-tpropertyRGRWRaRfRjRkRRqRR*RBRRR^RRRRRRRtgb_unitsRRR;R=(((s ../logical.pyR/s8       2  *     RcBsGeZdZdZdZedZedZdZRS(s vdev DOC node definition cCs#tt|i|d|_dS(Ntmirror(RRRR(RR((s ../logical.pyR5scCs9tid}|id|i|id|i|S(NRRR(RRRRR(RR"((s ../logical.pyR#:scCs|idjotStS(NR(R$R%R(R&R"((s ../logical.pyR'@scCsH|id}|id}t|}|dj o ||_n|S(NRR(R*RR+R(R&R"RRR((s ../logical.pyR-Fs    cCsd|i|ifS(NsVdev: name=%s; redundancy=%s(RR(R((s ../logical.pyR=Os( R>R?R@RR#RAR'R-R=(((s ../logical.pyR1s    RccBs eZdZdZedZedZdZedZ edZ dZ e dZ d Zd ZeeZe d Ze d Ze d ZdZe dZde dZe dZe dZe dZedZRS(s$ Filesystem DOC node definition cCs5tt|i|d|_d|_t|_dS(NRB(RRcRRCR+R2Rtin_be(RR((s ../logical.pyRWs  cCs|idj ow|ioD|iidt}tii|iid|i|ii dStii|ii|ii dSn|iSdS(s Keep a full_name attribute with the entire ZFS path for the filesystem. This is done because Filesystem objects can be created via Zpool.add_filesystem, simple instantiation, or with the in_be attribute set. R7tROOTRN( tparentR+Rtget_first_childtBEtostpathtjoinRtlstrip(Rtbe((s ../logical.pyt full_name_s )cCs|idj ow|ioD|iidt}tii|iid|i |i i dStii|ii|i i dSn|i SdS(s The full_realname attribute returns the full name as it will be the next time the zpool in which this filesystem belongs will be imported. R7RRN( RR+RRRRRRRGRR(RR((s ../logical.pyt full_realnamers cCstid}|id|i|id|i|idj o|id|in|idt|ii |S(NRXRRCR2R( RRRRRCR2R+R RR!(RR"((s ../logical.pyR#scCs4|idjotS|iddjotStS(s Returns True if element has: - the tag 'filesystem' - a name attribute - an action attribute otherwise return False RXRN(R$RR*R+R%(R&R"((s ../logical.pyR's cCs|id}|id}|id}|id}t|}|dj o ||_n|dj o ||_n|dj oOy%htd6td6|i|_Wqt j ot ddqXn|S( NRRCR2RR(R)s%Filesystem element's in_be attribute s must be either 'true' or 'false'( R*RcR+RCR2R%RR!RR,R(R&R"RRCR2RRX((s ../logical.pyR-s"       cCs?d|i|if}|idj o|d|i7}n|S(NsFilesystem: name=%s; action=%ss; mountpoint=%s(RRCR2R+(RR((s ../logical.pyR=scCsx|i|}|o*||ijo|idtd|ntd|g}ti|dtidtidtdS(s snapshot - method to create a ZFS shapshot of the filesystem snapshot_name - name of the snapshot to create overwrite - boolean argument to determine if ZFS should delete an existing snapshot with the same name (if it exists) RtRZRMRNR[N( tsnapnamet snapshot_listRRR]RRQRRR^(Rt snapshot_namet overwritetsnapRU((s ../logical.pyRZs cCs|id|S(sNReturns the full (dataset@snapshot) name based on the given short namet@(R(Rt short_name((s ../logical.pyRsc Cs^tddddddddd |ig }ti|d tid tid t}|iiS( so Get list of snapshots. Snapshots returned will be in creation time order with the earliest first REs-Hs-oRs-tRZs-stcreations-rRMRNR[(R]RRRQRRR^RMR_(RRURV((s ../logical.pyt _snapshotss  cCsctdg}|o|idn|i|i|ti|dtidtidtdS(sV rollback - method to rollback a ZFS filesystem to a given checkpoint trollbacks-rRMRNR[N(R]RbRRRQRRR^(Rt to_snapshott recursiveRU((s ../logical.pyRs  cCsntdd||f|ig}|o|iddn|p)ti|dtidtidtndS( s8 method to set a property on the ZFS filesystem Rs%s=%sis-rRMRNR[N(R]RtinsertRRQRRR^(RR{R|RtRRU((s ../logical.pyRs cCsdtd||ig}|o|iddn|p)ti|dtidtidtndS(s< method to inherit a property on the ZFS filesystem R}is-rRMRNR[N(R]RRRRQRRR^(RR{RtRRU((s ../logical.pyR}s c Cs[tdddd||ig}ti|dtidtidtidt}|ii S( sI method to return the value for a ZFS property of the filesystem R*s-Hs-oR|RMRNtstderr_loglevelR[( R]RRRQRRRtDEBUGR^RMRv(RR{RURV((s ../logical.pyR*sc Cs|iptddg}|idt}|d j o|i|in|id j o|idd|ign|i|i |p6t i |dt i dt i dt d hd d 6qnd S( s create the filesystem RBs-pR7s-os mountpoint=%sRMRNR[tenvtCtLC_ALLN(RWR]RtOptionsR+R~t get_arg_listR2RbRRRQRRR^(RRtRUt zfs_options((s ../logical.pyRBs  cCs|io|ptdg}|o|idn|dj o|i|i|n|i|iti|dtidtidt qndS(s destroy the filesystem Rs-rRMRNR[N( RWR]RbR+RRRRQRRR^(RRtRZRRU((s ../logical.pyRs   c Csa|ioStd|ig}|p6ti|dtidtidtdhdd6q]ndS( s mount the filesystem tmountRMRNR[RRRN(RWR]RRRQRRR^(RRtRU((s ../logical.pyR"s  c Csa|ioStd|ig}|p6ti|dtidtidtdhdd6q]ndS( s umount the filesystem tumountRMRNR[RRRN(RWR]RRRQRRR^(RRtRU((s ../logical.pyR+s  c Csk|io]tddd||ig}|p6ti|dtidtidtdhdd 6qgnd S( s* Temporarily mount the filesystem Rs-os mountpoint=%sRMRNR[RRRN(RWR]RRRQRRR^(Rt temp_mountRtRU((s ../logical.pyttemporary_mount4s   cCsItd|ig}ti|dtidtidti}|idjS(s? property to check for the existance of the filesystem RERMRNROi(R]RRRQRRRSRT(RRURV((s ../logical.pyRW>s N(R>R?R@RRRRR#RAR'R-R=RRZRRRRRR}R*RBR+RRRRRW(((s ../logical.pyRcSs,         RgcBseZdZdZedZedZdZedZ edZ edZ dZ d Z d Zd Zd Zeid ZRS(s Zvol DOC node definition cCs>tt|i|d|_d|_d|_t|_dS(NRBtnoneR(RRgRRCRRRR(RR((s ../logical.pyRLs    cCs8|idj otii|ii|iS|iSdS(s keep a full_name attribute with the entire ZFS path for the zvol. This is done because Zvol objects can either be created via Zpool.add_zvol or by simple instantiation (Zvol("tank/zv")) N(RR+RRRR(R((s ../logical.pyRUscCs8|idj otii|ii|iS|iSdS(s The full_realname attribute returns the full name as it will be the next time the zpool in which this zvol belongs will be imported. N(RR+RRRRGR(R((s ../logical.pyRascCswtid}|id|i|id|i|id|iti|d}|idt|i|S(NRRRCRRtval( RRRRRCRt SubElementR R(RR"R((s ../logical.pyR#lscCs4|idjotS|iddjotStS(s Returns True if element has: - the tag 'zvol' - a name attribute - an action attribute otherwise return False RRN(R$RR*R+R%(R&R"((s ../logical.pyR'ws cCs |id}|id}|id}t|}|id}|dj o|iddjotddn|iddjo.|djp |d jotd qn|id|_n td ||_|dj o ||_n|S( NRRCRRRs"Size element must contain a 'val' t attributeRtswapsA'max' value for 'val' attribute is applicable only for swap zvol.s+Zvol element must contain a size subelement(R*RgtfindR+RRRCR(R&R"RRCRRR((s ../logical.pyR-s$      cCsItd|ig}ti|dtidtidti}|idjS(s9 property to check for the existance of the zvol RERMRNROi(R]RRRQRRRSRT(RRURV((s ../logical.pyRWs c Cs[tdddd||ig}ti|dtidtidtidt}|ii S( sE method to return the value for a ZFS property of the volume R*s-Hs-oR|RMRNRR[( R]RRRQRRRRR^RMRv(RR{RURV((s ../logical.pyR*sc Cs\|idjo^tdtiid|ig}|p2ti|dtidtidt dt i qXn|idjot d tiid|ig}|i o d}nd}|pqti|dtidtidt dt i d |}|id jo't it }|id |iq1qXn$t it }|id|idS(sE method to add zvol (for use as swap or dump) to live system Rs-as /dev/zvol/dskRMRNR[Rtdumps-diiROs(Unable to create dump Zvol with size %s.sEZvol %s does not have use of 'swap' or 'dump'. Not adding to system.N(ii(i(RtSWAPRRRRRRQRRR^RRtDUMPADMRRTRtwarningR(RRtRUtresultsRVR[((s ../logical.pyt add_to_systems0!      c Css|ipet|ito)tt|iitid}n|idjot|idj o`t |ii }t|id}tt|itidd}t||_qn |i}t ddd|g}|i dt}|dj o|i|in|i|i|p6ti|d tid tid td hd d6qondS(s" method to create a zvol. tMRt availableg?RBs-ps-VR7RMRNR[RRRN(RWRDRRR RR*tmb_unitsRR+RcRR]RRR~RRbRRRQRRR^(RRtt zvol_sizeRetfs_sizeRUR((s ../logical.pyRBs& )  c Cs|io|ptiid|i}tdg}ti|dtidtidt dti dt i }|i id}x_|D]W}|i|oAtd |g}ti|dtidtidt dt i qqWtitgdtidtidt }x|i iD]U}|iid o9||jo(t it }|id |iPqrqqWtd |ig}ti|dtidtidt qnd S(s# method to destroy a zvol. s /dev/zvol/dsks-lRMRNR[RORis-ds Dump device:s:Unable to destroy Zvol '%s' as it is under dumpadm controlRN(RWRRRRRRRQRRR^RSRRRMR_t startswithRRRRR]( RRtt full_pathRURVt swap_listRpRyR[((s ../logical.pyRs:        cCs d|i|i|i|ifS(Ns)Zvol: name=%s; action=%s; use=%s; size=%s(RRCRR(R((s ../logical.pyR="scCs@|i|ii|i||t|t||_dS(s4 resize() - method to resize a Zvol object. N(tdeleteRRRR R(Rtnew_sizeR((s ../logical.pytresize&s (R>R?R@RRRRR#RAR'R-RWR*RRBRR=RRR(((s ../logical.pyRgHs     ! . RcBsJeZdZdZdZdZedZedZdZ dZ RS(s)Base class for all ZFS options variationsRtoptions-ocCs)tt|id|dtdtdS(sInitialize ZfsOptionsDict. t generate_xmlt value_as_attrN(RRRR+R%(RRRJR((s ../logical.pyR:scCsxt}xh|iD]]}|i|i|o"|id||i|fq|id||i|fqW|S(s9Returns a list of arguments suitable for passing to Popens%s="%s"s%s=%s(RERJRbtOPTIONS_PARAM_STR(Rtquotetarg_listtkey((s ../logical.pyRDs  ""cCsitdt}|idjpt|idjo|Sx(|iD]}|i|||dfRRR%(R((s ../logical.pyR=]s ( R>R?R@tTAG_NAMEt SUB_TAG_NAMERRRRRR=(((s ../logical.pyR3s RIcBseZdZdZRS(s pool_options DOC node definition Its a DataObjectDict using the tags like: RL(R>R?R@R(((s ../logical.pyRIbs tDatasetOptionscBseZdZdZdZRS(s' dataset_options DOC node definition Its a DataObjectDict using the tags like: tdataset_optionss-O(R>R?R@RR(((s ../logical.pyRqs RcBseZdZddZedZdZedZ edZ edZ edZ edZ d Zd edddded Zd Zd ZddZddZRS(s be DOC node definition cCsU|djo t}ntt|i|d|_||_d|_d|_dS(N( R+tDEFAULT_BE_NAMERRRt created_namet initial_nameR2tpoolname(RR((s ../logical.pyRs     cCs|ip|iS(N(RR(R((s ../logical.pyRscCs&tid}|id|i|S(NRR(RRRR(RR"((s ../logical.pyR#scCs|idjotStS(s] Returns True if element has: - the tag 'BE' otherwise return False R(R$RR%(R&R"((s ../logical.pyR'scCs3|id}|ot|}n t}|S(NR(R*R(R&R"RR((s ../logical.pyR-s  cCst|i|i}|S(s7 property to check for the existance of the BE (R RR(RRW((s ../logical.pyRWscCs!t|i|idd}|S(s- returns True if BE is the active BE ii(R RR(Rtactive((s ../logical.pyt is_activescCs;t|i|i}t|djpt|ddS(s9 returns a list of datasets that make up this BE iii(R RRRtAssertionError(Rtbelist((s ../logical.pytdatasetsscCs6d|i}|idj o|d|i7}n|S(Ns BE: name=%ss; mountpoint=%s(RR2R+(RR((s ../logical.pyR=s trpoolc Cs|p|idt} t|i|d|d| d|d|d|d|d|} |o:| d j o-tit} | id | | |_ n|i d j o|i |i ||n||_ nd S( sZ method to initialize a BE by creating the empty datasets for the BE. R7t nested_betzfs_propertiesRdtfs_zfs_propertiestshared_fs_listtshared_fs_zfs_propertiestallow_auto_namings!Initialized BE with auto name: %sN( RRR RR+RRR^RRR2RR( RRtt pool_nameR RdRRRRt be_optionstnew_nameR[((s ../logical.pytinits    cCs|pt|indS(s! method to destroy a BE. N(R R(RRt((s ../logical.pyRscCs|pt|indS(s" method to activate a BE. N(R R(RRt((s ../logical.pytactivatescCsp|petii|pti|n|ot|i||nt|i||i||_ndS(s method to mount a BE. N(RRRWtmakedirsR RRR2(RR2Rttaltpool((s ../logical.pyRscCsF|p;|ot|i|nt|i|id|_ndS(s! method to unmount a BE. N(RRRR+R2(RRtR((s ../logical.pytunmounts N(R>R?R@R+RRRR#RAR'R-RWRR R=RR%RRRRR(((s ../logical.pyRs$        tLoficBseZdZdddeedZedZedZei dZdZ dZ dZ d Z d Zd Zd Zd ZdZRS(ss class representing a loopback file interface. The backing-store does not have to exist; it can be created icCsU||_||_||_||_||_d|_d|_t|_ ||_ dS(s= constructor for the class ramdisk - path to the file to use as a backing store mountpoint - Path to mount the file as a loopback device. If not provided, lofi device is not mounted. size - size of the file to create nbpi - number of bytes per inode - used when backend file is formatted with ufs(7fs). If not provided, newfs(1m) uses default value. run_newfs - If set to True, backend file is formatted with ufs(7fs). labeled - If set to True, lofi device is created as labeled. N( tramdiskR2Rt run_newfstlabeledR+tlofi_blktlofi_rawRt_mountedtnbpi(RRR2RR"RR((s ../logical.pyRs        cCstii|iS(s< property to check for the existance of the ramdisk (RRRWR(R((s ../logical.pyRW/scCs|iS(sj property to return a boolean value representing if the lofi device is currently mounted. (R!(R((s ../logical.pytmounted5scCs ||_dS(N(R!(RR((s ../logical.pyR#<scCs[|ipMtd|i|ig}|p)ti|dtidtidtqWndS(sB create_ramdisk - method to create the ramdisk, if needed s%dkRMRNR[N(RWtMKFILERRRRQRRR^(RRtRU((s ../logical.pytcreate_ramdisk@s  cCs|iS(s$ Returns block lofi device. (R(R((s ../logical.pytget_blkKscCs|iS(s" Returns raw lofi device. (R (R((s ../logical.pytget_rawPscCs |idj S(so Returns True if image file is currently exported as lofi device. Otherwise returns False. N(RR+(R((s ../logical.pyRUscCs;|i||iotdd|ig}ntd|ig}|p{ti|dtidtidt}|ii |_ |io|i i dd|_ q|i i dd |_ n|i otd d d d g}|idj o'|id|it|in|i|i |patit}|iddi|t|dtidtidti}|idqn|idj otii|i o| oti|intddd d|i |ig}|p)ti|dtidtidtnt |_!ndS(sB create - method to create, newfs and mount a lofi device s-ls-aRMRNR[tdsktrdsktlofitrlofis-mt0s-otspaces-is Executing: %sRtstdinsy s-FtufstrwN("R%RtLOFIADMRRRQRRR^RMRvRtreplaceR RtNEWFSR"R+RbR RRRRtPIPEtDEVNULLt communicateR2RRRWRtMOUNTR%R#(RRtRURVR[((s ../logical.pyRB\s@         cCs]|ioOtd|ig}|p)ti|dtidtidtnt|_ndS(s( method to unmount the ramdisk. s-fRMRNR[N(R#tUMOUNTR2RRQRRR^R(RRtRU((s ../logical.pyRs   cCsw|ipdS|i|tdd|ig}|p)ti|dtidtidtnd|_d|_ dS(s7 method to unmount and destroy the lofi device Ns-fs-dRMRNR[( RWRR1RRRQRRR^R+R (RRtRU((s ../logical.pyRs    c Cs|iotd|ig}ti|dtidti}g}|iiD]}||iqQ~}|di \}}}} } } d||| | f} nd} | S(s method to get usage. s-hRMRNis+size %s, used %s, available %s, capacity %ssunavailable (not mounted)( R#tDFR2RRQRRRMR_RRw( RRURVt_[1]tlt size_infoRRtusedtavailtcapR2tusage((s ../logical.pyt get_usages !0"cCs,d|i|i|i|i|i|ifS(NsMLofi: ramdisk=%s; mountpoint=%s; size=%s; lofi_device=%s; mounted=%s; nbpi=%s(RR2RRR!R"(R((s ../logical.pyR=sN(R>R?R@R+RRRRWR#tsetterR%R&R'RRBRRRAR=(((s ../logical.pyRs     5  (>R@RRtlxmlRt libnvpairRtlibnvpair.constRtsolaris_installRtsolaris_install.data_objectRRt%solaris_install.data_object.data_dictRtsolaris_install.loggerRR^tsolaris_install.targetRtsolaris_install.target.libbeR R R R R Rt%solaris_install.target.shadow.logicalRt#solaris_install.target.shadow.zpoolRtsolaris_install.target.sizeRt zfs.ioctlRtBEADMR9RR1R$R7R3RR8R]RPRtBOOT_ENVIRONMENTtBE_NAMEt BE_MOUNTPOINTRR/RRcRgRRIRRtobjectR(((s ../logical.pytsR  .X"/