
    Hmd                     `   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Zd dl	Z	d dl
Z
d dlmZmZmZmZmZmZmZmZmZmZmZmZ d dlZd dlmZ d dlZd dlZd dlZd dlmZmZ d dlm Z  d dl!Z!d dl!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9 d dl:m;Z; d dl<m=Z=m>Z>m?Z?m@Z@mAZAmBZB  eCed	d
          ZDdaEdaF G d deG          ZH G d deG          ZI G d deI          ZJ G d deI          ZK G d deH          ZL G d deG          ZM G d deG          ZNdS )    N)EEXISTENOENTENODATAENOTDIRELOOPEACCESEISDIR	ENOTEMPTYESTALEEINVALEBUSYEPERM)rconf)RepceServerRepceClientgprimary_builder)GsyncdErrorselect
privilegedfuncodeentry2pbgauxpfx
errno_wraplstatNoStimeAvailablePartialHistoryAvailableChangelogExceptionChangelogHistoryNotAvailableget_changelog_log_levelget_rsync_versionGX_GFID_CANONICAL_LENgf_mount_readylfPopensupXattrmatching_disk_gfidget_gfid_from_mntunshare_propagation_supportedget_slv_dir_path)GeorepStatus)pipestr_to_bytearrayentry_pack_regentry_pack_reg_statentry_pack_mkdirentry_pack_symlinkENOTSUP
EOPNOTSUPPc                      e Zd ZdZ e            rdpdZedz   ZdZdZeez   Z	dZ
dZd	Zed
             Zed             Zed             Zd Zeed                         Zeed                         Zeed                         Zeed                         Zeed(d                        Zeed                         Zeed                         Zeed                         Zeed                         Zeed                         Zeed                         Zeed                         Zed)d            Zeed                         Zeed                         Z eed                         Z!eed                          Z"ed!             Z#ed"             Z$eed#                         Z%e&d$             Z'd%Z(ed&             Z)e&d'             Z*dS )*Serverzsingleton implemening those filesystem access primitives
       which are needed for geo-replication functionality

    (Singleton in the sense it's a class which has only static
    and classmethods and is used directly, without instantiation.)
    trustedsystem
.glusterfsz!BBBBBBBBBBBBBBBBBBBIIIztrusted.gfidz!BBBBBBBBBBBBBBBB c                      dt           |dz   fz  S )Nz!II%dsI%dsIII   r"   clsls     A/usr/lib/x86_64-linux-gnu/glusterfs/python/syncdaemon/resource.py
_fmt_mknodzServer._fmt_mknodL   s    "7Q!???    c                      dt           |dz   fz  S )Nz!II%dsI%dsIIr=   r>   r?   s     rB   
_fmt_mkdirzServer._fmt_mkdirP   s    !6A >>>rD   c                 (    dt           |dz   |dz   fz  S )Nz!II%dsI%ds%dsr=   r>   )r@   l1l2s      rB   _fmt_symlinkzServer._fmt_symlinkT   s    "7aa!HHHrD   c                      t                     }t          |j                                      d           fd}|S )zdecorator method that checks
        the path argument of the decorated
        functions to make sure it does not
        point out of the managed tree
        pathc                      |          }|                     d          }|d         dk    sd|v rt          d          t          |           } t          j                            | d         j        |          | <    |  S )N/r   z..zunsafe path)split
ValueErrorlistosrL   join
local_path)argsrL   psfpis      rB   ffzServer._pathguard.<locals>.ffb   st    8DCBAw#~~ ///::Dw||DG$6==DH1d8OrD   )r   rQ   co_varnamesindex)rW   fcrY   rX   s   `  @rB   
_pathguardzServer._pathguardX   sS     QZZ".!!''//	 	 	 	 	 	 	rD   c                     t          j        t          j        |          j                  s,t          t          t          j        t                              t          j        |          S )zdirectory entries in an array)	statS_ISDIRrR   r   st_modeOSErrorr   strerrorlistdirr@   rL   s     rB   entrieszServer.entriesl   sK    
 |BHTNN233 	9'2;w#7#7888z$rD   c                     	 t          j        |          S # t          t          f$ r4 t	          j                    d         }|j        t          k    r	|j        cY S  w xY w)Nr=   )rR   r   IOErrorrb   sysexc_infoerrnor   r@   rL   exs      rB   r   zServer.lstatu   s`    	8D>>!! 	 	 	"Bx6!!x	s    AAAc                     	 t          j        |d          dk     S # t          t          f$ r3 t	          j                    d         }|j        t          t          fv rY dS  w xY w)Nztrusted.glusterfs.dht.linktor;   r=   F)	r'   lgetxattr_bufrh   rb   ri   rj   rk   r   r   rl   s      rB   linkto_checkzServer.linkto_check   s    		#D$BD DGIJK K ! 	 	 	"BxFG,,,uu	s    ?A A c           
         t          t          j        || j        dgt          gt
          t          g          }|t          k    r|S t          |          }t          j	        dd
                    d t          j        | j        |          D                                 }d
                    |                                          S )N   (.{8})(.{4})(.{4})(.{4})(.{12})r;   c                     g | ]}d |z  S z%02x .0xs     rB   
