
    yf@                     N   S SK r S SKrS SKrS SKrS SKrSSKJr  SSKJrJ	r	  SSK
Jr  Su  rrrSu  rr\" \5      r
 " S S	5      r " S
 S\5      r " S S\	5      r " S S\5      r " S S\5      r " S S\5      r " S S\5      r " S S5      r " S S5      r " S S5      rg)    N   )platform)ErrorErrorWithTraceback)create_logger)addremoveremove2)shared	exclusivec                   @    \ rS rSrSrSS jrS rS rS rS r	S	 r
S
rg)TimeoutTimer   z
A timer for timeout checks (can also deal with "never timeout").
It can also compute and optionally execute a reasonable sleep time (e.g. to avoid
polling too often or to support thread/process rescheduling).
Nc                     Ub  US:  a  [        S5      eXl        Uc  Uc  SnO[        SUS-  5      nX l        SU l        SU l        g)a7  
Initialize a timer.

:param timeout: time out interval [s] or None (never timeout, wait forever) [default]
:param sleep: sleep interval [s] (>= 0: do sleep call, <0: don't call sleep)
              or None (autocompute: use 10% of timeout [but not more than 60s],
              or 1s for "never timeout" mode)
Nr   ztimeout must be >= 0g      ?g      N@g      $@)
ValueErrortimeout_intervalminsleep_interval
start_timeend_time)selftimeoutsleeps      ./usr/lib/python3/dist-packages/borg/locking.py__init__TimeoutTimer.__init__   sU     7Q;344 '=D'D.1#    c                     SR                  U R                  R                  U R                  U R                  U R
                  U R                  5      $ )Nz1<{}: start={!r} end={!r} timeout={!r} sleep={!r}>)format	__class____name__r   r   r   r   r   s    r   __repr__TimeoutTimer.__repr__,   s?    BIINN##T__dmm!!4#6#68 	8r   c                     [         R                   " 5       U l        U R                  b  U R                  U R                  -   U l        U $ N)timer   r   r   r"   s    r   startTimeoutTimer.start1   s6    ))+  , OOd.C.CCDMr   c                 f    U R                   S:  a!  [        R                  " U R                   5        g g Nr   )r   r'   r   r"   s    r   r   TimeoutTimer.sleep7   s'    !#JJt**+ $r   c                 p    U R                   S L=(       a"    [        R                  " 5       U R                   :  $ r&   )r   r'   r"   s    r   	timed_outTimeoutTimer.timed_out;   s%    }}D(ITYY[DMM-IIr   c                 P    U R                  5       (       a  gU R                  5         g)NTF)r.   r   r"   s    r   timed_out_or_sleepTimeoutTimer.timed_out_or_sleep>   s    >>JJLr   )r   r   r   r   NN)r!   
__module____qualname____firstlineno____doc__r   r#   r(   r   r.   r1   __static_attributes__ r   r   r   r      s&    
*8
,Jr   r   c                       \ rS rSrSrSrSrg)	LockErrorF   Failed to acquire the lock {}.r9   Nr!   r4   r5   r6   r7   
exit_mcoder8   r9   r   r   r;   r;   F   
    (Jr   r;   c                       \ rS rSrSrSrSrg)
LockErrorTK   r=   G   r9   Nr>   r9   r   r   rB   rB   K   r@   r   rB   c                       \ rS rSrSrSrSrg)
LockFailedP   z*Failed to create/acquire the lock {} ({}).H   r9   Nr>   r9   r   r   rF   rF   P   s
    4Jr   rF   c                       \ rS rSrSrSrSrg)LockTimeoutU   z/Failed to create/acquire the lock {} (timeout).I   r9   Nr>   r9   r   r   rJ   rJ   U   
    9Jr   rJ   c                       \ rS rSrSrSrSrg)	NotLockedZ   z/Failed to release the lock {} (was not locked).J   r9   Nr>   r9   r   r   rO   rO   Z   rM   r   rO   c                       \ rS rSrSrSrSrg)	NotMyLock_   z=Failed to release the lock {} (was/is locked, but not by me).rC   r9   Nr>   r9   r   r   rS   rS   _   s
    GJr   rS   c                   b    \ rS rSrSrSS jrS rS rS rSS jr	S	 r
