509318396
Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­
<!DOCTYPE html>
<html>
3
y¾œbnz  ã               @   sB  d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlm	Z	 d dl
mZ d dlZddlmZ eƒ 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mZmZ ddlmZ ddlmZ ddl m!Z! ddl"m#Z# e$ej%dƒZ&e$ej%dƒZ'e$ej%dƒZ(dd„ Z)dZ*G dd„ dƒZ+G dd„ dej,ƒZ-dS )é    N)Údefaultdict)ÚSIGINTé   )Úcreate_logger)Úblake2b_128)ÚArchiver)ÚArchive)ÚFuseVersionsIndex)Ú	daemonizeÚhardlinkableÚsignal_handlerÚformat_file_sizeÚError)Úmsgpack)ÚItem)ÚLRUCache)ÚRemoteRepositoryÚst_mtime_nsÚst_birthtimeÚst_birthtime_nsc               C   s   t jdd�S )Nr   )Úworkers)ÚllfuseÚmain© r   r   ú/usr/lib64/python3.6/fuse.pyÚ	fuse_main#   s    r   é   c               @   sF   e Zd ZdZdZejdƒZejdks(t	‚dd„ Z
dd	„ Zdd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.
    é   i   z=cIIé	   c             C   sJ   || _ tƒ | _d| _d| _tjdd�| _tddd„ d�| _	d| _
d| _d S )	Nr   i@B zborg-tmp)Úprefixé
   c             S   s   d S )Nr   )Ú_r   r   r   Ú<lambda>_   s    z$ItemCache.__init__.<locals>.<lambda>)ÚcapacityÚdispose)Údecrypted_repositoryÚ	bytearrayÚmetaÚwrite_offsetÚoffsetÚtempfileZTemporaryFileÚfdr   ÚchunksÚindirect_itemsÚdirect_items)Úselfr&   r   r   r   Ú__init__A   s    zItemCache.__init__c             C   s(  || j  }|dk rtdƒ‚| j| tdƒkrÀ| jj| j|ƒ\}}}|| }t| j||d … ƒ}| jj|ƒ}|s�t	| j
j|gƒƒ\}	}|| j|< t|ƒ|d … }
tjƒ }|j|
ƒ tt	|ƒd�S | j| tdƒk�rtj| j|d |d … d	ƒ}| jj|tjƒ tt	tj| jd
d�ƒd�S tdƒ‚d S )Nr   z3ItemCache.get() called with an invalid inode numberó   Ié    )Úinternal_dictó   Sr   r   Úlittlei   )Z	read_sizezInvalid entry type in self.meta)r*   Ú
ValueErrorr(   ÚordÚindirect_entry_structÚunpack_fromÚbytesr-   ÚgetÚnextr&   Úget_manyÚ
memoryviewr   ÚUnpackerÚfeedr   ÚintÚ
from_bytesr,   ÚseekÚioÚSEEK_SET)r0   Úinoder*   r"   Zchunk_id_relative_offsetÚchunk_offsetZchunk_id_offsetÚchunk_idÚchunkÚcsizeÚdataÚunpackerZ	fd_offsetr   r   r   r<   g   s(    