<listcomp>zServer.gfid.<locals>.<listcomp>   s    III!IIIrD   -)r   r'   	lgetxattr
GFID_XATTRr   r   r   r.   rematchrS   structunpackGFID_FMTSTRgroups)r@   rL   bufms       rB   gfidzServer.gfid   s     4*D FG#46 6&==J"3''C:BGGIIV]3?C%H%HIII=K =K L LA88AHHJJ'''rD   Nc                    |du }|s	 	 t          j        |           dS # t          $ rB t          j                    d         }|j        t          k    rt          j        |          }n Y nw xY wn# t          $ r t          j                    d         }|j        t          t          t          fv rT	 t          j        |           Y dS # t          $ r/ t          j                    d         }|j        t          k    rY Y dS  w xY w w xY w|D ]5}|                     t           j                            ||                     6|rt          j        |           dS dS )a  force-delete subtrees

        If @entries is not specified, delete
        the whole subtree under @path (including
        @path).

        Otherwise, @entries should be a
        a sequence of children of @path, and
        the effect is identical with a joint
        @entries-less purge on them, ie.

        for e in entries:
            cls.purge(os.path.join(path, e))
        Nr=   )rR   unlinkrb   ri   rj   rk   r	   rd   r   r   r   purgerL   rS   rmdir)r@   rL   rf   me_alsorm   es         rB   r   zServer.purge   s   " T/ 	IdOOOF   *Bx6))"$*T"2"2        \^^A&8777	$"    \^^A.8v--"FFF	   	- 	-AIIbgll4++,,,, 	HTNNNNN	 	s@    A	A+(A/ *A++A/ />D.C3C>8D<C>>Dc                     	  ||           dS # t           $ rM t          j                    d         }|j        t          k    r"|                     |            ||          cY S  w xY w)zpath creation backend routiner=   N)rb   ri   rj   rk   r   r   )r@   rL   ctorrm   s       rB   _createzServer._create   sv    	DJJJJJ 	 	 	"Bx6!!		$tDzz!!!	s    AA&$A&c                 F    |                      |t          j                   d S N)r   rR   mkdirre   s     rB   r   zServer.mkdir   s      	D"(#####rD   c                 :    |                      |fd           d S )Nc                 .    t          j        |           S r   )rR   symlink)plnks    rB   <lambda>z Server.symlink.<locals>.<lambda>   s    BJsA$6$6 rD   )r   )r@   r   rL   s    ` rB   r   zServer.symlink   s)     	D666677777rD   c                 F   	 t          j        |d                    | j        |dg          d          }t	          |          }t          j        d|          S # t          $ r? t          j	                    d         }|j
        t          t          t          fv r	|j
        cY S  w xY w)query xtime extended attribute

        Return xtime of @path for @uuid as a pair of integers.
        "Normal" errors due to non-existent @path or extended attribute
        are tolerated and errno is returned in such a case.
        .xtime   !IIr=   r'   r|   rS   	GX_NSPACEr.   r   r   rb   ri   rj   rk   r   r   r   r@   rL   uuidvalrm   s        rB   r   zServer.xtime       	/$"%((CM4+I"J"J"#% %C #3''C=,,, 	 	 	"BxFGW555x	   AA AB B c                 F   	 t          j        |d                    | j        |dg          d          }t	          |          }t          j        d|          S # t          $ r? t          j	                    d         }|j
        t          t          t          fv r	|j
        cY S  w xY wr   r   stimer   r   r=   r   r   s        rB   	stime_mntzServer.stime_mnt   r   r   c                 F   	 t          j        |d                    | j        |dg          d          }t	          |          }t          j        d|          S # t          $ r? t          j	                    d         }|j
        t          t          t          fv r	|j
        cY S  w xY wr   r   r   s        rB   r   zServer.stime  r   r   c                 F   	 t          j        |d                    | j        |dg          d          }t	          |          }t          j        d|          S # t          $ r? t          j	                    d         }|j
        t          t          t          fv r	|j
        cY S  w xY w)au  
        entry_stime xattr to reduce the number of retry of Entry changes when
        Geo-rep worker crashes and restarts. entry_stime is updated after
        processing every changelog file. On failure and restart, worker only
        have to reprocess the last changelog for Entry ops.
        Xattr Key: <PFX>.<PRIMARYVOL_UUID>.<SECONDARYVOL_UUID>.entry_stime
        r   entry_stimer   r   r=   r   r   s        rB   r   zServer.entry_stime)  s    	/$"%((CM4,9,; #< #<"#% %C #3''C=,,, 	 	 	"BxFGW555x	r   r   c                     	 t          j        |d                    | j        dg                    }|d d                             d          S # t
          $ r  w xY w)Nr   z	node-uuid )r'   ro   rS   r   rO   rb   )r@   rL   uuid_ls      rB   	node_uuidzServer.node_uuidA  sk    	(chh{;<<> >F#2#;$$S))) 	 	 		s   AA Ac           	          t          t          j        |d                    | j        |dg          t          j        dg|R  gt          gt          t          g           dS )%set @mark as stime for @uuid on @pathr   r   r   N
r   r'   	lsetxattrrS   r   r   packr   r   r   r@   rL   r   marks       rB   	set_stimezServer.set_stimeJ  h     	5?HHcmT7;<<K----/ 8F#	% 	% 	% 	% 	%rD   c           	          t          t          j        |d                    | j        |dg          t          j        dg|R  gt          gt          t          g           dS )r   r   r   r   Nr   r   s       rB   set_entry_stimezServer.set_entry_stimeU  sh     	5?HHcmT=ABBK----/ 8F#	% 	% 	% 	% 	%rD   c           	          t          t          j        |d                    | j        |dg          t          j        dg|R  gt          gt          t          g           dS )z%set @mark as xtime for @uuid on @pathr   r   r   Nr   r   s       rB   	set_xtimezServer.set_xtime`  r   rD   c                     t          j        |d                    | j        |dg          t	          j        dg|R             dS )z
        set @mark as xtime for @uuid on @path
        the difference b/w this and set_xtime() being
        set_xtime() being overloaded to set the xtime
        on the brick (this method sets xtime on the
        remote secondary)
        r   r   r   N)r'   r   rS   r   r   r   r   s       rB   set_xtime_remotezServer.set_xtime_remotek  sQ     	#((CM49::K%%%%	' 	' 	' 	' 	'rD   c                    t                      t          j        dt          |          z             t          j        j        }fd}d.fd	g fdfd}|D 	]d }d         }d         }d	         }d
}	d
}
d         r*                    di           r2d         d         }	d         d         }
d
d         d<   d
d         d<   t          |          \  }}|dv r$ |||||	|
          }t          |t                    r|t          k    r|dk    rt          ||t          j                            ||          gg t          t           t"          g          }t          |t                    s t          j        d|d|d|d           nt          j        t'          d|||t          j        |                               nt          j        t'          d|||t          j        |                               n|dv rt          j                            |          }t+          |          }t          |t                    r(t-          | ||d         d         d                   }n-|dv r>t          t          j        ||gt0          t2          gt           g          } ||	|
           n|dk    rNd	         }t          j                            |          }t+          |          }t          |t                    r(t5          | ||d         d         d                   }nnt          t+          |          t                    st7          ||          st          j        t'          d|t          |                               t;          t<          t>          |          }| t0          |	|
           |C||k    r=i }d|d<   d|d <   d|d!<   d|d"<   ||d#<   ||d$<                        t2          |f           n|d%k    rt          j                            |          }t+          |          }t          |t                    rt          |          \  }}tC          j"        d         d                   rtG          | ||d                   }ntC          j$        d         d                   rtK          | ||d&         d                   }nt          t          j        ||gt0          t2          gt           g          } ||	|
           n||d'k    rrd	         }t+          |          }t          |t                    r!tK          | ||d&         d                   }n)t7          ||          s t2          |	|
           n|d(k    rd)         }t7          ||          sd         rttC          j&        d         d                   sStC          j$        d         d                   rd&         {t+          |          }t          |t                    r3t          |          \  }}tK          | ||d&         d                   }n;t7          ||          s t2          |	|
d           nt          j                            |          }t+          |          }t          |t                    r,t          |          \  }}tG          | ||d                   }nt          t          j        ||gt0          t2          gt           g          } ||	|
           net+          |          }t+          |          }t          |t                    r |||||	|
           n!|j'        |j'        k    r	 t          t          j(        |gt0          t           gtR          g           n# tT          $ rj+        tX          k    r~	 t          t          j-        |gt0          t           gtR          g           nN# tT          $ r@j+        t          k    r%t          j.        t'          d*||+                     n Y d n	d ww xY w Y d nBd ww xY wt7          ||          s|d,k    r t2          |	|
d           n |||||	|
           |rt          t^          j0        |d-|gt2          t0          t           gt           tb          tR          g          } ||	|
           |	d
k    s|
d
k    r_t          j                            |          }t          t          j2        ||	|
gt0          gt           tb          g          } ||	|
           	
