asda?‰PNG  IHDR ? f ??C1 sRGB ??é gAMA ±? üa pHYs ? ??o¨d GIDATx^íüL”÷e÷Y?a?("Bh?_ò???¢§?q5k?*:t0A-o??¥]VkJ¢M??f?±8\k2íll£1]q?ù???T 3 ybnz@sBddlZddlZddlZddlZddlZddlZddlZddlZddlm Z ddl m Z ddl Z ddl mZeZ ddlmZddlmZddlmZdd lmZdd lmZmZmZmZmZdd lmZdd lmZdd l m!Z!ddl"m#Z#e$e j%dZ&e$e j%dZ'e$e j%dZ(ddZ)dZ*GdddZ+Gddde j,Z-dS)N) defaultdict)SIGINT) create_logger) blake2b_128)Archiver)Archive)FuseVersionsIndex) daemonize hardlinkablesignal_handlerformat_file_sizeError)msgpack)Item)LRUCache)RemoteRepository st_mtime_ns st_birthtimest_birthtime_nscCs tjddS)Nr)workers)llfusemainrr/usr/lib64/python3.6/fuse.py fuse_main#src@sFeZdZdZdZejdZejdks(t ddZ dd Z dd d Z d S) ItemCachez This is the "meat" of the file system's metadata storage. This class generates inode numbers that efficiently index items in archives, and retrieves items from these inode numbers. iz=cII cCsJ||_t|_d|_d|_tjdd|_tdddd|_ d|_ d|_ dS) Nri@Bzborg-tmp)prefix cSsdS)Nr)_rrr_sz$ItemCache.__init__..)capacitydispose) decrypted_repository bytearraymeta write_offsetoffsettempfileZ TemporaryFilefdrchunksindirect_items direct_items)selfr&rrr__init__AszItemCache.__init__c Cs(||j}|dkrtd|j|tdkr|jj|j|\}}}||}t|j||d}|jj|}|st |j j |g\} }||j|<t ||d} t j} | j| tt | dS|j|tdkrtj|j|d|dd } |jj| tjtt t j|jd d dStd dS) Nrz3ItemCache.get() called with an invalid inode numberI ) internal_dictSrrlittlei)Z read_sizezInvalid entry type in self.meta)r* ValueErrorr(ordindirect_entry_struct unpack_frombytesr-getnextr&get_many memoryviewrUnpackerfeedrint from_bytesr,seekioSEEK_SET) r0inoder*r"Zchunk_id_relative_offset chunk_offsetZchunk_id_offsetchunk_idchunkcsizedataunpackerZ fd_offsetrrrr<gs(    z ItemCache.getNFc#stj}dd}d}d|j}|j}|jj} fdd} xt||jj|D]\} \} } |dt |kr|t |j |_}| |||d<|}|d7}||7}t | }|j | x8y|j | }Wntjk rPYnXt|d}|r|| s| rd|krdq}t |}||k}d|dt |krX|t |j |_}|r|jjdtj}|jj|d |jd d |||d<|jd 7_n.||}| ||d ||||jd 7_||j}|d7}||fVqWqPW||_dS)Nrcs|7t|7dS)N)len)Zappend_msgpacked_bytes)msgpacked_bytes stream_offsetrr write_bytessz1ItemCache.iter_archive_items..write_bytesr3)r4partrr5r6rr2)rr@r)r(r9 pack_intozipr&r>rOr; GROW_META_BYrAunpackZ OutOfDatarr,rDrESEEK_ENDwriteto_bytesr/r.r*)r0Zarchive_item_idsfilterconsider_part_filesrMZ chunk_beginZlast_chunk_lengthr)r(Zpack_indirect_intorRkeyrKrLZcurrent_id_offsetitemZ current_itemZcurrent_item_lengthZcurrent_spans_chunksposZ item_offsetrGr)rPrQriter_archive_itemssZ$  "    zItemCache.iter_archive_itemsii )NF) __name__ __module__ __qualname____doc__rWstructStructr9sizeAssertionErrorr1r<rarrrrr.s &rcseZdZdZdZdZdZdZdZfddZ ddZ d d Z d1d d Z d2d dZ gfddZddZddZddZd3ddZddZgfddZd4ddZd5dd Zd6d!d"Zd#d$Zd7d%d&Zd8d'd(Zd9d)d*Zd+d,Zd-d.Zd:d/d0ZZS);FuseOperationsz(Export archive as a FUSE filesystem FNrcstj||_||_||_||_||_i|_tt ddd|_ d|_ i|_ t t|_tj|_tj|_d|_i|_t||_ttjjdtjpd}tjd|t|ddd|_tt d dd|_ dS) NcSsdS)Nr)r"rrrr#sz)FuseOperations.__init__..)r$r%rZBORG_MOUNT_DATA_CACHE_ENTRIESrz$mount data cache capacity: %d chunkscSsdS)Nr)r"rrrr#scSsdS)Nr)r"rrrr#s)!superr1repository_uncachedr&argsmanifestr^itemsrFILES _inode_cache _inode_countparentrdictcontentsosgetuid default_uidgetgid default_gid default_dirpending_archivesrcacherBenvironr< cpu_countloggerdebug data_cache _last_pos)r0r^Z repositoryrnrmr&Zdata_cache_capacity) __class__rrr1s(      zFuseOperations.__init__cCs|jdd|jjjr6|jr$td|j|jjjntt|_xj|j j j |jD]V}|jrh|j|j qP|jdt |jjdd}||jdtj|j <|j |j|<qPWdS)Nr)rsz_for versions view, do not specify a single archive, but always give the repository as location.geA)rsmtime) _create_dirrmlocationarchiveversionsrprocess_archiver versions_indexrnZarchivesZlist_consideringnamerBZtsZ timestamprurvfsencoder|)r0rZ archive_inoderrr_create_filesystems  z!FuseOperations._create_filesystemc Cstjd|jt|jttj|jt|jtj|jtjdt|jtjd|j j |j j |j j |j j ttj|j j tt j|j jjjtjdt|jj|jjttdd|jjD|jjdS)Nz$fuse: %d synth inodes, %d edges (%s)zfuse: %d pending archivesz]fuse: ItemCache %d entries (%d direct, %d indirect), meta-array size %s, direct items size %sz#fuse: data cache: %d/%d entries, %scss|]\}}t|VqdS)N)rO).0r^rJrrr sz2FuseOperations.sig_info_handler..)rrrrrOrsr sys getsizeofr|r}r/r.r(rvstatr,filenost_sizerroZ _capacitysumr&Zlog_instrumentation)r0Zsig_nostackrrrsig_info_handlers (zFuseOperations.sig_info_handlercCsddd}dddg}|r(|j|jd||dd d t}|rL||dd d t||d d d t|_||d d d t|_||d ddt|_||dddt|_||dddtdd|_|jdk r|jn|j }|jdk r|jn|j }d|j@} t | tt j d||d|_ |jtj||||sBt\} } t|jtsB|jj| | d } zRtd|j$td|j t} WdQRXWdQRX| dkp| tko|} Wdtj| XdS)z6Mount filesystem on *mountpoint* with *mount_options*.rc Sst|tstxt|D]\}}||kr8|j||S|j|dr|j||jddd}|tkr|j} | dkr|dS| dkrd St d ||t kry t ||dSt k rt d |dYnXy||St k rt d |dYqXqW|SdS)N=ryyestrue1Tnnofalse0Fzunsupported value in option: %s)base)rrrr)rrrr) isinstancelistri enumeratepop startswithsplitboollowerr7rB) optionsr^ZpresentZ not_presentZ wanted_typeint_baseidxZoptionvaluevrrr pop_option&s2    z(FuseOperations.mount..pop_optionz fsname=borgfsZroZdefault_permissions,ignore_permissionsTFallow_damaged_filesruidNgidumaskrT)riAgeA)moderrrSIGUSR1ZSIGINFO)r)extendrrrrrB uid_forced gid_forcedrrxrzrtimer{rrZinitr rrlrZ migrate_lockr rrrclose)r0Z mountpointZ mount_optionsZ foregroundrrrZdir_uidZdir_gidZdir_modeZold_idZnew_idZumountsignalrrrmount#s: !   zFuseOperations.mountcCsN|j}|dk r4tf|jj|j|<||j|_n |j|j|<||j|<|S)zCreate directory N)allocate_inoderr{Zas_dictrorrs)r0rsrZinorrrrps  zFuseOperations._create_dircsi|_tj}t|j|j|j||jjd}|jj }t j |jj |jj }|j pR|r\indfdd}t j|||}x|jj|jj||jjdD]\} } |rtjj| jjtj|d| _tj| j} tj| j} | ry|j| |} Wntk rYnX| |j| <q|| jd}d}x"|dd D]}|j||}q6W|j |d | ||| | |qWtj|}t!j"d||j#dS) z9Build FUSE inode hierarchy from archive metadata )r]NcsDr@| r@t|jr@|jddr@d|kr@|jddf|jd<dS)NZhardlink_masterTsourcer-path)r rr<)r_Zmatched)hardlink_masterspartial_extractrrpeek_and_store_hardlink_mastersszGFuseOperations.process_archive..peek_and_store_hardlink_masters)r\r]/rz8fuse: process_archive completed in %.1f s for archive %sr)$ file_versionsrZ perf_counterrrlr^rnrmr]strip_componentsrZ build_matcherZpatternspathsemptyZ build_filterr}raZmetadatarorvsepjoinrrrrS_ISDIRr _find_inodeKeyError process_inner process_leafrrr)r0 archive_namer Zt0rrZmatcherrr\ item_inoder_ris_dirrGsegmentsrssegmentZdurationr)rrrr|s>        zFuseOperations.process_archivec  s|j} |`|pi}fdd} d dd} d|ko8t|jr,tjj|jjtj|d} |j|jd| f\} }|rtj |}j rj |}| ||dd}yj ||}Wn"t k rtjd | | dSXj|}|jd d d |_|j|<n2| dk r0| |_|}|j|<|r0d| f||j<n|}j r~| r~j||}tj | }| ||}|dk r~| ||}|j |<|j|<|r|j||<dS) Ncsfd|krbt|}jj|d\}}dd|jD}tdj|}||kr^|d7}||fj|<|SdS)Nr-rcSsg|]\}}}|qSrr)rrIr"rrr szEFuseOperations.process_leaf..file_version..rNr)rN)rrr<r-r)r_rZfile_idZcurrent_versionZ previous_idZ chunk_idsZ contents_id)r0rr file_versionsz1FuseOperations.process_leaf..file_versionFcSsJ|r |jdd}|d|d7}tjj|\}}tjd|}|||S)Nrrz.%05dr)rsplitrvrsplitextr)rversionadd_dirZ path_fnameZextZ version_encrrrmake_versioned_names  z8FuseOperations.process_leaf..make_versioned_namerT)rz#Skipping broken hard link: %s -> %snlinkr)F)rr rrvrrrrr<rrrrrrwarningget_itemrror-rrsru)r0rr_rsr rrrZstripped_componentsrrrrr-Z link_targetrrGZenc_pathr)r0rrsL               zFuseOperations.process_leafcCs6|j|}||kr||}n|j|}|r2|||<|S)N)rur)r0r parent_inodedirrGrrrrs   zFuseOperations.process_innercCs|jd7_|jS)Nr)rr)r0rrrrszFuseOperations.allocate_inodecCsLtj}d|_d|_d|_d|_d|_d|_d|_d|_ t |drHd|_ |S)Nir f_namemax) rZ StatvfsDataf_bsizef_frsizef_blocksf_bfreef_bavailf_filesf_ffreef_favailhasattrr)r0ctxZstat_rrrstatfss zFuseOperations.statfsc CsR|jj|}|dk r|Sy |j|Stk rL|jj|}||j|<|SXdS)N)rqr<rorr})r0rGr_rrrr s    zFuseOperations.get_itemcCs2||jd}d}x|D]}|j||}qW|S)Nrr)rru)r0rr rrGrrrrrs  zFuseOperations._find_inodecCs\|j|}tj}||_d|_d|_d|_|j|j@|_ |j dd|_ |j dk rX|j n|j dkrh|j n|j|_|jdk r|jn|jdkr|jn|j|_|j dd|_|j|_d|_|j|jd|j|_|j}tr||_|j d||_|j d||_trX|j d ||_nF|d |_ |j d|d |_!|j d|d |_"t#rX|j d |d |_$|S) Nri,rrZrdeviZatimeZctimeZ birthtimegeA)%rrEntryAttributesst_inoZ generationZ entry_timeoutZ attr_timeoutrrst_moder<st_nlinkrrrxst_uidrrrzst_gidst_rdevZget_sizer st_blksize st_blocksrhave_fuse_xtime_nsr st_atime_ns st_ctime_nshave_fuse_birthtime_nsrst_mtimest_atimest_ctimehave_fuse_birthtimer)r0rGrr_entryZmtime_nsrrrgetattrs6 ((  zFuseOperations.getattrcCs|j|}|jdijS)Nxattrs)rr<keys)r0rGrr_rrr listxattr>s zFuseOperations.listxattrc CsF|j|}y|jdi|pdStk r@tjtjdYnXdS)NrrN)rr<rr FUSEErrorZENOATTR)r0rGrrr_rrrgetxattrBs  zFuseOperations.getxattrcCs*|jj|d}|r&|j|tj|gdS)N)r|rrrvr)r0rGrrrr_load_pending_archiveIsz$FuseOperations._load_pending_archivecCsV|j||dkr|}n4|dkr,|j|}n |j|j|}|sLtjtj|j|S)N.s..) r rsrur<rrerrnoENOENTr)r0rrrrGrrrlookupOs   zFuseOperations.lookupcCs2|js.|j|}d|kr.tjdtjtj|S)NZchunks_healthyzzFile has damaged (all-zero) chunks. Try running borg check --repair. Mount with allow_damaged_files to read damaged files.)rrrrrrr ZEIO)r0rGflagsrr_rrropen[s    zFuseOperations.opencCs|j||S)N)r )r0rGrrrropendirgs zFuseOperations.opendircCsTg}|j|}|jj|d\}}||kr0d\}}||8}|j}xt|t|D]} || \} } } | |kr|| 8}|| 7}|d7}qPt|| |} | |jkr|j| }|| t|kr|j| =n0|jj | |j j| }|| t|kr||j| <|j |||| d}|| 8}|sP||jkr6|jj |||fn||f|j|<PqPWdj |S)NrrrN)rr)rr)rrr<r-rangerOminrr^ZdecryptrlappendZupdr)r0fhr*rhpartsr_Zchunk_norHr-ridsrKrrLrrrreadks>      zFuseOperations.readccshd|fd|j|fg}|j|j|jx8t||d|D]"\}\}}||j||dfVq>WdS)Nr s..r)rsrrurorr)r0rZoffZentriesirrGrrrreaddirs zFuseOperations.readdircCs|j|}tj|jS)N)rrvrr)r0rGrr_rrrreadlinks zFuseOperations.readlink)F)N)N)N)N)N)N)N)N)N) rbrcrdrerrrrrr1rrrrrrrrrrrrrrr r rrrrr __classcell__rr)rrrjs8  M ,G       +rj).r rErvrrfrr+r collectionsrrrrrrZcrypto.low_levelrZarchiverrrrZ hashindexr Zhelpersr r r r rrr_rZlrucacherZremoterrrrrrrrprZ Operationsrjrrrrs:              +