ó »µiVc@sCdZddlZddlmZmZddlZddlmZddl j Z ddl m Z m Z ddlmZddlmZmZmZmZmZddlZddlZddlZddlZddlmZdad „Zd „Zeƒejd „ƒd „Zd „Z d„Z!d„Z"d„Z#de$d„Z%e$dd„Z&d„Z'd„Z(d„Z)d„Z*d„Z+d„Z,d„Z-d„Z.d„Z/dd„Z0e1d„Z2e1d„Z3dd„Z4d „Z5d!„Z6d"„Z7d#„Z8d$„Z9d%„Z:d&„Z;d'„Z<d(„Z=dde1d)„Z>dS(*s" PRIVATE ZFS HELPERS FOR BOOTMGMT iÿÿÿÿN(tcfunctconst(t LoggerMixin(tNVListtnvlistp(tNV_UNIQUE_NAME(t BootmgmtErrortBootmgmtZFSErrortBootmgmtArgumentErrortBootmgmtZFSPoolNotFoundErrortBootmgmtZFSPoolConflictError(tQueuecCstr tStjƒatS(s (t __libzfshRt libzfs_init(((s%../../common/bootmgmt/zfs/__init__.pyR s cCs trtjtƒdandS(s N(R Rt libzfs_finitNone(((s%../../common/bootmgmt/zfs/__init__.pyR(s cCstƒS(N(R(((s%../../common/bootmgmt/zfs/__init__.pyt3scCsôtjt|tjƒ}tj|tjƒjdkrxt d|tj tƒdtj tƒfdtj tƒƒ‚ntj||tƒ}zR|dkrÞt d|tj tƒdtj tƒfdtj tƒƒ‚nWdtj|ƒXdS(sRenames the given datasetsFailed to open dataset %s: %ss: terrCodeisFailed to rename dataset %s: %sN(Rtzfs_openR RtZFS_TYPE_FILESYSTEMtCtcasttc_void_ptvalueRRtlibzfs_error_actiontlibzfs_error_descriptiont libzfs_errnot zfs_renametFalset zfs_close(told_dstnew_dstzfshtret((s%../../common/bootmgmt/zfs/__init__.pytrename_dataset5s cCs8tj|ƒ}|dj|ƒ|d|||dƒS(Ntdsqueuetfunctarg(Rt zfs_get_nametput(tzhpR%tdsname((s%../../common/bootmgmt/zfs/__init__.pyt _zfs_iterfuncLscCstƒ}|j|ƒi|d6|d6|d6}xÝ|jƒs|jdtƒ}tjt|tj ƒ}t j |t j ƒj d krÊtd|tjtƒdtjtƒfdtjtƒƒ‚nz2tj|tjtƒ|ƒ}|dkrû|SWd tj|ƒXq4Wd S( s¡ Non-recursively iterates over all filesystems under the specified starting dataset, calling the specified callback with the specified argument. R$R%R#tblocksFailed to open dataset %s: %ss: RiN(R R'temptytgetRRRR RRRRRRRRRRRtzfs_iter_filesystemst ZFS_ITER_FR*R(tstart_dsR$R%R#targdicttdatasetR tretval((s%../../common/bootmgmt/zfs/__init__.pyR.Qs"    cCs]zKy2tjƒtjd|ƒ}|r0|dSdSWntk rIdSXWdtjƒXdS(Nt mnt_specialt mnt_mountp(tpysolt mnttab_opent getmntanyRtIOErrort mnttab_close(R2tmntinfo((s%../../common/bootmgmt/zfs/__init__.pytdataset_mountpointls   cCs\tjtƒdkr:tjƒdkr:tjtjƒƒStjtƒdtjtƒSdS(Nis: ( RRR Rt get_errnotoststrerrorRR(((s%../../common/bootmgmt/zfs/__init__.pytzfs_error_stringxs'cCsŠddl}g}xˆ|D]€}|r)Pntjj|ƒ}|jdƒs]|j|ƒqn|j|jƒdƒ}|rŒ|j|ƒq|j|ƒqW|r¬|}ntj ƒ}t |ƒ} t j | |Œ|_| |_ d|_d|_d|_d|_d|_tjtt j|ƒƒ} t| tƒ} d} xE| D]=} | | d} t| ƒtkst| ƒtkr+d}xü| D]˜}||dkrŒ|dtjkrŒt|dƒtj ƒkrŒd |kr|d |kr|} |d }q$d |kr$|dkr$|} q$qŒqŒWqG|| dkrG| dtjkrGt| dƒtj ƒkrG| s„| | d} q„qGqGW| sõtj!tƒ}|dtj"gkrÁt#|ƒ‚qõt$d |t|ƒt%ƒfd tj!tƒƒ‚ntƒ}|r1x*|D]}|j&|ƒ||d ftpathtabspatht startswithtappendtstriptextendRt ImportArgstlenRtc_char_ptpathsRtpoolnamet cachefiletuniquetguidt trust_cachetzpool_search_importR tbyrefRRttypetlistttupleRtPOOL_STATE_DESTROYEDtstrR6t get_hostidRt EZFS_NOENTR RR@R-tzpool_import_propstZFS_IMPORT_ONLY(RRtdevlistt poolpropstliteral_devlistRGt newdevlisttdevRQtiargst devlist_lentpoolst found_pooltpooltpoolnvlREtdup_pooltzfs_errtpropnvltkeyterr((s%../../common/bootmgmt/zfs/__init__.pyt zpool_import€s~             $         "cCsæg}idtj6dtj6dtj6dtj6}g}|tj}|tj}t|ƒdks|dtjtj tj tj gkr®t j d|dtjƒd S|dtjtj krÜ|dtj}nxË|D]Ã}t j d|ƒ|rt|ƒ} n |tj} |dkr™d} xS|jƒD]E} y+|| rj|| | krj|| } nWq:tk r~q:Xq:W|j| | fƒqã|j| ƒqãW|rât|dd „ƒ}g|D]\} } | ^qÌS|S( s Convert a ZFS pool configuration (stored as an nvlist) to a list of constituent disk devices. This is only to be used on pool with a single top-level mirror vdev and disk/file children under that vdev, OR a single disk/file top-level vdev. iiiis&Invalid pool -- top level vdev is a %ss Child: %sthealthRpcSs|dS(Ni((tx((s%../../common/bootmgmt/zfs/__init__.pyR sN(RtZPOOL_CONFIG_DEGRADEDtZPOOL_CONFIG_OFFLINEtZPOOL_CONFIG_FAULTEDtZPOOL_CONFIG_REMOVEDtZPOOL_CONFIG_VDEV_TREEtZPOOL_CONFIG_CHILDRENROtZPOOL_CONFIG_TYPEtVDEV_TYPE_MIRRORtVDEV_TYPE_FILEtVDEV_TYPE_DISKRt_debugRtzfs_get_adjusted_pathtZPOOL_CONFIG_PATHtkeystKeyErrorRKtsorted(tnvlt wholedisktsorttsortlistt healthmapRbt vdev_treetchildrentchildRftsortvalRttitj((s%../../common/bootmgmt/zfs/__init__.pytzpool_config_to_listßsD            cCs‹tj|kr||tjr||tj}|jdƒ}|dkrx||djƒrx|| }tjd|ƒqxn|S|tjSdS(s tsiÿÿÿÿisChild[wholedisk] => %sN(RtZPOOL_CONFIG_WHOLE_DISKRtrfindtisdigitRR(RŒRftlast_s((s%../../common/bootmgmt/zfs/__init__.pyR€s    cCst|dtƒS(s R†(RtTrue(R…((s%../../common/bootmgmt/zfs/__init__.pytzpool_config_to_disklist scCs t|ƒS(s (R(R…((s%../../common/bootmgmt/zfs/__init__.pytzpool_config_to_partlist%scCst|ddƒS(s R‡Rs(R(R…((s%../../common/bootmgmt/zfs/__init__.pytzpool_config_to_healthlist*scCs`tjt|ƒ}tj|tjƒjdkrOtjtƒt j kr\t Sn tj |ƒt S(s N(Rtzpool_open_canfailR RRRRRRRR_Rt zpool_closeR–(RRtzph((s%../../common/bootmgmt/zfs/__init__.pyt zpool_exists/s  cCsòtjt|tjƒ}tj|tjƒjdkrxt d|tj tƒdtj tƒfdtj tƒƒ‚ntj|||ƒ}tj|ƒ|dkrît d|||tj tƒdtj tƒfdtj tƒƒ‚ndS(s sFailed to open dataset %s: %ss: Ris3Couldn't set zfs property %s=%s for dataset %s (%s)N(RRR RRRRRRRRRRRt zfs_prop_setR(R2tpropnametpropvalR Rq((s%../../common/bootmgmt/zfs/__init__.pyt zfs_set_prop=s   cCs›tjt|tjƒ}tj|tjƒjdkrxt d|tj tƒdtj tƒfdtj tƒƒ‚ntj||ƒ}tj|ƒ|S(sQ Returns the named property (in integer form) from the specified dataset sFailed to open dataset %s: %ss: RN(RRR RRRRRRRRRRRtzfs_prop_get_intR(R2RŸR tval((s%../../common/bootmgmt/zfs/__init__.pyR¢Us cCstjt|tjƒ}tj|tjƒjdkrxt d|tj tƒdtj tƒfdtj tƒƒ‚ntj|ƒ}tj|tjƒjdkr¶tj|ƒdSt|tƒ}y||d}Wntk rðd}nXtj|ƒ|S(sP Returns the named property (in string form) from the specified dataset sFailed to open dataset %s: %ss: RRN(RRR RRRRRRRRRRRtzfs_get_user_propsRRRRƒ(R2RŸR tnvlpR…R3((s%../../common/bootmgmt/zfs/__init__.pytzfs_get_user_propis"    cCsKtj}tj||ƒs.td|ƒ‚ntjt||ƒrGtStS(s sInvalid dataset name: %s( RRRtzfs_name_validRtzfs_dataset_existsR R–R(R2tcrtype((s%../../common/bootmgmt/zfs/__init__.pytdataset_existsƒs  cCsJtj}tj||ƒs.td|ƒ‚ntjt||ƒrGdStjt|ƒdkr¡td|tj tƒdtj tƒfdtj tƒƒ‚n|ràt ƒ}x3|j ƒD]\}}|||dfR?(torigtlibnvptdupRq((s%../../common/bootmgmt/zfs/__init__.pyR¾ÿs  cCstjt|ƒ}tj|tjƒjdkrrtd|tj tƒdtj tƒfdtj tƒƒ‚ntj |dƒ}tj|tjƒjdkrätj tƒdtj tƒ}td|dtj tƒƒ‚nt t|ƒƒ}tj|ƒ|S(sC Return the zpool configuration nvlist for the given pool. sFailed to open pool %s: %ss: RsFailed to get zpool config (%s)N(RRšR RRRRRRRRRtzpool_get_configRR¾R›(RRRœtconfigterr_strR3((s%../../common/bootmgmt/zfs/__init__.pyRÈs  c Cstjt|ƒ}tj|tjƒjd krrtd|tj tƒdtj tƒfdtj tƒƒ‚ntj |d ƒ}tj|tjƒjd krñtj tƒdtj tƒ}tj |ƒtd|dtj tƒƒ‚nt|tƒ}|tj}|tj}|dtj}|tjkrt|ƒdkrhtj |ƒtdƒ‚n|dtj}|dtj}n|tjtjgkr¸t|dƒ} ntj |ƒtdƒ‚g} g} x|D]} tjt|tdtttjdtjd| ƒƒ } | d krptj tƒdtj tƒ}| j| d| |ffƒqäntj|| | | tƒ}|rßd tj tƒd| |f}|tj tƒd 7}| j| |fƒqä| j| ƒqäWtj |ƒ| | fS( sG Add the specified list of devices to the specified boot pool. sFailed to open pool %s: %ss: RsFailed to get zpool config (%s)iis#Invalid boot pool ZFS configurations$Failed to make root vdev for %s (%s)s'Failed to attach %s to boot pool `%s' (s) N(Rt zpool_openR RRRRRRRRRRÈR›RRRRyRzR{R|ROR~R}R€tzpool_make_root_vdevR–tZPOOL_LABEL_MATCH_REQ_PARTRPRKtzpool_vdev_attach(RRt device_listRœRÉRÊt confignvlRŠt children_nvltpooltypetotherdevtfailedtsuccesstdevicetnvrootRq((s%../../common/bootmgmt/zfs/__init__.pytadd_devices_to_pool'sj            cCstjt|ƒ}tj|tjƒjdkrrtd|tj tƒdtj tƒfdtj tƒƒ‚ng}g}x‡|D]}tj ||ƒ}|dkr÷dtj tƒd||f}|tj tƒd7}|j ||fƒq…|j |ƒq…Wtj|ƒ||fS(s˜ Remove the specified devices from the boot pool. Returns a tuple of two lists, [0] = devices successfully removed, and [1] = not removed. sFailed to open pool %s: %ss: Ris)Failed to remove %s from boot pool `%s' (s) N(RRËR RRRRRRRRRtzpool_vdev_detachRKR›(RRRÏRœRÕRÔRÖRqRÊ((s%../../common/bootmgmt/zfs/__init__.pytremove_devices_from_poolxs"  ! cCsKtjt|ƒ}|jdkrctd|tjtƒdtjtƒfdtjtƒƒ‚ntj |t ƒdkrÐtjtƒdtjtƒ}tj |ƒtd||fdtjtƒƒ‚ntj |ƒdkr:tjtƒdtjtƒ}tj |ƒtd||fdtjtƒƒ‚ntj |ƒdS(s+ Destroys the named pool forcibly. sFailed to open pool %s (%s)s: Ris*Failed to disable datasets in pool %s (%s)sFailed to destroy pool %s (%s)N( RRšR tcontentsRRRRRtzpool_disable_datasetsR–R›t zpool_destroy(RRRœRÊ((s%../../common/bootmgmt/zfs/__init__.pyt destroy_pool˜s&  " "cCs›tjt|ƒ}tj|tjƒjdkrrtd|tj tƒdtj tƒfdtj tƒƒ‚ntj |ƒt jk}tj|ƒ|S(s,Returns true if the pool is unavailable sFailed to open pool %s (%s)s: RN(RRšR RRRRRRRRRtzpool_get_stateRtPOOL_STATE_UNAVAILR›(RRRœtunavail((s%../../common/bootmgmt/zfs/__init__.pytis_pool_unavail¶s  cCs t|dƒS(s+Returns the bootfs pool property value tbootfs(tzpool_prop_get(RR((s%../../common/bootmgmt/zfs/__init__.pytzpool_get_bootfsÆscCs¬tjt|ƒ}tj|tjƒjdkrOtjtƒt j krOt Sntj t j ƒ}tj|tj|ƒ|t j dƒ}tj|ƒ|dkr¥dS|jS(s iN(RRšR RRRRRRRR_Rtcreate_string_buffertZFS_MAXPROPLENtzpool_get_proptzpool_name_to_propR›(RRRŸRœtbufRq((s%../../common/bootmgmt/zfs/__init__.pyRäÌs  cCs‰tjt|ƒ}tj|tjƒjdkrOtjtƒt j krOt Sntj |||ƒ}tj |ƒ|dkrt StSdS(s iN(RRšR RRRRRRRR_Rtzpool_set_propR›R–(RRRŸR£RœRq((s%../../common/bootmgmt/zfs/__init__.pytzpool_prop_setßs  c Csåtdtƒ}tdtƒ}tjtjƒ}d||dfRHtexiststreplaceR–tstattS_ISREGtst_modetst_sizetS_ISCHRR6traw_device_sizeRKR9RRROR]RRMRÌR RtZPOOL_LABEL_REQ_PARTRRPRRRRtEZFS_DEV_INUSER RRt zpool_create(RRt devicelistRct userpropsR¶R®tfspropstmntpttautorepltpropReRÖtsuffixt check_deviceRútsbtsizetioerrtargstargslent config_nvlptcodeRq((s%../../common/bootmgmt/zfs/__init__.pytcreate_boot_poolñs                #  (?t__doc__tctypesRtbootmgmt.zfs.libzfsRRtbootmgmt.bootutiltbootmgmtRtbootmgmt.pysolR6t libnvpairRRtlibnvpair.constRRRRR R R>RütatexitR¿R RR R RtregisterR"R*R.R<R@RRrRR€R—R˜R™RR¡R¢R¦RªR¯R–R¹R³RºR¾RÈRØRÚRÞRâRåRäRìR(((s%../../common/bootmgmt/zfs/__init__.pytsb  (         _2          "      Q