S )/Nzentries: %sc                 6   t          t          |          t                    s@t          t          t          j                            |                    t                    rd S t          ||          s |t          ||           d S | dk    r>t          t          j	        |gt          t          gt          g          }|t          k    r|S d S | dk    rBt          t          j        |gt          t          t          gt          g          }|t          k    r|S d S d S )NUNLINKRMDIR)
isinstancer   intrR   rL   rS   r(   r   r   r   r   r   r   r	   r   r
   )	opentryr   r   uidgidercollect_failurepfxs	          rB   entry_purgez%Server.entry_ops.<locals>.entry_purge  s    %,,,, %S$ 7 788#>>%dE22 63444X~~	E7VV4DugNN <<I  < w5'FF4=4?AFI I??I	  #?rD   Fc                    i }d|d<   d|d<   ||d<   d|d<   d |d<   d |d<   |dS |                      di           r|| d         d	<   || d         d
<   |t          t          fv r|r	| d         }n| d         }t          |          }t	          |t
                    r| d         |k    rd|d<   t          |          }t	          |t                    sF|r?t          j	        |j
                  r&d|d<   t          t          t          |          }	|	|d<   nd|d<   ||d<   
                    | ||f           ndS 
                    | ||f           dS )NFgfid_mismatchname_mismatchdstsecondary_isdirsecondary_namesecondary_gfidr_   r   r   entry1r   r   T)getr   r   r)   r   strr   r   r_   r`   ra   r+   slv_host
slv_volumeappend)r   cmd_retr   r   r   slv_entry_infoen	disk_gfidstdir_namefailuress             rB   r   z)Server.entry_ops.<locals>.collect_failure  s   N.3N?+.3N?+$'N5!05N,-/3N+,/3N+, uuuVR   '#&&	% #&&	% 66*** $8BB7B-b11	i-- !V9	))6:N?3rB%b#.. F F$,rz":": F@DN+<='7*8A(C (CH?GN+;<<@EN+<=7@N#34OOQ$@AAAA 5G^ <===4rD   c                 H   t          | |          sdS g }t          t          j        |gt          gt
          t          g          }t          |t                    rdS |D ]}t          j	        
                    ||          }t          | |          s dS t          t          j        |gt          t
          t          gt          g          }|t          k    r | ||           t          | |          sdS t          t          j        |gt          t
          gt          g           dS )a  disk_gfid check added for original path for which
            recursive_delete is called. This disk gfid check executed
            before every Unlink/Rmdir. If disk gfid is not matching
            with GFID from Changelog, that means other worker
            deleted the directory. Even if the subdir/file present,
            it belongs to different parent. Exit without performing
            further deletes.
            N)r(   r   rR   rd   r   r   r3   r   r   rL   rS   remover	   r   r   )r   r   rL   namesnamefullnamer   recursive_rmdirs          rB   r   z)Server.entry_ops.<locals>.recursive_rmdir  s    &dE22 ErzD6F8fg=NOOE%%%  ; ;7<<d33)$66 FF	H:8>8@BGJ J <<#OD%:::%dE22 rx$&&)9E7CCCCCrD   c           
      @   t          | |          sHt          j        t          d|| t	          |          |                      t
          ||           d S t          t          j        ||gt          t
          gt          t          g          } |||           d S )Nz=RENAME ignored: source entry does not match with on-disk gfid)sourcer   r   target)r(   loggingerrorr$   r)   r   r   rR   renamer   r   r   )r   r   r   r   r   r   r   r   s         rB   "rename_with_disk_gfid_confirmationz<Server.entry_ops.<locals>.rename_with_disk_gfid_confirmation  s    %dE22 b "5(-&*+<U+C+C(*, , , - - -  63444 "'"(&!1FE?D DG OAwS11111rD   r   r   r   r   
skip_entryr_   r   r   )r   r   r   zRemoved z => rN   z recursivelyzRecursive remove failed)r   pgfidbnamer   zFailed to remove)CREATEMKNODmode)r   MKDIRzSpecial case: rename on mkdir)r   r   r   Tr   r   r   r   secondary_entryLINKlinkSYMLINKRENAMEr   z<Directory Rename failed. Both Old and New directories exists)oldnewr=   zglusterfs.gfid.newfileF)3r   r   debugreprr   rU   primary_dist_countr   r   r   r   r
   r   rR   rL   rS   r   r   warnr$   rc   r   r/   r   r   r   r1   r(   infor+   r   r   r   r_   S_ISREGr0   S_ISLNKr2   r`   st_inor   r   rb   rk   r	   r   r   r'   r   r   lchown)r@   rf   
dist_countr   r   blobr   r   r   r   r   pgr   r   er1slinkr   r   r   	src_entryr   st1rL   r   r   r   r   r   s                          @@@@@rB   	entry_opszServer.entry_opsy  s
   iimd7mm3444Z2
	 	 	 	 	 	<+	 +	 +	 +	 +	 +	Z 	D 	D 	D 	D 	D@	2 	2 	2 	2 	2 	2   P	: P	:AD4BV9DgJECC  uuVR   % i&i&#$&	% #$&	% "5//KR((( ![UD!S#>>b#&& @Y2==(*.*,',,r5*A*A*C)+i-IK K  *#s33 E#MM+/44UUU+< = = = = $L,E15242724+c2B2B	*D *D *D E E E E  R(:-1.0.3.0k"oo	&? &? &? @ @ @
 ***S$//5\\b#&& 
:)#tU*+F)QuXqxI IDD
 9__(*/*0&)9F8E EG $OAwS999wwZS$//5\\b#&& E+Cu,-fIqx5K KDD rC00 E,T266E L$C)-T%[["B "B "B C C C 0:t L LI ('63<<< ,e1C1C)+:?7:>705u-<@'89;?'78<E'89 FN(CDDDvS$//5\\b#&& :"*5//KR|AfIf$566 =23eQvYOOai&788 =1#tUAfI23F) =  = )*/*0&)9F8E EG $OAwS9999ywZ5\\b#&& 9-c4&	./i9 9DD+D"55 9#OAvsC888xx[ *$66 CIy Fai6G)H)H F<&	&(9:: F
  !y4&+Bii#-c3#7#7 !O2:2,,KR+=c4>?i>?i,I ,IDD *<D")E)E !O$3OAvsC$N$N$N$&GLLd$;$;E!&uB)"c22 F.6rllU':3e;<V9(F (F +5RWubk5;V4Dvh+P +P /7C E E EuB))C!#s++ $I::4;>E E E E 9