zItemCache.getNFc             #   s  t jƒ }d‰d}d}d‰ | j}| j}| jj}	‡ ‡fdd„}
�xºt|| jj|ƒƒD �]¢\}\}}|d t	|ƒkr‚|t
| jƒ  | _}||||d …< |}|d7 }||7 }t	|ƒ}|j|ƒ �x8y|j|
ƒ}W n t jk
râ   P Y nX t|d�}|rþ||ƒ �s| �rd|k�rd‰ q¼ˆ }t	|ƒ}ˆ| |k }d‰ |d t	|ƒk�rX|t
| jƒ  | _}|�r¦| jjdtjƒ}| jj|ƒ d	|jd
dƒ |||d …< |  jd7  _n.ˆ| | }|	||d|| |ƒ |  jd7  _|| j }|d7 }||fV  q¼W qPW || _d S )Nr   ó    c                s   ˆ | 7 ‰ ˆt | ƒ7 ‰d S )N)Úlen)Zappend_msgpacked_bytes)Úmsgpacked_bytesÚstream_offsetr   r   Úwrite_bytesŽ   s    z1ItemCache.iter_archive_items.<locals>.write_bytesr3   )r4   Úpartr   r5   é   r6   r   r2   )r   r@   r)   r(   r9   Ú	pack_intoÚzipr&   r>   rO   r;   ÚGROW_META_BYrA   ÚunpackZ	OutOfDatar   r,   rD   rE   ÚSEEK_ENDÚwriteÚto_bytesr/   r.   r*   )r0   Zarchive_item_idsÚfilterÚconsider_part_filesrM   Zchunk_beginZlast_chunk_lengthr)   r(   Zpack_indirect_intorR   ÚkeyrK   rL   Zcurrent_id_offsetÚitemZcurrent_itemZcurrent_item_lengthZcurrent_spans_chunksÚposZitem_offsetrG   r   )rP   rQ   r   Úiter_archive_items   sZ    $

"
zItemCache.iter_archive_itemsi   i    )NF)Ú__name__Ú
__module__Ú__qualname__Ú__doc__rW   ÚstructÚStructr9   ÚsizeÚAssertionErrorr1   r<   ra   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‡ fdd„Z	dd„ Z
d	d
„ Zd1dd„Zd2dd„Zg fdd„Zdd„ Zdd„ Zdd„ Zd3dd„Zdd„ Zg fdd„Zd4dd„Zd5dd „Zd6d!d"„Zd#d$„ Zd7d%d&„Zd8d'd(„Zd9d)d*„Zd+d,„ Zd-d.„ Zd:d/d0„Z‡  ZS );ÚFuseOperationsz(Export archive as a FUSE filesystem
    FNr   c                sÎ   t ƒ jƒ  || _|| _|| _|| _|| _i | _tt	dd„ d�| _
