o
    eP                     @   s  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Zejdkr>d dlZd dlZnd dlmZ d dlmZ d dlZd dlZd dlZejdZdadadadadadadada da!da"dd Z#d	d
 Z$dd Z%dd Z&dd Z'dd Z(dd Z)dd Z*dd Z+dd Z,dd Z-dd Z.dd  Z/d!d" Z0d#d$ Z1d%d& Z2d'd( Z3d)d* Z4d+d, Z5d-d. Z6d/d0 Z7d1d2 Z8d3d4 Z9d5d6 Z:d7d8 Z;d9d: Z<d;d< Z=dS )=    Nwin32daemonFT   c                 C   s6   | du s| dkrdt jjt jjf S t jt jj| S )zdReturns the file name that would be used for a pidfile if 'name' were
    provided to set_pidfile().N z	%s/%s.pid)ovsdirsRUNDIRutilPROGRAM_NAMEabs_file_namename r   ,/usr/lib/python3/dist-packages/ovs/daemon.pymake_pidfile_nameF   s   r   c                 C   s   t | adS )aG  Sets up a following call to daemonize() to create a pidfile named
    'name'.  If 'name' begins with '/', then it is treated as an absolute path.
    Otherwise, it is taken relative to ovs.util.RUNDIR, which is
    $(prefix)/var/run by default.

    If 'name' is null, then ovs.util.PROGRAM_NAME followed by ".pid" is
    used.N)r   _pidfiler   r   r   r   set_pidfileO   s   	r   c                   C      da dS )z!Sets that we do not chdir to "/".FN)_chdirr   r   r   r   set_no_chdir[   s   r   c                   C   r   )zNormally, daemonize() or daemonize_start() will terminate the program
    with a message if a locked pidfile already exists.  If this function is
    called, an existing pidfile will be replaced, with a warning.TN)_overwrite_pidfiler   r   r   r   ignore_existing_pidfilea   s   r   c                   C   r   )zzSets up a following call to daemonize() to detach from the foreground
    session, running this process in the background.TN_detachr   r   r   r   
set_detachi      r   c                 C   s   da t| adS )zSets up a following call to daemonize() to fork a supervisory
    process to monitor the daemon and restart it if it dies due to
    an error signal. Used on Windows only.TN)	_detachedint_daemonize_fd)wpr   r   r   set_detachedp   s   r    c                   C   s   t S )zWill daemonize() really detach?r   r   r   r   r   
get_detachz   s   r!   c                   C   r   )zSets up a following call to daemonize() to fork a supervisory process to
    monitor the daemon and restart it if it dies due to an error signal.TN)_monitorr   r   r   r   set_monitor   r   r#   c                 C   s(   t |  tjd|   td d S )N%s
   )vlogerrsysstderrwriteexit)msgr   r   r   _fatal   s   
r-   c               
   C   s  t  } tjdkrdt| f }tj| ndt }zt|da	W n t
y< } ztd||jf  W Y d}~nd}~ww z	t t	 }W n t
ya } ztd||jf  W Y d}~nd}~ww zt	d|   t	  W n ty } ztd	||jf  W Y d}~nd}~ww ztjdkrtt	tjtjB  n
tt	tjtjB  W n t
y } ztd
||jf  W Y d}~nd}~ww tjdkrtjtt	 ntrzt |t W n_ ty } ztd|t|jf  W Y d}~nHd}~ww 	 z
t |t d}W n ty } z	|j}W Y d}~nd}~ww |tjkr#t  n|tjkr*nq|r:td|tt |f  tjt tsWtj|}|rWtd|t |f  |j a!|j"a#dS )zIf a pidfile has been configured, creates it and stores the running
    process's pid in it.  Ensures that the pidfile will be deleted when the
    process exits.r   z%s.tmp%dz%swz%s: create failed (%s)Nz%s: fstat failed (%s)r$   z%s: write failed: %sz%s: fcntl failed: %sz"failed to rename "%s" to "%s" (%s)Tr   z failed to link "%s" as "%s" (%s)z%s: unlink failed (%s))$osgetpidr(   platformr   r   fatal_signaladd_file_to_unlinkopenfile_handleIOErrorr-   strerrorfstatfilenor*   flushOSErrorfcntllockfLOCK_EXLOCK_NBLOCK_SHadd_file_to_close_and_unlinkr   renamelinkerrnoEEXIST_check_already_runningEINTRunlink_file_nowst_dev_pidfile_devst_ino_pidfile_ino)pidtmpfileeserrorr   r   r   _make_pidfile   s   






rR   c                   C   s   t   t  dS )ztIf configured with set_pidfile() or set_detach(), creates the pid file
    and detaches from the foreground session.N)daemonize_startdaemonize_completer   r   r   r   	daemonize   s   