22* *29ug,2F+;eW!F !F !F !F#* * * *#$7f#4#4%2(228eW4:F3CeW)N )N )N )N+2 	%2 	%2 	%2+,7i+?+?,3M02 4I 8=79	1; 1; 1;-< -< -< -< -2-< -< -< -< -<	%2 %*!*" "4D"!=!= 
I*q..+OAvsCFFFF ?>tUB?BCI I I :$U_&(*BD%I&,ff%=&,fe%<> >  7C555
 !88saxx7<<T22D(T34Dvh*0&)9; ;G#OAwS999sB   /_
a1a,)/`a,
a##6aa,a##a,,a1c                 x   t          j        dt          |          z             g }|D ]}|d         d         }|d         d         }|d         d         }|d         d         }|d         d         }|d         }	d	}
t          t          j        |	||gt          gt          t          g          }t          |t                    rt          j                            |	          }
|
st          t          j        |	|gt          t          t          gt          t          g          }t          |t                    r|                    ||d
f           t          t          j        |	||fgt          t          t          gt          t          g          }t          |t                    r|                    ||df           |S )NzMeta-entries: %sr_   r   r   r   atimemtimegoFchmodutime)r   r   r   r   rR   r  r   r   r   r   r   rL   islinkr  r   r   r   r  )r@   meta_entriesr   r   r   r   r   r  r  r  
is_symlinkr   s               rB   meta_opszServer.meta_ops  s   (4+=+==>>> '	; '	;AV9V$DF)E"CF)E"CfIg&EfIg&E4B  J RcNVH"(&!13 3G'3'' ++J 	;$RXDz&,fe%<vv>NP Pgs++ ;OOQ$9:::$RXUEN/C&,fe%<vv>NP Pgs++ ;OOQ$9:::rD   c                 0   |                     d          }|rt          j        |g|R   |                     d          }|r't          j        |t	          j        |                     |                     d          }|rt          j        ||           dS dS )zset file attributes

        @adct is a dict, where 'own', 'mode' and 'times'
        keys are looked for and values used to perform
        chown, chmod or utimes on @path.
        ownr   timesN)r   rR   r  r  r_   S_IMODEr  )r@   rL   adctr  r   r  s         rB   setattrzServer.setattr  s     hhuoo 	"Id!S!!!!xx 	/HT4<--...!! 	"HT5!!!!!	" 	"rD   c                  (    t          j                    S r   )rR   getpidrv   rD   rB   pidz
Server.pid  s    y{{rD   r   c                    |rd                     | j        d|d         g          }t          j        | j        g|d         t          d t          j        d|d                   D                       z   |d         fz   |d         d	d
         z   |d         fz   R  }t          j	        d||           | xj
        dz  c_
        | j
        S )a	  process keepalive messages.

        Return keep-alive counter (number of received keep-alive
        messages).

        Now the "keep-alive" message can also have a payload which is
        used to set a foreign volume-mark on the underlying file system.
        r   volume-markr   versionc              3   6   K   | ]}t          |d           V  dS )rr   N)r   rw   s     rB   	<genexpr>z$Server.keep_alive.<locals>.<genexpr>%  sF       &H &H*+ '*!Rjj &H &H &H &H &H &HrD   z(?:[\da-f]){2}retvalvolume_markr      timeoutr=   )rS   r   r   r   FRGN_FMTSTRtupler~   findallr'   r   last_keep_alive)r@   dctkeyr   s       rB   
keep_alivezServer.keep_alive  s     		+((CM=#f+FGGC+co 7 #I % &H &H/1z:J:=f+0G 0G&H &H &H !H !H!H "%X 0	!1 47}3Eac3J	!K
 %(	NN5	!57 7 7C OCc***q ""rD   c                      dS )zversion used in handshakeg      ?rv   rv   rD   rB   r%  zServer.version.  s	     srD   r   )r   )+__name__
__module____qualname____doc__r   GX_NSPACE_PFXr   
NTV_FMTSTRFRGN_XTRA_FMTr,  r}   r   rT   classmethodrC   rF   rJ   r]   rf   r   rp   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  staticmethodr"  r/  r2  r%  rv   rD   rB   r6   r6   7   s          Z\\/i;8M,I&JM},K  J KJ@ @ [@ ? ? [? I I [I  (     Z [    Z [ 
 
 Z [
 	( 	( Z [	( - - - Z [-^ 	 	 Z [	 $ $ Z [$ 8 8 Z [8   Z [*   Z [*   Z [*   Z [,    [ % % Z [% % % Z [% % % Z [% 
' 
' Z [
' T T [Tl
 + + [+Z " " Z [""   \ O# # [#,   \  rD   r6   c                   d    e Zd ZdZd Zed             Zd Zed             ZddZ	d Z
d	 Zd
 ZdS )Mounterz(Abstract base class for mounter backendsc                 0    || _         d | _        g | _        d S r   )paramsmntpt
umount_cmd)selfr@  s     rB   __init__zMounter.__init__8  s    
rD   c                     t          j        d          }t          j        j        dk    rt          j        d          }t
          j                            || j                  S )Nzgluster-command-dir	secondarysecondary-gluster-command-dir)	gconfr   r   rU   subcmdrR   rL   rS   glusterprog)r@   gluster_cmd_dirs     rB   get_glusterprogzMounter.get_glusterprog=  sJ    )$9:::++#i(GHHOw||OS_===rD   c                     t          |                     |          t          j        d          }|                                 |S )zperform lazy umountTstderruniversal_newlines)r%   make_umount_argv
subprocessPIPEwait)rC  dpos      rB   umount_lzMounter.umount_lD  s?    4((++JO&*, , ,
				rD   c                     t           r   NotImplementedErrorr@   rU  s     rB   rQ  zMounter.make_umount_argvK  s    !!rD   Nc                     t           r   rY  rC  labels     rB   make_mount_argvzMounter.make_mount_argvO  s    !!rD   c                     d S r   rv   )rC  as     rB   cleanup_mntptzMounter.cleanup_mntptR  s    rD   c                 .    |                                  d S r   )rT  rC  rV  s     rB   handle_mounterzMounter.handle_mounterU  s    
					rD   c                 	   t                      \  }}t          j                    }|rt          j        |           t          j        |t
          j        t
          j                   d|                     |          }| j	        r5| j	        dz   }|
                                }t          j        ||           t          |fi | j        }|                     |           |                                 t          j        d           s5| j	        dz   }|
                                }t          j        ||           d
                                }t          j        ||           t#          j        fd          }	|	                                 t(          j        t-          j        d          z   }
	 |	                                snAt3          j                    |
k    rt#          j        d	
           t3          j        d	           Vt          j        |           t#          j        |d          \  }}|rt          j        |          rt          j        |          pdt          j        |          rt          j         |          pdz
  }t          j!        tE          d                     tG          d|fz            nd}	 t          j$                     t          j        |           d}	 t          j%        |d	          }|&                                }|sn||z  }2|r)d}|d         dk    r|dd         }|sJ d}|d         dk    sJ |dd         }|sJ d}d}t(          j'        j(        dk    r$tS                      st-          j        d          sd}t(          j'        j(        dk    rt-          j        d          sd}|rl|s|rh| *                    |          }|                    d           |j+        dk    r|,                                 |j+        }t          j        d|z             |s|r| -                    |           n#  t          j.        d           d}Y nxY wt          j/        |           d}ta                      sB|dk     rt          j1        d           n'|d	z  }t3          j        d           ta                      Bt          j        d           dS )zinhibit a gluster filesystem

        Mount glusterfs over a temporary mountpoint,
        change into the mount, and lazy unmount the
        filesystem.
        N z"auxiliary glusterfs mount in placeMc                  ,    t          j                   S r   )rR   chdirrU  s   rB   r   z!Mounter.inhibit.<locals>.<lambda>y  s    ! rD   r   zconnection-timeoutTr=   )exvalr   z stale mount possibly left behind)rL   z4cleaning up temp mountpoint %s failed with status %dr;   Fr   workerzaccess-mountrF  secondary-access-mount)fail_on_errzLazy umount done: %szmount cleanup failure:   
   zSubvols are not upg?z"auxiliary glusterfs mount prepared)2r-   r%   forkrR   closefcntlF_SETFD
FD_CLOEXECr_  rA  encodewritemountkwre  terminate_geterrr   r   
syncdutilsThreadstartr   	starttimerH  r   is_alivetimefinalizesleepwaitpid	WIFEXITEDWEXITSTATUSWIFSIGNALEDWTERMSIGr  r$   r   setsidreaddecoderU   rI  r*   rW  
returncodeerrlogrb  	exception_exitr#   r   )rC  r^  mpimpomhmargvmnt_msgencoded_msgrV  ttlim_rvmntdatacmountedrA  umount_primaryumount_secondaryRETRIESrU  s                       @rB   inhibitzMounter.inhibitX  s    66SZ\\ X	HSMMMKU]E,<===A((//Ez +Jd(%nn..k***u----B###!!!M>??? +Jd(%nn..k*****,,KHS+&&&!)<)<)<)<===AGGIII?UY/C%D%DDDzz|| 9;;$&&'a0000
1 HSMMM&r1--EAr +l2&&=2>"+=+=BnR((<R[__ACR B%&( ( ( ) ) )! #:#$b'#* + + ++ B)	!QA

A qLG!  2#Gr{c))")#2#,&"&"2;$....#CRCLE MMM%*N',$z(H44<>> 5$y88 5 *.z(K77$y)ABB 8+/( FN F6F F!]]511+++>>>=A--IIKKK!#B&<u&DEEE% 2)9 2**5111!":;;;HRLLL  "" 	{{2333qLGJsOOO !"" 	 	:;;;;;s   FQ Q/r   )r4  r5  r6  r7  rD  r;  rL  rW  rQ  r_  rb  re  r  rv   rD   rB   r>  r>  4  s        22  
 > > [>   " " ["" " " "    l< l< l< l< l<rD   r>  c                   P    e Zd ZdZej        ddZdZed             Z	d	dZ
d	dZdS )
DirectMounterz8mounter backend which calls mount(8), umount(8) directlyTrN  	glusterfsc                     dd| gS )Numountz-lrv   rk  s    rB   rQ  zDirectMounter.make_umount_argv  s    $""rD   Nc                     t          j        d          | _        | j        t          _        |                                 gd | j        D             z   | j        gz   S )Nzgsyncd-aux-mount-prefixc                     g | ]}d |z   S )z--rv   )rx   r   s     rB   rz   z1DirectMounter.make_mount_argv.<locals>.<listcomp>  s    +++!TAX+++rD   )tempfilemkdtemprA  r   mount_pointrL  r@  r]  s     rB   r_  zDirectMounter.make_mount_argv  s]    %-@AAA
 J$$&&'++t{+++,/3zl; 	;rD   c                 h    |s| j         }t          t          j        |gt          t
          g           d S r   )rA  r   rR   r   r   r   )rC  rA  s     rB   rb  zDirectMounter.cleanup_mntpt  s1     	JE28eWvuo66666rD   r   )r4  r5  r6  r7  rR  rS  rz  rJ  r<  rQ  r_  rb  rv   rD   rB   r  r    so        BB#EEGK# # \#; ; ; ;7 7 7 7 7 7rD   r  c                   n    e Zd ZdZej        ej        ddZdZed             Z	ed             Z
d Zd Zd	S )
MountbrokerMounterz5mounter backend using the mountbroker gluster serviceT)rO  stdoutrP  glusterc                     |                                  gdgz   t          j        d                                          z   dgz   S )Nz--remote-host=localhostzgluster-cli-optionszsystem::)rL  rH  r   rO   )r@   s    rB   make_cli_argvz MountbrokerMounter.make_cli_argv  sM    ##%%&*C)DDI+,,224458B|D 	DrD   c                 6    |                                  d|dgz   S )Nr  lazy)r  r[  s     rB   rQ  z#MountbrokerMounter.make_umount_argv  s       ""h6%:::rD   c                 n    |                                  d|dt          j                    z   gz   | j        z   S )Nmountzuser-map-root=)r  r|  getusernamer@  r]  s     rB   r_  z"MountbrokerMounter.make_mount_argv  sC    !!##e-&(() **,0K8 	8rD   c                    |j                                         d d         | _        | j        t          _        dt          _        |                                 dgz   | _        | j        t          _        |j         	                                 t          | |           |j        dk    r*t          j        t          d| j                             d S d S )Nr   Tr  r   zglusterd answered)mnt)r  readlinerA  r   r  mountbrokerr  rB  mbr_umount_cmdrt  r&   r  r   r   r$   rd  s     rB   re  z!MountbrokerMounter.handle_mounter  s    Y''))#2#.
 J ,,..(;#
	D"=A M"0djAAABBBBB	 rD   N)r4  r5  r6  r7  rR  rS  rz  rJ  r;  r  rQ  r_  re  rv   rD   rB   r  r    s        ??#JO%)+ +GKD D [D ; ; [;8 8 8
C C C C CrD   r  c                   V    e Zd ZdZedd            Zed             Zed             ZdS )GLUSTERServerz+server enhancements for a glusterfs backendr;   c           	         | j         |z   }t          j        d|t          j        |                    }t          |          }t          j        ||          }t          j        dd	                    d |dd         D                                 }d	                    |
                                          }|dd         ||d         |d	d
         d}|r||t          |           d         fS |S )z+generic volume mark fetching/parsing backedr   rs   r;   c                     g | ]}d |z  S ru   rv   rw   s     rB   rz   z3GLUSTERServer._attr_unpack_dict.<locals>.<listcomp>  s    222AVaZ222rD   r*     r{   r         )r%  r   r(  r)  N)r9  r'   r|   r   calcsizer.   r   r~   r   rS   r   len)	r@   xattrextra_fields
fmt_stringr   vmr   r   volinfos	            rB   _attr_unpack_dictzGLUSTERServer._attr_unpack_dict  s     ^l2
oc5&/**E*EFFs##]:s++H-GG22AbD222335 5 xx

## 1gV"$RU) 
  	BL 1 1122333NrD   c                 &   g }t          j        d          }|D ]}|                    d                    | j        ddg                    dk    r|                     || j                  \  }}t          t          j                              }|d         |k    rPt          j
        d|d         |d         |d         |z
  fz             |d         |d<   |                    |           	 t          j        d|           # t          $ r Y w xY w|S )z7return list of valid (not expired) foreign volume marksr   r$  r;   r   z&volinfo[%s] expires: %d (%d sec later)r   r+  )r'   llistxattr_buffindrS   r   r  r:  r   r  r   r   r   lremovexattrrb   )r@   	dict_list
xattr_listelerU  ry   nows          rB   foreign_volume_infosz"GLUSTERServer.foreign_volume_infos  s;    	)#..
 	 	Cxx#-!CDDEEJJ,,S#2CDD1$)++&&Q4#::M #3#$V9adAaD3J"?#@ A A A $%Q4AiL$$Q''''*34444"    K s   *D  
DDc                     	 |                      d                    | j        dg                    S # t          $ r. t	          j                    d         }|j        t          k    r Y dS w xY w)z;get the native volume mark of the underlying gluster volumer   r$  r=   N)r  rS   r   rb   ri   rj   rk   r   )r@   rm   s     rB   native_volume_infoz GLUSTERServer.native_volume_info2  s    	((3=3@3B *C *C D D D 	 	 	"Bx7"" #""	s   .1 4A)(A)N)r;   )r4  r5  r6  r7  r;  r  r  r  rv   rD   rB   r  r    sn        33   [(   [*   [  rD   r  c                   0    e Zd ZdZeZd Zd Zd ZddZ	dS )GLUSTERaA  scheme class for gluster:// urls

    can be used to represent a gluster secondary server
    on secondary side, or interface to a remote gluster
    secondary on primary side, or to represent primary
    (secondary-ish features come from the mixins, primary
    functionality is outsourced to GPrimary from primary)
    c                 V    |d|| _         || _        || _        | j        a| j        ad S )N:)rL   hostvolumer   r   rC  r  r  s      rB   rD  zGLUSTER.__init__J  s6    #ttVV,		 [
9rD   c                 4   t          j        d           t          j                    }t          j        dd          }|s!t                      st          j                    }|rt          pt          }t          j        d          }t          j        j        dk    rt          j        d          }t          j        d          }t          j        j        dk    rt          j        d          }t          j        d	                                          d
|z   gz   d|z   d| j        z   gz   d| j        z   dgz   } ||          | _        | j                            |           t          j        t%          ddt          j                    |z
  z                       dS )zinhibit the resource beyond

        Choose mounting backend (direct or mountbroker),
        set up glusterfs parameters and perform the mount
        with given backend
        z"Mounting gluster volume locally...r  Nzgluster-log-filerF  zsecondary-gluster-log-filezgluster-log-levelsecondary-gluster-log-levelzgluster-paramsz
log-level=z	log-file=zvolfile-server=zvolfile-id=zclient-pid=-1zMounted gluster volume%.4fduration)r   r  r  rH  r   r   r|  r  r  r  r   rU   rI  rO   r  r  mounterr  r$   )rC  t0r^  r  log_file	log_levelr@  s          rB   connectzGLUSTER.connectT  s    	9:::Y[[	-.. 	-Z\\ 	-*,,E..?-9/00:++y!=>>HI122	:++	"?@@I+,,2244I%&'8#%6%BCD T[(/:;
 wvU###R0!'49;;+;!<> > > 	? 	? 	? 	? 	?rD   c                      t          d          | |           t                      | |           t          d          | |          fS )zLreturn a tuple of the 'one shot' and the 'main crawl'
        class instancexsyncchangeloghistoryr   )rC  rF  s     rB   gprimary_instantiate_tuplez"GLUSTER.gprimary_instantiate_tupleu  sW     * ))$	::" ""4334 !344T9EEG 	GrD   Nc           
           t           j        j        dk    rht          j        d          rt                      st          d          t           j        t          j
        t          j        t          j        d                    t          j        fd          }|                                 t          j        d           t          j        d          rt          j        d          d	k    r{	  j        j        }t%          j        t          j        d                     | j        j        k    r6t          j        t)          dt          j        d                               nynt+          ddd           dS  G  fddt,                    t/          j        fd|j                  |j        _        t/          j        fd|j                  |j        _        t/          j        fd|j                  |j        _        t/          j        fd|j                  |j        _        t/          j        fd|j                  |j        _                             |          \  }}}|j        _        |j        _        |j        _        tA          t          j        d          t           j        j!        t           j        j"        t           j        j#        t           j        j        t           j        j$                  }|%                                 	 |&                                }t          j        d          dk    r]tO          j(        t           j        j"        |t          j        d          tS          t          j        d                    |j*                   tW          t%          j                              }	|(                    |	|           |(                    |	|           nN# tX          $ rA}
t          j-        t)          d|
                     t          j.        d           Y d}
~
nd}
~
ww xY w|(                    |           t          j        t)          d|	                      	 |/                    d
!           n# t`          $ rD}
t          j        t)          d"|
#                     |/                    d
|	$           Y d}
~
nd}
~
wtb          $ r. t          j        d%           |/                    d
|	$           Y ntd          $ r. t          j        d&           |/                    d
|	$           Y nMtX          $ rA}
t          j-        t)          d'|
                     t          j.        d           Y d}