S
 rS rS rS rS rSrg)ExclusiveLockd   a  An exclusive Lock based on mkdir fs operation being atomic.

If possible, try to use the contextmanager here like::

    with ExclusiveLock(...) as lock:
        ...

This makes sure the lock is released again if the block is left, no
matter how (e.g. if an exception occurred).
Nc                 >   X l         X0l        [        R                  R	                  U5      U l        U=(       d    [
        R                  " 5       U l        [        R                  R                  U R                  SU R                  -  5      U l	        SU l
        SU l        g )N%s.%d-%xTF)r   r   ospathabspathr   get_process_ididjoinunique_namekill_stale_locksstale_warning_printed)r   r[   r   r   r^   s        r   r   ExclusiveLock.__init__o   si    
GGOOD)	1//177<<		:3GH $%*"r   c                 "    U R                  5       $ r&   acquirer"   s    r   	__enter__ExclusiveLock.__enter__x       ||~r   c                 $    U R                  5         g r&   releaser   excs     r   __exit__ExclusiveLock.__exit__{       r   c                 R    SU R                   R                   SU R                  < S3$ N<z: >)r    r!   r`   r"   s    r   r#   ExclusiveLock.__repr__~   s)    4>>**+2d.>.>-ACCr   c                    Uc  U R                   nUc  U R                  n[        R                  R	                  U R                  5      u  p4[        R                  R                  U R                  5      nS n [        R                  " SUS-   U5      n[        R                  R                  Xe5      n[        US5          S S S 5        [        X5      R                  5       n  [        R                  " X`R                  5        S nU Ub/   [        R                  " U5         [        R                  " U5        $ $ ! , (       d  f       N= f!    N.= f!    $ = f! [          a    U R#                  5       (       aE  U s Ub>   [        R                  " U5        O!    O= f [        R                  " U5        $ !    $ = f$ U R%                  5         UR'                  5       (       a  [)        U R                  5      S e Of = fGM  ! [          a%  n	[+        U R                  [-        U	5      5      S eS n	A	ff = f! Ub>   [        R                  " W5        O!    O= f [        R                  " U5        f !    f = ff = f)Nz.tmp.wb)r   r   rZ   r[   splitbasenamer`   tempfilemkdtempr_   openr   r(   replaceunlinkrmdirOSErrorby_mekill_stale_lockr1   rJ   rF   str)
r   r   r   parent_path	base_nameunique_base_name	temp_pathtemp_unique_nametimererrs
             r   rf   ExclusiveLock.acquire   s$   ?llG=JJE!#tyy!977++D,<,<=	 	 ((S+NI!ww||IH&- .
 !0668E
 JJy))4 !%I$II./HHY' %' .-0)  ?zz||# $II./HHY' % ((*//11)$))4$> 2	? 	  	<TYYC1t;	<" $II./HHY' %s   6AG> <D7>G> H0 ! E H0 EE7