d| _i | _ttƒ| _tjƒ | _tjƒ | _d | _i | _t|ƒ| _ttjjdtjƒ p”dƒƒ}tjd|ƒ t|dd„ d�| _tt	d	d„ d�| _ d S )
Nc             S   s   d S )Nr   )r"   r   r   r   r#   ï   s    z)FuseOperations.__init__.<locals>.<lambda>)r$   r%   r   ZBORG_MOUNT_DATA_CACHE_ENTRIESr   z$mount data cache capacity: %d chunksc             S   s   d S )Nr   )r"   r   r   r   r#   þ   s    c             S   s   d S )Nr   )r"   r   r   r   r#   ÿ   s    )!Úsuperr1   Úrepository_uncachedr&   ÚargsÚmanifestr^   Úitemsr   ÚFILESÚ_inode_cacheÚ_inode_countÚparentr   ÚdictÚcontentsÚosÚgetuidÚdefault_uidÚgetgidÚdefault_gidÚdefault_dirÚpending_archivesr   ÚcacherB   Úenvironr<   Ú	cpu_countÚloggerÚdebugÚ
data_cacheÚ	_last_pos)r0   r^   Z
repositoryrn   rm   r&   Zdata_cache_capacity)Ú	__class__r   r   r1   â   s(    




zFuseOperations.__init__c             C   s®   | j dd� | jjjr6| jr$tdƒ‚| j| jjjƒ nttƒ | _xj| j	j
j| jƒD ]V}| jrh| j|jƒ qP| j dt|jjƒ d ƒd�}|| jd tj|jƒ< |j| j|< qPW d S )Nr   )rs   z_for versions view, do not specify a single archive, but always give the repository as location.g    eÍÍA)rs   Úmtime)Ú_create_dirrm   ÚlocationÚarchiveÚversionsr   Úprocess_archiver	   Úversions_indexrn   ZarchivesZlist_consideringÚnamerB   ZtsZ	timestampru   rv   Úfsencoder|   )r0   rˆ   Zarchive_inoder   r   r   Ú_create_filesystem  s    
z!FuseOperations._create_filesystemc          	   C   sÚ   t jd| jt| jƒttj| jƒt| jƒtj| jƒ  ƒƒ t jdt| jƒƒ t jd| j	j
| j	j | j	j
| j	jttj| j	jƒƒttj| j	jjƒ ƒjƒƒ t jdt| jjƒ ƒ| jjttdd„ | jjƒ D ƒƒƒƒ | jjƒ  d S )Nz$fuse: %d synth inodes, %d edges (%s)zfuse: %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, %sc             s   s   | ]\}}t |ƒV  qd S )N)rO   )Ú.0r^   rJ   r   r   r   ú	<genexpr>   s    z2FuseOperations.sig_info_handler.<locals>.<genexpr>)r€   r�   rr   rO   rs   r   ÚsysÚ	getsizeofr|   r}   r/   r.   r(   rv   Ústatr,   ÚfilenoÚst_sizer‚   ro   Z	_capacityÚsumr&   Zlog_instrumentation)r0   Zsig_noÚstackr   r   r   Úsig_info_handler  s    (zFuseOperations.sig_info_handlerc             C   sª  ddd„}dddg}|r(|j |jdƒƒ ||dd	d
tƒ}|rL||dd	d
tƒ ||dd	d
tƒ| _||dd	d
tƒ| _||dddtƒ| _||dddtƒ| _||dddtdd�| _| jdk	rº| jn| j	}| jdk	rÐ| jn| j
}d| j @ }	t|	ttjƒ d ƒ||d�| _| jƒ  tj| ||ƒ |�sBtƒ \}
}t| jtƒ�sB| jj|
|ƒ d
}zRtd| jƒ�$ td| jƒ� tƒ }W dQ R X W dQ R X |dk�p”|tk�o”|}W dtj|ƒ X dS )z6Mount filesystem on *mountpoint* with *mount_options*.r   c       
      S   s  t | tƒst‚� xðt| ƒD ]à\}}||kr8| j|ƒ |S |j|d ƒr| j|ƒ |jddƒd }|tkr”|jƒ }	|	dkr|dS |	dkrˆdS t	d| ƒ‚|t
krÌyt
||d�S  t	k
rÊ   t	d| ƒd ‚Y nX y||ƒS  t	k
� rø   t	d| ƒd ‚Y qX qW |S d S )Nú=r   ÚyÚyesÚtrueÚ1TÚnÚnoÚfalseÚ0Fzunsupported value in option: %s)Úbase)rš   r›   rœ   r�   )rž   rŸ   r    r¡   )Ú
isinstanceÚlistri   Ú	enumerateÚpopÚ
startswithÚsplitÚboolÚlowerr7   rB   )
Úoptionsr^   ZpresentZnot_presentZwanted_typeÚint_baseÚidxZoptionÚvalueÚvr   r   r   Ú
pop_option&  s2    

z(FuseOperations.mount.<locals>.pop_optionzfsname=borgfsZroZdefault_permissionsú,Úignore_permissionsTFÚallow_damaged_filesr‰   ÚuidNÚgidÚumaskrT   )r¬   iíA  g    eÍÍA)Úmoder…   r´   rµ   ÚSIGUSR1ZSIGINFO)r   )Úextendr¨   r©   r³   r‰   rB   Ú
uid_forcedÚ
gid_forcedr¶   rx   rz   r   Útimer{   rŽ   r   Zinitr
   r£   rl   r   Zmigrate_lockr   r˜   r   r   Úclose)r0   Z
mountpointZmount_optionsZ
foregroundr°   r«   r²   Zdir_uidZdir_gidZdir_modeZold_idZnew_idZumountÚsignalr   r   r   Úmount#  s:    
!