~
nd}
~
ww xY w	 |/                                 dS # tX          $ rB}
t          j-        t)          d(|
                     t          j.        d           Y d}
~
dS d}
~
ww xY w))zenter service loop

        - if secondary given, instantiate GPrimary and
          pass control to that instance, which implements
          primary behavior
        - else do that's what's inherited
        rF  use-rsync-xattrsz4using rsync for extended attributes is not supportedz	sync-jobsc                  H      j                     t          j                    fS r   )service_loopr|  r  )repces   rB   r   z&GLUSTER.service_loop.<locals>.<lambda>  s%    2D%2D2F2F2<2E2G2G2I rD   rl  zsecondary listeningsecondary-timeoutr   Tzconnection inactive, stopping)r+  rv   Nc                        e Zd Zej        j        Zj        Ze fd            Z	e fd            Z
e fd            Ze fd            Z xZS ))GLUSTER.service_loop.<locals>.brickserverc                     t          |                               |          }|dk    r<	 |                    d           |                    d           n# t          $ r Y nw xY w|S )Nr   r9   z	.trashcan)superrf   r   rP   )r@   rL   r   	__class__brickservers      rB   rf   z1GLUSTER.service_loop.<locals>.brickserver.entries  sz    +s++33D993;;...----%   s   *A 
A$#A$c                 J    t          |                               |          S )z path based backend stat )r  r   r@   r   r  r  s     rB   r   z/GLUSTER.service_loop.<locals>.brickserver.lstat  s#     [#..44Q777rD   c                 J    t          |                               |          S )z path based backend gfid fetch )r  r   r  s     rB   r   z.GLUSTER.service_loop.<locals>.brickserver.gfid  s#     [#..33A666rD   c                 J    t          |                               |          S r   )r  rp   r  s     rB   rp   z6GLUSTER.service_loop.<locals>.brickserver.linkto_check  s!    [#..;;A>>>rD   )r4  r5  r6  r   rU   rT   server
aggregatedr;  rf   r   r   rp   __classcell__)r  r  rC  s   @rB   r  r    s        .JJ	 	 	 	 	 [	 8 8 8 8 8 [8 7 7 7 7 7 [7 ? ? ? ? ? [? ? ? ? ?rD   r  c                 Z                         ||dz   t          j        j        z             S Nr   )r   r   rU   secondary_id_selfrL   r   r  s      rB   r   z&GLUSTER.service_loop.<locals>.<lambda>  0    !!$"&*uz/F"FH H rD   c                 Z                         ||dz   t          j        j        z             S r  )r   r   rU   r  r  s      rB   r   z&GLUSTER.service_loop.<locals>.<lambda>  r  rD   c                 Z                         ||dz   t          j        j        z             S r  )r   r   rU   r  r  s      rB   r   z&GLUSTER.service_loop.<locals>.<lambda>  s/    ''3J!88: : rD   c                 \                         ||dz   t          j        j        z   |          S r  )r   r   rU   r  r  rL   r   r   r  s       rB   r   z&GLUSTER.service_loop.<locals>.<lambda>  s1    %%d&*Sj5:3J&J&*, , rD   c                 \                         ||dz   t          j        j        z   |          S r  )r   r   rU   r  r	  s       rB   r   z&GLUSTER.service_loop.<locals>.<lambda>  s2    ++3J!88  rD   z
state-filezchange-detectorr  zchangelog-log-filezchangelog-log-levelzChangelog register failed)r   r=   )statuszRegister time)r  )oneshotzDPartial history available, using xsync crawl after consuming history)till)r  register_timez,Changelog history not available, using xsyncz%No stime available, using xsync crawlzChangelog History Crawl failedzChangelog crawl failed)3r   rU   rI  rH  r   r   r   r   r  ri   stdinr  r|  r}  r~  r   r  r/  r  r  r$   r   r6   types
MethodTyper   r   r   r   r   r  primaryr,   
local_noderT   local_node_idrF  reset_on_worker_startsetup_working_dirlibgfchangelogregisterr    CHANGELOG_CONN_RETRIESr   r   r   exit	crawlwrapr   r   r   )rC  rF  r  lpg1g2g3r  workdirr  r   r  r  s   `          @@rB   r  zGLUSTER.service_loop|  s    :++y+,, LZ\\ L!JL L L  SY
EIk4J4JL LE! *I *I *I *I J J JAGGIIIL.///y,-- 
#%)<O2P2PST2T2T4BJuy)<==>>>T[888>',y1D'E'EG G GH H H  r2r"""F	? 	? 	? 	? 	? 	? 	? 	?& 	? 	? 	?B "'!1    " "	 "'!1    " "	 (-'7   
 ( (	$ &+%5   
 & &	" ,1+;    , ,	( 66yAAR'
'
'
 ei55#j3#j3#j6#j0#j24 4 	$$&&&	**,,G y*++w66 '
(=(/(-	2F(G(G(?,1I6K,L,L)N )N(*(AC C C  	,,MKKv...KKv....! 	 	 	M"8BBBCCCHQKKKKKKKK	 	6"""R*, , , 	- 	- 	-	LLL&&&&& 	D 	D 	DL 7!"$ $ $ % % % LL]LCCCCCCCC+ 	D 	D 	DLGHHHLL]LCCCCC 	D 	D 	DL@AAALL]LCCCCC! 	 	 	M"=#$& & & ' ' 'HQKKKKKKKK	
	LLNNNNN! 	 	 	M"5Q???@@@HQKKKKKKKKK	sa   CO4 4
P?>7P::P?<R 
V:S8V4V	V7VVV1 1
W=;7W88W=r   )
r4  r5  r6  r7  r  r  rD  r  r  r  rv   rD   rB   r  r  >  sp          F  ? ? ?BG G Gk k k k k krD   r  c                   H    e Zd ZdZd Zed             Zd Zd Zd Z	d
dZ
d	S )SSHzxscheme class for ssh:// urls

    interface to remote secondary on primary side
    implementing an ssh based proxy
    c                 "    || _         || _        d S r   )remote_addrr  r  s      rB   rD  zSSH.__init__2  s    rD   c                     t          j        d| j                  }|r|                                \  }}nt	          j                    | j        }}|| _        ||dS )Nz([^@]+)@(.+))userr  )r~   r   r$  r   r|  r  
remotehost)rC  r   uhs       rB   parse_ssh_addresszSSH.parse_ssh_address6  s[    H^T%566 	>88::DAqq)++T-=qA1%%%rD   c                    t          ||          | _        | j                                        }t          j        t
                                          d}||f}i i f}t          d          D ]:}||                                         D ]\  }}t          |          ||         |<   ;|d         |d         k    rt          d|d|          d| j                                        z  }	d                    | j        |	g          | _        d	S )
zset up RePCe client, handshake with server

        It's cut out as a separate method to let
        subclasses hook into client startup
        )protoobjectr*  r   r=   z$RePCe major version mismatch: local z	, remote z/proc/%d/cwdr  N)r   r  __version__r  repce_versionr6   r%  rangeitemsr   r   r"  rS   r$  secondaryurl)
rC  ior  exrvda0da1kvsecondarypaths
             rB   start_fd_clientzSSH.start_fd_client@  s    "!Q''[$$&&,8H8HII4j2hq 	# 	#AA # #1FFAq		#q6SV+rr   '):)::HHd&6%FGGrD   c                    t          j        t          j        d          | j        | j                   t          j        d           t          j                    }g }t          j
        d          }|dk    rd}t          j
        d          r|                    d           t          j
        d	          gt          j
        d
                                          z   dt          t          j
        d                    gz   t          j        z   | j        gz   |dgz   |z   t          j        j        t          j        j        gz   dt          j        j        dt          j        j        dt          j        j        dt          j        j        dt          j        j        g
z   dt          t          j
        d                    dt          j
        d          dt          j
        d          dt          j
        d          dt          t          j
        d                    g
z   }t          j
        d          r|                    d           t          j        j        r|                    d           t3          |t4          j        t4          j        t4          j                   }|t          _        |                     |j        |j                   t          j        tA          d!d"t          j                    |z
  z  #                     d$S )%a  connect to inner secondary url through outer ssh url

        Wrap the connecting utility in ssh.

        Much care is put into daemonizing: in that case
        ssh is started before daemonization, but
        RePCe client is to be created after that (as ssh
        interactive password auth would be defeated by
        a daemonized ssh, while client should be present
        only in the final process). In that case the action
        is taken apart to two parts, this method is ivoked
        once pre-daemon, once post-daemon. Use @go_daemon
        to deiced what part to perform.

        [NB. ATM gluster product does not makes use of interactive
        authentication.]
        zgsyncd-aux-ssh-r  z<Initializing SSH connection between primary and secondary...zremote-gsyncdr;   z/nonexistent/gsyncdr  z--use-rsync-xattrsssh-commandssh-options-pssh-portrF  z--primary-nodez--primary-node-idz--primary-brickz--local-nodez--local-node-idz--secondary-timeoutr  z--secondary-log-levelzsecondary-log-levelz--secondary-gluster-log-levelr  z--secondary-gluster-command-dirrG  z--primary-dist-countzprimary-distribution-countro  z--secondary-access-mountz--debug)r  r  rO  z9SSH connection between primary and secondary established.r  r  N)!r|  setup_ssh_ctlr  r  r$  r  r   r  r  rH  r   r   rO   r   r   ssh_ctl_argsrU   r  rF  r  r  rT   resource_remoteresource_remote_idr   r%   rR  rS  	transportr;  r  r  r$   )rC  r  
extra_optsremote_gsyncdargs_to_secondaryrV  s         rB   connect_remotezSSH.connect_remoteU  s   $ 	 !19J!K!K!K!%!1!%	. 	. 	. 	STTTY[[
	/22B1M9'(( 	42333"Y}556Im$$**,,-3uy,,--./  #'"2!34 K(	)
  Z!567 !%*"7#UZ%=!5:#8
 :!5:#@BB" &s595H+I+I'J'J'3H)I)I/	7881	9::&EI:;;<<>>4 9-.. 	A$$%?@@@: 	0$$Y///$#$/+ + + RY111RS!'49;;+;!<> > > 	? 	? 	? 	? 	?rD   c                    |st          d          t          j        dd                    |          z              g }t	          j        d          r(t          t	          j        d                    dk    rdg}t	          j        d          gt	          j        d	                                          z   d
t          t	          j        d                    gz   t          j
        z   t	          j        d                                          z   }t	          j        d          dddddddg}t	          j        d          r|dgz  }t	          j        d          r|dgz  }t	          j        d          r|dgz  }|t	          j        d                                          z   |z   dgz   dd                    |          gz   | j        gz   }t	          j        dd          }d}|D ]!}	|	d k    s|	                    d!          rd"} n"|s|r3t          |t          j        t          j        t          j        d"#          }
n't          |t          j        t          j        d"$          }
|D ]6}|
j                            |           |
j                            d%           7|
                                \  }}|                    d&d          rV|                                                    d'          d(d)         D ]&}t          j        t-          d*d+|,                     '|r"g }|                    d'          D ]}|                    d-          s|                    d.          s|                    d/          s~|                    d0          si|                    d1          sT|                    d2          s?|                    d3          s*|                    d4          s|                    d5          r|                    |           t          j        t-          d6d                    |          7                     |r0t          j        t-          d8t3          |          7                     |
S )9zinvoke rsyncno files to syncfiles: , zrsync-opt-ignore-missing-argszrsync-commandz3.1.0z--ignore-missing-argsr=  r>  r?  r@  zrsync-ssh-optionsz-aR0z	--inplacez--files-from=-z--superz--statsz--numeric-idsz--no-implied-dirszrsync-opt-existingz
--existingzsync-xattrsz--xattrsz	sync-aclsz--aclszrsync-optionsr   z-er   zlog-rsync-performanceFz	--verbosez-vT)r  r  rO  rP  r  rO  rP  rg  log_err
Nr   
SYNC ErrorRsyncsync_enginer   zNumber of files:z$Number of regular files transferred:zTotal file size:zTotal transferred file size:zLiteral data:zMatched data:zTotal bytes sent:zTotal bytes received:zsent zrsync performance)datazrsync verbose)r   r   r   rS   rH  r   r!   rO   r   r   rB  r2  getr
startswithr%   rR  rS  r  ry  communicatestripr   r$   r   r  r   )rC  filesrU   kwextra_rsync_flagsrsync_ssh_optsargvlog_rsync_performancersync_verboseitemrV  rW   r  rO  errline	rsync_msglines                    rB   rsyncz	SSH.rsync  s    	20111i$))E"2"22333 9455 	:UY7788GCC!8 9)M223Im$$**,,-3uy,,--./  I)**0022	3 Io&&	
 9)** 	#\N"D9]## 	!ZL D9[!! 	XJDIo&&,,../!$& 388N++,- 	  !&
+BE J J 	 	D{""dood&;&;" $ # ! 	0M 	0 t:?:?(o$H H HBB t:?:?*.0 0 0B  	! 	!AHNN1HNN4    ))66)U## 	1!<<>>//55crc: 1 1b-4'.0 0 0 1 1 1 1 ! 	8IT** 
+ 
+??#566 	+??#IJJ	+??#566	+ ??#ABB	+ ???33		+
 ???33	+ ??#677	+ ??#:;;	+ ??7++	+ $$T***L/!%9!5!57 7 7 8 8 8  	ALO$v,,???@@@	rD   Fc                    |st          d          t          j        dd                    |          z              | j                            d          \  }}dgg dz   }t          j        d                                          t          j        d                                          z   d	t          t          j        d
                    gz   |dgz   dddd|gz   }t          |t          j        t          j        t          j        d          }t          ||j        t          j        d          }|D ]6}	|j                            |	           |j                            d           7|j                                         |j                                         d|_        d|_        fd}
t!          j        |
|f          }|                                 |                                \  }}|                                 rV|                                                    d          dd         D ]&}t          j        t-          dd|                     '|S )zinvoke tar+ssh
        -z (compress) can be use if needed, but omitting it now
        as it results in weird error (tar+ssh errors out (errcode: 2)
        rK  rL  rM  r  tar)z--sparsez-cfr{   z--files-fromr{   r=  zssh-options-tarr?  r@  z--overwritez-xfr{   z-CT)r  r  rO  rP  rN  rP  Nc                     |                                  \  }}rZ|                                                    d          d d         D ],}d|vr$t          j        t          dd|                     +d S d S )NrP  r   zNo such file or directoryrQ  TarsshrS  )rX  rY  rO   r   r   r$   )p0r  rO  rb  rO  s       rB   wait_for_tarz SSH.tarssh.<locals>.wait_for_tar   s    ((IAv 9%||~~33D99#2#> 9 9G2'AAb5=/6'8 '8 '8 9 9 99 99 9rD   )r   rU   r   rQ  ri  rS  )r   r   r   rS   r2  rO   rH  r   r   r%   rR  rS  r  r  ry  rt  r|  r}  r~  rX  rY  r   r$   )rC  rZ  rO  r  rdirtar_cmdssh_cmdrj  p1rW   rk  r  r  stderr1rb  s     `            rB   tarsshz