rU   c              
   C   sP   	 zt | |W S  ty' } z|jtjkr	 |j dfW  Y d }~S d }~ww )NTr   )r/   waitpidr;   rD   rG   )rM   optionsrO   r   r   r   _waitpid   s   rX   c               
   C   s  t jdkrt S zt \} }W n# ty3 } zt jdt|j	  t 
d W Y d }~nd }~ww zt }W n# ty] } zt jdt|j	  t 
d W Y d }~nd }~ww |dkrt| tj  	 z
t| d}d}W n ty } zd}|j	}W Y d }~nd }~ww |t	jkrnqmt|dkrt|d\}}||krt|rt|rt 
t| n$t jdtj|  n|dk sJ t jd	t|   t 
d t|  |S t|  tj  |a|S )
Nr   zpipe failed: %s
r%   zcould not fork: %s
r   Tr   z)fork child failed to signal startup (%s)
zwaitpid failed (%s)
)r(   r1   "_fork_and_wait_for_startup_windowsr/   piper;   r)   r*   r7   rD   r+   forkcloser   r2   readrG   lenrX   	WIFEXITEDWEXITSTATUSprocess
status_msgtimevalpostforkr   )rfdwfdrO   rM   rP   rQ   retvalstatusr   r   r   _fork_and_wait_for_startup   sd   



	





ri   c            
   
   C   sp  t r	tj  dS 	 t  zt \} }W n! tj	y7 } zt
jd|j  t
d W Y d }~nd }~ww z#tj}dt
jdt
jt|f }tj|dd|t
jt
jd}|j}W n# ty~ } zt
jdt|j  t
d W Y d }~nd }~ww tj| tj  t | d\}}|rd	}t!|dkr|" }	|	dkrt
jd
 nt
|	 tj|  |S )Nr   zpipe failed to create: %s
r%   z%s %s --pipe-handle=%ld F)args	close_fdsshellcreationflagsstdoutr)   zCreateProcess failed (%s)
r   z$fork child failed to signal startup
)#r   r   rc   rd   r&   close_log_filewinutilswindows_create_pipe
pywintypesrQ   r(   r)   r*   r7   r+   win32processDETACHED_PROCESS
executablejoinargvr   
subprocessPopenro   rM   r;   r/   rD   	win32fileCloseHandler2   r[   windows_read_piper^   wait)
re   rf   rO   creationFlagsrk   procrM   rQ   rP   rg   r   r   r   rY   *  sV   



rY   c                 C   s\   t jdkrt|  d S | d ur,tj| d\}}|r%t jd t d t	
|  d S d S )Nr   0zcould not write to pipe
r%   )r(   r1   _fork_notify_startup_windowsr   socket_utilwrite_fullyr)   r*   r+   r/   r\   )fdrQ   bytes_writtenr   r   r   _fork_notify_startup`  s   

r   c              
   C   sp   | d ur6zt j| dd  W d S  t jjy5 } ztjdt	|j
  td W Y d }~d S d }~ww d S )N   0zcould not write to pipe: %s
r%   )rq   r{   	WriteFilers   rQ   r(   r)   r*   r/   r7   winerrorr+   )r   rO   r   r   r   r   m  s   
r   c                 C   sr   t jdkr| d? }|tkrdS dS t| rt| tkrdS t| r7dD ]}t| tt	|d kr6 dS q&dS )Nr      TF)	SIGABRTSIGALRMSIGBUSSIGFPESIGILLSIGPIPESIGSEGVSIGXCPUSIGXFSZ)
r(   r1   RESTART_EXIT_CODEr/   r_   r`   WIFSIGNALEDWTERMSIGgetattrsignal)rh   exit_statussignamer   r   r   _should_restartz  s   

r   c                 C   sR  d }	 t | d\}}|dk rtjd td n|| krd| tj|f }t|rtj	dkrOt
|rOz	ttjd W n tjyN   td Y nw |d urtj |d	 k rtd
|  	 tj }|d	 }||krrntjd|| d   t|| d  qdtj }td|  t } | sd S ntd|  td q)NTr   zwaitpid failed
r%   zpid %d died, %sr   )r   r   zfailed to disable core dumpsi'  z/%s, waiting until 10 seconds since last restartz	sleep %f
g     @@z%s, restartingz%s, exiting)rX   r(   r)   r*   r+   r   ra   rb   r   r1   r/   	WCOREDUMPresource	setrlimitRLIMIT_CORErQ   r&   warnrc   msecro   timesleepr'   ri   info)
daemon_pidlast_restartrg   rh   rb   nowwakeupr   r   r   _monitor_daemon  sR   



r   c                  C   s>   t j } | dkrt| d t| d t| d dS dS )zClose stdin, stdout, stderr.  If we're started from e.g. an SSH session,
    then this keeps us from holding that session open artificially.r   r%      N)r   r   get_null_fdr/   dup2)null_fdr   r   r   _close_standard_fds  s   