zFuseOperations.mountc             C   sN   | j ƒ }|dk	r4tf | jjƒ Ž| j|< || j| _n| j| j|< || j|< |S )zCreate directory
        N)Úallocate_inoder   r{   Zas_dictro   r…   rs   )r0   rs   r…   Zinor   r   r   r†   p  s    
zFuseOperations._create_dirc                sŒ  i | _ tjƒ }t| j| j| j|| jjd�}| jj	}t
j| jj| jjƒ}|jƒ  pR|‰ˆr\i nd‰ ‡ ‡fdd„}t
j|||ƒ}xî| jj|jj|| jjd�D ]Ð\}	}
|rÄtjj|
jjtjƒ|d… ƒ|
_tj|
jƒ}tj|
jƒ}|�ry| j||ƒ}W n tk
�r   Y nX |
| j|< q˜||jdƒ }d}x"|dd	… D ]}| j||ƒ}�q6W | j |d
 |
||||	ˆ |ƒ q˜W tjƒ | }t!j"d||j#ƒ dS )z9Build FUSE inode hierarchy from archive metadata
        )r]   Nc                sD   ˆr@| r@t | jƒr@| jddƒr@d| kr@| jdƒd fˆ | jdƒ< d S )NZhardlink_masterTÚsourcer-   Úpath)r   r·   r<   )r_   Zmatched)Úhardlink_mastersÚpartial_extractr   r   Úpeek_and_store_hardlink_mastersˆ  s    zGFuseOperations.process_archive.<locals>.peek_and_store_hardlink_masters)r\   r]   ó   /r   z8fuse: process_archive completed in %.1f s for archive %séÿÿÿÿrÇ   )$Úfile_versionsr¼   Zperf_counterr   rl   r^   rn   rm   r]   Ústrip_componentsr   Zbuild_matcherZpatternsÚpathsÚemptyZbuild_filterr}   ra   Zmetadataro   rv   ÚsepÚjoinrÂ   r¨   r�   r“   ÚS_ISDIRr·   Ú_find_inodeÚKeyErrorÚprocess_innerÚprocess_leafr€   r�   rŒ   )r0   Úarchive_namer    Zt0rˆ   rÉ   ZmatcherrÅ   r\   Ú