SSH.tarssh  ss   
  	20111i$))E"2"22333(..s33t'999:)M**0022I'((..0013uy,,--./ 5M E3d3	4
 7:?#&*, , , 7")JO&*, , , 	! 	!AHNN1HNN4    

	 		9 	9 	9 	9 	9 \??? 	
			 ^^%%
7	 	1"==??0066ss; 1 1b-5'.0 0 0 1 1 1 1 	rD   Nr   )r4  r5  r6  r7  rD  r<  r*  r;  rI  re  rq  rv   rD   rB   r"  r"  *  s            & & \&H H H*G? G? G?R^ ^ ^@: : : : : :rD   r"  )Or~   rR   ri   r_   r  ru  r  r   r   r  rR  rk   r   r   r   r   r   r   r	   r
   r   r   r   r   r   gsyncdconfigrH  r  r  r   r   r  r   r|  r   r   r   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   gsyncdstatusr,   py2py3r-   r.   r/   r0   r1   r2   getattrr3   r   r   r-  r6   r>  r  r  r  r  r"  rv   rD   rB   <module>rv     s   
			 				 



           D D D D D D D D D D D D D D D D D D D D D D D D D D D D                 * * * * * * * * $ $ $ $ $ $    I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I & % % % % %( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (
 '%L
1
1
z z z z zV z z zzP< P< P< P< P<f P< P< P<f7 7 7 7 7G 7 7 7."C "C "C "C "C "C "C "CJ8 8 8 8 8F 8 8 8vi i i i if i i iXN N N N N& N N N N NrD   