EG> EE!G87H0 <FFF22F6:;G85H0 7G88H0 >
H- H((H--H0 0I35II3II3I+*I3+I/-I3c                    U R                  5       (       d  [        U R                  5      eU R                  5       (       d  [	        U R                  5      e[
        R                  " U R                  5         [
        R                  " U R                  5        g ! [         aI  nUR                  [        R                  [        R                  [        R                  4;  a  Ue S nAg S nAff = fr&   )	is_lockedrO   r[   r   rS   rZ   r   r`   r   r   errno	ENOTEMPTYEEXISTENOENT)r   r   s     r   rl   ExclusiveLock.release   s    ~~DII&&zz||DII&&
		$""#	HHTYY 	yy%,, MM	 N	s   6 B 
C*!?C%%C*c                 T    [         R                  R                  U R                  5      $ r&   )rZ   r[   existsr"   s    r   r   ExclusiveLock.is_locked   s    ww~~dii((r   c                 T    [         R                  R                  U R                  5      $ r&   )rZ   r[   r   r`   r"   s    r   r   ExclusiveLock.by_me   s    ww~~d..//r   c           	          [         R                  " U R                  5      nU H  n UR                  SS5      u  p4UR                  SS5      u  pV[	        U5      n[	        US5      n[        R                  " XWU5      (       a    gU R                  (       d0  U R                  (       d  [        R                  SU5        SU l          g [         R                  " [         R                  R                  U R                  U5      5        [        R                  S	U5        M      [         R$                  " U R                  5        g! [
         a$    [        R                  SX R                  5           gf = f! [         aC  n	U R                  (       d'  [        R                  S
U[!        U	5      5        SU l         S n	A	  gS n	A	ff = f! ["         a     Nf = f! [         ak  n	U	R&                  [&        R(                  [&        R*                  [&        R,                  4;   a   S n	A	g[        R                  S[!        U	5      5         S n	A	gS n	A	ff = f)N-r   rx      z9Found malformed lock %s in %s. Please check/fix manually.FzLFound stale lock %s, but not deleting because self.kill_stale_locks = False.TzKilled stale lock %s.z0Found stale lock %s, but cannot delete due to %szFailed to remove lock dir: %s)rZ   listdirr[   rsplitintr   loggererrorr   process_alivera   rb   warningr   r_   r   r   FileNotFoundErrorr   r   r   r   r   )
r   namesnamehost_pid
thread_strhostpid_strpidthreadr   s
             r   r   ExclusiveLock.kill_stale_lock   s   "	!JJtyy)E !+/;;sA+>(H$,OOC$;MDg,C R0F ))$V<< ,,55'uw{|592 !IIbggll499d;<NN#:DA/ >	HHTYY G " !LL!\^bdmdmn !$  !55%WY]_bcf_gh592 !7 ! 		H  	yyU__ellELLIILL8#c(C	sY    G ?EAE2  G *E/.E/2
F?<8F::F?
GG
I=IIIc                 :   U R                  5       (       a  [        R                  " U R                  5       HA  n[        R                  " [        R                  R                  U R                  U5      5        MC     [        R                  " U R                  5        g g r&   )r   rZ   r   r[   r   r_   r   )r   r   s     r   
break_lockExclusiveLock.break_lock   sZ    >>

499-		"'',,tyy$78 .HHTYY r   c                    U R                   U:X  d   e[        R                  R                  U R                  SU-  5      nU R	                  5       (       aK  U R                  5       (       a6  [        US5          SSS5        [        R                  " U R                  5        X#sU l         U l        g! , (       d  f       N== f)0migrate the lock ownership from old_id to new_idrY   ry   N)	r^   rZ   r[   r_   r   r   r~   r   r`   )r   old_idnew_idnew_unique_names       r   migrate_lockExclusiveLock.migrate_lock   s    ww&   '',,tyy*v2EF>>

ot, -IId&&'$*!! -,s   6B//
B=)r^   ra   r[   r   rb   r   r`   NNNr3   )r!   r4   r5   r6   r7   r   rg   ro   r#   rf   rl   r   r   r   r   r   r8   r9   r   r   rV   rV   d   sA    	+D(T )0/b <r   rV   c                   L    \ rS rSrSrSS jrS rS rS rS r	S	 r
S
 rS rSrg)
LockRosteri  z
A Lock Roster to track shared/exclusive lockers.

Note: you usually should call the methods with an exclusive lock held,
to avoid conflicting access by multiple threads/processes/machines.
Nc                 d    Xl         U=(       d    [        R                  " 5       U l        SU l        g )NT)r[   r   r]   r^   ra   )r   r[   r^   s      r   r   LockRoster.__init__
  s$    	1//1 $r   c           	          [        U R                  5       n[        R                  " U5      nS S S 5        U R                  (       a  [
        [        4 Ht  n WU   n[        5       nU HN  u  pgn[        R                  " XgU5      (       a  UR                  XgU45        M7  [        R                  SX6Xx5        MP     [        U5      X#'   Mv     W$ ! , (       d  f       N= f! [         a     M  f = f! [        [         4 a    0 n U$ f = f)Nz:Removed stale %s roster lock for host %s pid %d thread %d.)r~   r[   jsonloadra   SHARED	EXCLUSIVEKeyErrorsetr   r   r   r   r   listr   r   )	r   fdatakeyentrieselementsr   r   r   s	            r   r   LockRoster.load  s    	diiAyy| ! $$"I.C!"&s)  #uH-4)6#11$VDD$LL$V)<="NN+g+.cC	 .5 !%XDI /  + ! $ ! ! ":. 	D	sL   C/ C(C/ CA/C/ 
CC/ 
C,(C/ +C,,C/ /DDc                     [        U R                  S5       n[        R                  " X5        S S S 5        g ! , (       d  f       g = f)Nw)r~   r[   r   dump)r   r   r   s      r   saveLockRoster.save(  s*    $))S!QIId "!!s	   7
Ac                 f     [         R                  " U R                  5        g ! [         a     g f = fr&   )rZ   r   r[   r   r"   s    r   r	   LockRoster.remove,  s)    	IIdii   		s    # 
00c                     U R                  5       nUR                  U/ 5       Vs1 s H  n[        U5      iM     sn$ s  snf r&   )r   gettuple)r   r   rosteres       r   r   LockRoster.get2  s6    "(**S""56"5Qa"5666s   =c                 .   ^  [        U 4S jU 5       5      $ )Nc              3   P   >#    U  H  nTR                  U5      (       + v   M     g 7fr&   )r   ).0r   r   s     r   	<genexpr>#LockRoster.empty.<locals>.<genexpr>7  s     5txx}$$s   #&)all)r   keyss   ` r   emptyLockRoster.empty6  s    5555r   c                    U R                  5       n X1    Vs1 s H  n[        U5      iM     nnU[        :X  a  UR                  U R                  5        OZU[        :X  a  UR                  U R                  5        O4U[        :X  a  UR                  U R                  5        O[        SU-  5      e[        S U 5       5      X1'   U R                  U5        g s  snf ! [         a    [        5       n Nf = f)NzUnknown LockRoster op %rc              3   8   #    U  H  n[        U5      v   M     g 7fr&   )r   )r   r   s     r   r   $LockRoster.modify.<locals>.<genexpr>J  s     5Hq477Hs   )r   r   r   r   ADDr   r^   REMOVEdiscardREMOVE2r	   r   r   r   )r   r   opr   r   r   s         r   modifyLockRoster.modify9  s    	*0+6+Qa+H6 9LL!6\ TWW%7]OODGG$7"<==5H55		& 7 	uH	s!   C CC C C10C1c                    U R                   U:X  d   eU R                  Sso@l          U R                  U[        5        X0l         U R                  U[        5        X@l        g! [
         a	    X0l          Nf = f! X@l        f = f)r   FN)r^   ra   r   r   r   r   )r   r   r   r   killings        r   r   LockRoster.migrate_lockM  s{    ww&    *.)>)>&&	,&C) !C%$+!  ! ! %,!s(   A! A7 !A41A7 3A44A7 7A?)r^   ra   r[   r&   )r!   r4   r5   r6   r7   r   r   r   r	   r   r   r   r   r8   r9   r   r   r   r     s/    %
276(,r   r   c                   h    \ rS rSrSrSS jrS rS rS rSS jr	S	 r
S
 rS rS rS rS rS rSrg)Lockia  a  
A Lock for a resource that can be accessed in a shared or exclusive way.
Typically, write access to a resource needs an exclusive lock (1 writer,
no one is allowed reading) and read access to a resource needs a shared
lock (multiple readers are allowed).

If possible, try to use the contextmanager here like::

    with Lock(...) as lock:
        ...

This makes sure the lock is released again if the block is left, no
matter how (e.g. if an exception occurred).
Nc                     Xl         X l        X0l        X@l        U=(       d    [        R
                  " 5       U l        [        US-   US9U l        [        US-   XTS9U l
        g )Nz.roster)r^   z
.exclusive)r^   r   )r[   is_exclusiver   r   r   r]   r^   r   _rosterrV   _lock)r   r[   r   r   r   r^   s         r   r   Lock.__init__p  sT    	%
1//1!$"2r: #4,#62O
r   c                 "    U R                  5       $ r&   re   r"   s    r   rg   Lock.__enter__}  ri   r   c                 $    U R                  5         g r&   rk   rm   s     r   ro   Lock.__exit__  rq   r   c                 R    SU R                   R                   SU R                  < S3$ rs   )r    r!   r^   r"   s    r   r#   Lock.__repr__  s&    4>>**+2dgg[::r   c                    Uc  U R                   nU=(       d    U R                  =(       d    SnU(       a6  U R                  X#5        U R                  R	                  [
        [        5        O\U R                     Ub   U R                  R	                  U[        5        U R                  R	                  [        [        5        S S S 5        Xl         U $ ! , (       d  f       N= f)Ng?)
r   r   _wait_for_readers_finishingr   r   r   r   r   r   r   )r   r   r	   r   s       r   rf   Lock.acquire  s    ))I**s,,V;LL	3/%LL''7##FC0  & s   7AC
Cc                 4   [        U R                  U5      R                  5       n U R                  R	                  5          Ub   U R
                  R                  U[        5        [        U R
                  R                  [        5      5      S:X  a  g Ub   U R
                  R                  U[        5        U R                  R                  5         UR                  5       (       a  [        U R                  5      eM  !   U R                  R                  5         e = fr+   )r   r   r(   r   rf   r   r   r   lenr   r   r   rl   r1   rJ   r[   )r   r	   r   r   s       r   r    Lock._wait_for_readers_finishing  s    T\\51779JJ %%LL''7t||''/0A5%LL''4 

""$''))!$)),,# 

""$s   AC: #C: :Dc                 D   U R                   (       a  U R                  R                  [        [        5        U R                  R                  [        [        5      (       a  U R                  R                  5         U R                  R                  5         g U R                     U R                  R                  [        [        5        U R                  R                  [        [        5      (       a  U R                  R                  5         S S S 5        g ! , (       d  f       g = fr&   )
r   r   r   r   r   r   r   r	   r   rl   r"   s    r   rl   Lock.release  s    LL	62||!!)V44##%JJ ##FF3<<%%i88LL'') s    A(D
Dc                 P    U R                   (       d  U R                  S[        S9  g g )NTr   r	   )r   rf   r   r"   s    r   upgradeLock.upgrade  s"       LL4L7 !r   c                 P    U R                   (       a  U R                  S[        S9  g g )NFr  )r   rf   r   r"   s    r   	downgradeLock.downgrade  s     LL5L; r   c                     U R                   =(       a;    U R                  R                  5       =(       a    U R                  R                  5       $ r&   )r   r   r   r   r"   s    r   got_exclusive_lockLock.got_exclusive_lock  s2      RTZZ%9%9%;R

@P@P@RRr   c                 l    U R                   R                  5         U R                  R                  5         g r&   )r   r	   r   r   r"   s    r   r   Lock.break_lock  s"    

r   c                    U R                   U:X  d   eX l         U R                  (       a<  U R                  R                  X5        U R                  R                  [
        X5        g U R                     U R                  R                  X5        U R                  R                  [        X5        S S S 5        g ! , (       d  f       g = fr&   )r^   r   r   r   r   r   r   )r   r   r   s      r   r   Lock.migrate_lock  s    ww&   JJ##F3LL%%i@

''7))&&A s   2<B77
C)r   r   r^   r   r[   r   r   )FNNNr   )r!   r4   r5   r6   r7   r   rg   ro   r#   rf   r   rl   r  r  r  r   r   r8   r9   r   r   r   r   a  sF    P;-*
*8<S 	Br   r   )r   r   rZ   r|   r'    r   helpersr   r   r   r   r   r   r   r   r   r!   r   r;   rB   rF   rJ   rO   rS   rV   r   r   r9   r   r   <module>r     s      	    . !1 VW) 		x	 2 2j 
# 
 
) 

 

 
\< \<~[, [,|oB oBr   