item_inoder_   rÂ   Úis_dirrG   Úsegmentsrs   ÚsegmentZdurationr   )rÃ   rÄ   r   rŠ   |  s>     
zFuseOperations.process_archivec	                s   |j }	|` |pi }‡ fdd„}
ddd„}d|ko8t|jƒ�r,tjj|jjtjƒ|d … ƒ}|j|jd |fƒ\}}|røtj	|ƒ}ˆ j
rœˆ j| }|||dd�}yˆ j||ƒ}W n" tk
rÎ   tjd	|	|ƒ d S X ˆ j|ƒ}|jd
dƒd |_|ˆ j|< n2|d k	�r0||_|}|ˆ j|< |�r0d |	f||j< n|}ˆ j
�r~| �r~ˆ j||ƒ}tj	|	ƒ}|
||ƒ}|d k	�r~|||ƒ}|ˆ j|< |ˆ j|< |�rœ|ˆ j| |< d S )Nc                sf   d| krbt |ƒ}ˆ jj|dƒ\}}dd„ | jD ƒ}t dj|ƒƒ}||kr^|d7 }||fˆ j|< |S d S )Nr-   r   c             S   s   g | ]\}}}|‘qS r   r   )r�   rI   r"   r   r   r   ú
<listcomp>²  s    zEFuseOperations.process_leaf.<locals>.file_version.<locals>.<listcomp>rN   r   )r   N)r   r‹   r<   r-   rÍ   )r_   rÂ   Zfile_idZcurrent_versionZprevious_idZ	chunk_idsZcontents_id)r0   r   r   Úfile_version­  s    z1FuseOperations.process_leaf.<locals>.file_versionFc             S   sJ   |r | j ddƒ}| d|d  7 } tjj| ƒ\} }tjd| ƒ}| | | S )NrÆ   r   z.%05drÇ   )Úrsplitrv   rÂ   Úsplitextr�   )rŒ   ÚversionÚadd_dirZ
path_fnameZextZversion_encr   r   r   Úmake_versioned_name»  s    z8FuseOperations.process_leaf.<locals>.make_versioned_namerÁ   T)rÝ   z#Skipping broken hard link: %s -> %sÚnlinkr   )F)rÂ   r   r·   rv   rÌ   rÍ   rÁ   r¨   r<   r�   r‰   rÈ   rÏ   rÐ   r€   ÚwarningÚget_itemrß   ro   r-   rÑ   rs   ru   )r0   rŒ   r_   rs   r    rÕ   rÔ   rÃ   Zstripped_componentsrÂ   rÙ   rÞ   rÁ   r-   Zlink_targetrÜ   rG   Zenc_pathr   )r0   r   rÒ   ¨  sL    












zFuseOperations.process_leafc             C   s6   | j | }||kr|| }n| j|ƒ}|r2|||< |S )N)ru   r†   )r0   rŒ   Úparent_inodeÚdirrG   r   r   r   rÑ   ï  s    


zFuseOperations.process_innerc             C   s   |  j d7  _ | j S )Nr   )rr   )r0   r   r   r   rÀ   ù  s    zFuseOperations.allocate_inodec             C   sL   t jƒ }d|_d|_d|_d|_d|_d|_d|_d|_	t
|dƒrHd|_|S )Ni   r   Ú	f_namemaxéÿ   )r   ZStatvfsDataÚf_bsizeÚf_frsizeÚf_blocksÚf_bfreeÚf_bavailÚf_filesÚf_ffreeÚf_favailÚhasattrrä   )r0   ÚctxZstat_r   r   r   Ústatfsý  s    
zFuseOperations.statfsc             C   sR   | j j|ƒ}|d k	r|S y
| j| S  tk
rL   | jj|ƒ}|| j |< |S X d S )N)rq   r<   ro   rÐ   r}   )r0   rG   r_   r   r   r   rá     s    

zFuseOperations.get_itemc             C   s2   ||j dƒ }d}x|D ]}| j| | }qW |S )NrÆ   r   )r¨   ru   )r0   rÂ   r    rÖ   rG   r×   r   r   r   rÏ     s
    
zFuseOperations._find_inodec             C   s\  | j |ƒ}tjƒ }||_d|_d|_d|_|j| j @ |_	|j
ddƒ|_| jd k	rX| jn|jdkrh|jn| j|_| jd k	r€| jn|jdkr�|jn| j|_|j
ddƒ|_|jƒ |_d|_|j|j d |j |_|j}t�r||_|j
d|ƒ|_|j
d|ƒ|_t�rX|j
d	|ƒ|_nF|d
 |_ |j
d|ƒd
 |_!|j
d|ƒd
 |_"t#�rX|j
d	|ƒd
 |_$|S )Nr   i,  rß   r   Zrdevi   ZatimeZctimeZ	birthtimeg    eÍÍA)%rá   r   ÚEntryAttributesÚst_inoZ
generationZentry_timeoutZattr_timeoutr·   r¶   Úst_moder<   Úst_nlinkrº   r´   rx   Úst_uidr»   rµ   rz   Úst_gidÚst_rdevZget_sizer•   Ú
st_blksizeÚ	st_blocksr…   Úhave_fuse_xtime_nsr   Úst_atime_nsÚst_ctime_nsÚhave_fuse_birthtime_nsr   Úst_mtimeÚst_atimeÚst_ctimeÚhave_fuse_birthtimer   )r0   rG   rï   r_   ÚentryZmtime_nsr   r   r   Úgetattr  s6    
((

zFuseOperations.getattrc             C   s   | j |ƒ}|jdi ƒjƒ S )NÚxattrs)rá   r<   Úkeys)r0   rG   rï   r_   r   r   r   Ú	listxattr>  s    
zFuseOperations.listxattrc             C   sF   | j |ƒ}y|jdi ƒ| pdS  tk
r@   tjtjƒd ‚Y nX d S )Nr  rN   )rá   r<   rÐ   r   Ú	FUSEErrorZENOATTR)r0   rG   rŒ   rï   r_   r   r   r   ÚgetxattrB  s
    
zFuseOperations.getxattrc             C   s*   | j j|d ƒ}|r&| j|tj|ƒgƒ d S )N)r|   r¦   rŠ   rv   r�   )r0   rG   rÓ   r   r   r   Ú_load_pending_archiveI  s    z$FuseOperations._load_pending_archivec             C   sV   | j |ƒ |dkr|}n4|dkr,| j| }n | j| j|ƒ}|sLtjtjƒ‚| j|ƒS )Nó   .s   ..)	r	  rs   ru   r<   r   r  ÚerrnoÚENOENTr  )r0   râ   rŒ   rï   rG   r   r   r   ÚlookupO  s    
zFuseOperations.lookupc             C   s2   | j s.| j|ƒ}d|kr.tjdƒ tjtjƒ‚|S )NZchunks_healthyzzFile has damaged (all-zero) chunks. Try running borg check --repair. Mount with allow_damaged_files to read damaged files.)r³   rá   r€   rà   r   r  r  ZEIO)r0   rG   Úflagsrï   r_   r   r   r   Úopen[  s    

zFuseOperations.openc             C   s   | j |ƒ |S )N)r	  )r0   rG   rï   r   r   r   Úopendirg  s    
zFuseOperations.opendirc             C   sT  g }| j |ƒ}| jj|dƒ\}}||kr0d\}}||8 }|j}�xt|t|ƒƒD ]ö}	||	 \}
}}||k r„||8 }||7 }|d7 }qPt||| ƒ}|
| jkrÀ| j|
 }|| t|ƒkrð| j|
= n0| jj	|
| j
j|
ƒƒ}|| t|ƒk rð|| j|
< |j|||| … ƒ d}||8 }|sP|| jk�r6| jj|||fƒ n||f| j|< P qPW dj|ƒS )Nr   r   rN   )r   r   )r   r   )rá   rƒ   r<   r-   ÚrangerO   Úminr‚   r^   Zdecryptrl   ÚappendZupdrÍ   )r0   Úfhr*   rh   Úpartsr_   Zchunk_norH   r-   r­   ÚidÚsrK   rž   rL   r   r   r   Úreadk  s>    




zFuseOperations.readc             c   sh   d|fd| j | fg}|j| j| jƒ ƒ x8t||d … |ƒD ]"\}\}}|| j|ƒ|d fV  q>W d S )Nr
  s   ..r   )rs   r¹   ru   ro   r¥   r  )r0   r  ZoffZentriesÚirŒ   rG   r   r   r   Úreaddir–  s     zFuseOperations.readdirc             C   s   | j |ƒ}tj|jƒS )N)rá   rv   r�   rÁ   )r0   rG   rï   r_   r   r   r   Úreadlinkœ  s    
zFuseOperations.readlink)F)N)N)N)N)N)N)N)N)N) rb   rc   rd   re   r³   r‰   rº   r»   r¶   r1   rŽ   r˜   r¿   r†   rŠ   rÒ   rÑ   rÀ   rð   rá   rÏ   r  r  r  r	  r  r  r  r  r  r  Ú__classcell__r   r   )r„   r   rj   Ø   s8   
M
,G







+rj   ).r  rE   rv   r“   rf   r‘   r+   r¼   Úcollectionsr   r¾   r   r   r€   r   Zcrypto.low_levelr   Zarchiverr   rˆ   r   Z	hashindexr	   Zhelpersr
   r   r   r   r   r   r_   r   Zlrucacher   Zremoter   rî   rñ   rú   r  rý   r   rp   r   Z
Operationsrj   r   r   r   r   Ú<module>   s:    +