r   c                  C   sr   t rt dkrtd tjdkrt  tr0t} t }|dkr0t	|  tjdkr,t
  t| tr7t  dS dS )aI  If daemonization is configured, then starts daemonization, by forking
    and returning in the child process.  The parent process hangs around until
    the child lets it know either that it completed startup successfully (by
    calling daemon_complete()) or that it failed to start up (by exiting with a
    nonzero exit code).r   r   N)r   ri   r(   r+   r1   r/   setsidr"   r   r   r   r   r   rR   )saved_daemonize_fdr   r   r   r   rS     s    




rS   c                   C   s(   t t trtrtd t  dS dS )zIf daemonization is configured, then this function notifies the parent
    process that the child process has completed startup successfully./N)r   r   r   r   r/   chdirr   r   r   r   r   rT     s   

rT   c                   C   s    t jdtjjtjjf  d S )Nz
Daemon options:
   --detach                run in background as daemon
   --no-chdir              do not chdir to '/'
   --pidfile[=FILE]        create pidfile (default: %s/%s.pid)
   --overwrite-pidfile     with --pidfile, start even if already running
)r(   ro   r*   r   r   r   r	   r
   r   r   r   r   usage  s   
r   c                 C   s  t d ur$zt| }|jtkr|jt krt W S W n	 ty#   Y nw zt| d}W n/ t	yZ } z#|j
t
jkrB|rBW Y d }~dS td| |jf  |j
 W  Y d }~S d }~ww zt|tjtjB  |sx|  td|   t
j W S zd}t| }t| }|j|jks|j|jkrd}W n t	y   d}Y nw |rtd|   t
j W S zt|  W n! t	y } ztd| |jf  |j
 W  Y d }~W S d }~ww td	|   |  W dS  t	y } z$|j
t
jt
jfvrtd
| |jf  |j
 W  Y d }~S W Y d }~nd }~ww zQzt| }W n5 t	yB } ztd| |jf  |j
 }W Y d }~nd }~w tyV   td|   t
j }Y nw |W z|  W S  t	yi   Y S w z|  W w  t	yz   Y w w )Nzr+r   z%s: open: %sz%s: pid file is staleFTz%s: lost race to delete pidfilez'%s: failed to delete stale pidfile (%s)z%s: deleted stale pidfilez%s: fcntl: %sz%s: read: %sz%s does not contain a pid) rJ   r/   statrK   rL   rI   r0   r;   r4   r6   rD   ENOENTr&   r   r7   r<   r=   r>   r?   r\   ESRCHr8   r9   EALREADYunlinkdbgEACCESEAGAINr   readline
ValueErrorEINVAL)pidfiledelete_if_stalerP   r5   rO   raceds2rQ   r   r   r   __read_pidfile  s   




r   c                 C   s
   t | dS )ztOpens and reads a PID from 'pidfile'.  Returns the positive PID if
    successful, otherwise a negative errno value.F)r   )r   r   r   r   read_pidfileO  s   
r   c                  C   sL   t td} | dkrtdt| f  d S | dk r$tdtt| f  d S d S )NTr   z'%s: already running as pid %d, abortingz'%s: pidfile check failed (%s), aborting)r   r   r-   r/   r7   )rM   r   r   r   rF   U  s   

rF   c                 C   s   t d}| jdd}|jdddd |jddd	d |jd
ddtjj d |jdd|d| d |jdddd tjdkrG|jddd dS dS )zPopulates 'parser', an ArgumentParser allocated using the argparse
    module, with the command line arguments required by the daemon module.NzDaemon Options)titlez--detach
store_truezRun in background as a daemon.)actionhelpz
--no-chdirzDo not chdir to '/'.z	--monitorzMonitor %s process.z	--pidfile?zCreate pidfile (default %s).)nargsconstr   z--overwrite-pidfilez.With --pidfile, start even if already running.r   z--pipe-handle)r   )r   add_argument_groupadd_argumentr   r	   r
   r(   r1   )parserr   groupr   r   r   add_args^  s,   



r   c                 C   sb   t jdkr| jrt| j | jrt  | jrt  | jr!t	| j | j
r't  | jr/t  dS dS )zHandles daemon module settings in 'args'.  'args' is an object
    containing values parsed by the parse_args() method of ArgumentParser.  The
    parent ArgumentParser should have been prepared by add_args() before
    calling parse_args().r   N)r(   r1   pipe_handler    detachr   no_chdirr   r   r   overwrite_pidfiler   monitorr#   )rk   r   r   r   handle_argsu  s   



r   )>rD   r/   r   r(   r   ovs.dirsr   ovs.fatal_signalovs.processovs.socket_utilovs.timevalovs.utilovs.vlogr1   r<   r   ovs.winutilsrq   ovs.fcntl_win	fcntl_winrs   ry   rt   r&   Vlogr   r   r   rJ   rL   r   r   r"   r   r   r   r   r   r   r   r    r!   r#   r-   rR   rU   rX   ri   rY   r   r   r   r   r   rS   rT   r   r   r   rF   r   r   r   r   r   r   <module>   st   

	
T
96/

Q	