unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
* how to kill child process?
       [not found] <2139767403.5164633.1598212258730.ref@mail.yahoo.com>
@ 2020-08-23 19:50 ` vapnik spaknik
  2020-08-23 20:31   ` Sebastian Miele
  2020-08-24 12:05   ` Sebastian Miele
  0 siblings, 2 replies; 11+ messages in thread
From: vapnik spaknik @ 2020-08-23 19:50 UTC (permalink / raw)
  To: guile users mailing list

Hi,
    I'm writing a backup script in guile, and want to run rsync several times over the same ssh connection.
From the shell command line I can start an ssh session with a control master socket, and then tell ssh to reuse that socket with each invocation of rsync:
> ssh -S ~/.ssh/%C -N -f remotehost &
> rsync -au -e "ssh -S ~/.ssh/%C remotehost" remotehost:file1 backupdir/file1
> rsync -au -e "ssh -S ~/.ssh/%C remotehost" remotehost:file2 backupdir/file2
and finally, find the pid and kill the ssh session:
> ps -e|grep ssh
> kill <PID>

To do the same thing in guile I tried the following:

(let ((pid (primitive-fork))) 
      (if (eq? 0 pid) 
          (execlp "ssh" "ssh" "-S" "~/.ssh/%C" "-N" "-f" "remotehost") 
          (begin (system "rsync -au -e \"ssh -S ~/.ssh/%C remotehost\" remotehost:file1 backupdir/file1")
                     (system "rsync -au -e \"ssh -S ~/.ssh/%C remotehost\" remotehost:file1 backupdir/file1")
                     (kill pid SIGTERM)))

However, this doesn't work because the pid returned by primitive-fork is the pid of the guile thread, not its child ssh process, and killing the guile thread doesn't kill its child process.
I don't want to run (system "kill ssh") because I might have other ssh processes running that I need to keep alive.

It might be possible for me to achieve the same end results using a tunnel with guile-ssh for this particular problem, but I would like to know how to solve the more general problem of killing a long-running child process in guile, since I will probably face this problem again at some point in the future.
Can anyone help me?

Joe Bloggs.



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: how to kill child process?
  2020-08-23 19:50 ` how to kill child process? vapnik spaknik
@ 2020-08-23 20:31   ` Sebastian Miele
  2020-08-23 23:08     ` Sebastian Miele
  2020-08-24 11:07     ` vapnik spaknik via General Guile related discussions
  2020-08-24 12:05   ` Sebastian Miele
  1 sibling, 2 replies; 11+ messages in thread
From: Sebastian Miele @ 2020-08-23 20:31 UTC (permalink / raw)
  To: vapnik spaknik; +Cc: guile-user

vapnik spaknik <vapniks@yahoo.com> writes:

>> ssh -S ~/.ssh/%C -N -f remotehost &
>> rsync -au -e "ssh -S ~/.ssh/%C remotehost" remotehost:file1 backupdir/file1
>> rsync -au -e "ssh -S ~/.ssh/%C remotehost" remotehost:file2 backupdir/file2
>
> and finally, find the pid and kill the ssh session:
>
>> ps -e|grep ssh
>> kill <PID>

This does not answer your exact question, but such behavior can be
acheived very automatically by putting something like the following into
~/.ssh/config:

  ControlMaster auto
  ControlPath ~/.ssh/socket/%C
  ControlPersist 5

This automatically creates master processes.  And the respective master
processes automatically terminate after 5 seconds.  See 'man 5
ssh_config'.

See "ControlMaster" in 'man 5 ssh_config' for a possible limitation:
"X11 and ssh-agent(1) forwarding is supported over these multi‐ plexed
connections, however the display and agent forwarded will be the one
belonging to the master connection i.e. it is not pos‐ sible to forward
multiple displays or agents."

But even then: ssh seems to have a '-o <option>'.  From 'man 1 ssh':
"This is useful for specifying options for which there is no separate
command-line flag."  So you do not even have to put it into the config
and can use it only on specific commands.

Best wishes
Sebastian



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: how to kill child process?
  2020-08-23 20:31   ` Sebastian Miele
@ 2020-08-23 23:08     ` Sebastian Miele
  2020-08-24 11:07     ` vapnik spaknik via General Guile related discussions
  1 sibling, 0 replies; 11+ messages in thread
From: Sebastian Miele @ 2020-08-23 23:08 UTC (permalink / raw)
  To: vapnik spaknik; +Cc: guile-user

Me:

> vapnik spaknik <vapniks@yahoo.com> writes:
>
> >> ssh -S ~/.ssh/%C -N -f remotehost &
> >> rsync -au -e "ssh -S ~/.ssh/%C remotehost" remotehost:file1
> backupdir/file1
> >> rsync -au -e "ssh -S ~/.ssh/%C remotehost" remotehost:file2
> backupdir/file2
> >
> > and finally, find the pid and kill the ssh session:
> >
> >> ps -e|grep ssh
> >> kill <PID>
>
> This does not answer your exact question, but such behavior can be
> acheived very automatically by putting something like the following into
> ~/.ssh/config:
>
>   ControlMaster auto
>   ControlPath ~/.ssh/socket/%C
>   ControlPersist 5
>
> This automatically creates master processes.


Or not, if there currently already is one, in which case that one is used.

And the respective master
> processes automatically terminate after 5 seconds.
>

After 5 seconds of being without at slave.

>


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: how to kill child process?
  2020-08-23 20:31   ` Sebastian Miele
  2020-08-23 23:08     ` Sebastian Miele
@ 2020-08-24 11:07     ` vapnik spaknik via General Guile related discussions
  1 sibling, 0 replies; 11+ messages in thread
From: vapnik spaknik via General Guile related discussions @ 2020-08-24 11:07 UTC (permalink / raw)
  To: Sebastian Miele; +Cc: guile-user

 

>This does not answer your exact question, but such behavior can be
>acheived very automatically by putting something like the following into
>~/.ssh/config:
>
>  ControlMaster auto
>  ControlPath ~/.ssh/socket/%C
>  ControlPersist 5
>
>This automatically creates master processes.  And the respective master
>processes automatically terminate after 5 seconds.  See 'man 5
>ssh_config'.

Yes, I'm aware of this, but I don't want to have to depend on the config file.

>But even then: ssh seems to have a '-o <option>'.  From 'man 1 ssh':
>"This is useful for specifying options for which there is no separate
>command-line flag."  So you do not even have to put it into the config
>and can use it only on specific commands.
>
>Best wishes
>Sebastian

OK thanks, I guess I could use '-o ControlPersist no' or run another ssh process with '-O exit' after running the rsync commands.
However, I'm still interested to know if there is a more general way of killing long-running child processes. Seems to me that this is quite a fundamentally important ability.  


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: how to kill child process?
  2020-08-23 19:50 ` how to kill child process? vapnik spaknik
  2020-08-23 20:31   ` Sebastian Miele
@ 2020-08-24 12:05   ` Sebastian Miele
  2020-08-24 13:15     ` vapnik spaknik via General Guile related discussions
  1 sibling, 1 reply; 11+ messages in thread
From: Sebastian Miele @ 2020-08-24 12:05 UTC (permalink / raw)
  To: vapnik spaknik; +Cc: guile-user

vapnik spaknik <vapniks@yahoo.com> writes:

> (execlp "ssh" "ssh" "-S" "~/.ssh/%C" "-N" "-f" "remotehost") 
>
> However, this doesn't work

The problem probably is the following: The above invocation of 'ssh'
with '-S' is the invocation of a slave.  It creates a master (with a new
PID).  After that it immediately exits ('-N').

Best wishes
Sebastian



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: how to kill child process?
  2020-08-24 12:05   ` Sebastian Miele
@ 2020-08-24 13:15     ` vapnik spaknik via General Guile related discussions
  2020-08-24 14:27       ` Sebastian Miele
  0 siblings, 1 reply; 11+ messages in thread
From: vapnik spaknik via General Guile related discussions @ 2020-08-24 13:15 UTC (permalink / raw)
  To: Sebastian Miele; +Cc: guile-user

 

>On Monday, August 24, 2020, 01:05:31 PM GMT+1, Sebastian Miele <sebastian.miele@gmail.com> wrote:

>vapnik spaknik <vapniks@yahoo.com> writes:

>> (execlp "ssh" "ssh" "-S" "~/.ssh/%C" "-N" "-f" "remotehost")
>>
>> However, this doesn't work


>The problem probably is the following: The above invocation of 'ssh'
>with '-S' is the invocation of a slave.  It creates a master (with a new
>PID).  After that it immediately exits ('-N').

Oops, I forgot to include the "-M" flag in the previous post. That ensures the ssh connection is a master connection, and I get the same problem.
  


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: how to kill child process?
  2020-08-24 13:15     ` vapnik spaknik via General Guile related discussions
@ 2020-08-24 14:27       ` Sebastian Miele
  2020-08-24 14:33         ` Sebastian Miele
  2020-08-24 16:51         ` vapnik spaknik via General Guile related discussions
  0 siblings, 2 replies; 11+ messages in thread
From: Sebastian Miele @ 2020-08-24 14:27 UTC (permalink / raw)
  To: vapnik spaknik; +Cc: guile-user

vapnik spaknik <vapniks@yahoo.com> writes:

> Oops, I forgot to include the "-M" flag in the previous post. That
> ensures the ssh connection is a master connection, and I get the same
> problem.

Look at output of the following:

  pkill ssh
  ssh -S '~/.ssh/socket/%C' -N -M -f <host> &
  echo $!
  pgrep -a ssh

Then look at the output of:

  pkill ssh
  ssh -S '~/.ssh/socket/%C' -N -M <host> &
  echo $!
  pgrep -a ssh

Passing '-f' does make 'ssh' fork.

Not using '-f' does not make 'ssh' fork.  (At least the current 'ssh' on
my machine.  I do not know whether OpenSSH in any way guarantees that
behavior in the future.)



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: how to kill child process?
  2020-08-24 14:27       ` Sebastian Miele
@ 2020-08-24 14:33         ` Sebastian Miele
  2020-08-24 16:51         ` vapnik spaknik via General Guile related discussions
  1 sibling, 0 replies; 11+ messages in thread
From: Sebastian Miele @ 2020-08-24 14:33 UTC (permalink / raw)
  To: vapnik spaknik; +Cc: guile-user

Me:
> Look at output of the following:
>
>   pkill ssh
>   ssh -S '~/.ssh/socket/%C' -N -M -f <host> &
>   echo $!
>   pgrep -a ssh
>
> Then look at the output of:
>
>   pkill ssh
>   ssh -S '~/.ssh/socket/%C' -N -M <host> &
>   echo $!
>   pgrep -a ssh
>

For the tests I temporarily renamed my '~/.ssh/config', so that 'ssh'
runs without config file.  I do not know whether this is/was relevant.
I now see: 'ssh' has a '-F none' (do not use a config file).



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: how to kill child process?
  2020-08-24 14:27       ` Sebastian Miele
  2020-08-24 14:33         ` Sebastian Miele
@ 2020-08-24 16:51         ` vapnik spaknik via General Guile related discussions
  2020-08-24 18:47           ` Sebastian Miele
  1 sibling, 1 reply; 11+ messages in thread
From: vapnik spaknik via General Guile related discussions @ 2020-08-24 16:51 UTC (permalink / raw)
  To: Sebastian Miele; +Cc: guile-user

 

>On Monday, August 24, 2020, 03:27:57 PM GMT+1, Sebastian Miele <sebastian.miele@gmail.com> wrote:
>
>Look at output of the following:
>
>  pkill ssh
>  ssh -S '~/.ssh/socket/%C' -N -M -f <host> &
>  echo $!
>  pgrep -a ssh
>
>Then look at the output of:
>
> pkill ssh
>  ssh -S '~/.ssh/socket/%C' -N -M <host> &
>  echo $!
>  pgrep -a ssh
>
>Passing '-f' does make 'ssh' fork.
>
>Not using '-f' does not make 'ssh' fork.  (At least the current 'ssh' on
>my machine.  I do not know whether OpenSSH in any way guarantees that
>behavior in the future.)

Even without the '-f' flag I still get the same problem in guile.
If I print the pid of the child process I can see that it is different from the pid of the ssh process.  


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: how to kill child process?
  2020-08-24 16:51         ` vapnik spaknik via General Guile related discussions
@ 2020-08-24 18:47           ` Sebastian Miele
  2020-08-25 18:21             ` vapnik spaknik via General Guile related discussions
  0 siblings, 1 reply; 11+ messages in thread
From: Sebastian Miele @ 2020-08-24 18:47 UTC (permalink / raw)
  To: vapnik spaknik; +Cc: guile-user

vapnik spaknik <vapniks@yahoo.com> writes:
>
> Even without the '-f' flag I still get the same problem in guile.  If
> I print the pid of the child process I can see that it is different
> from the pid of the ssh process.

When I put

  (let ((pid  (primitive-fork))
        (host         THE-HOST)
        (control   "~/.ssh/%C"))
    (if (eq? 0 pid)
        (execlp "ssh" "ssh"
                "-F" "none"
                "-S" control
                "-N" "-M"
                host)
        (begin
          (display pid)
          (sleep 3600))))

into a file '0.scm' and run it using, e.g., 'guile 0.scm' (tested with
Guile 3.0.4, 2.2.6, and 1.8.8), and after that run 'pgrep -a ssh' in
another terminal, I do get the same PIDs.

So everything is as expected here.  (Apart from that, somehow the single
'ssh' child of the Guile process gets killed automatically when the
Guile process gets killed.  I do not exactly know why.  This may very
well be reliable behaviour prescribed by POSIX.)

It is really, really unlikely that Guile is the culprit of the
unexpected behavior that you describe.  Think about it this way: How
likely is it to introduce such a bug in a wrapper for 'execvp'?  It
would have to be really convoluted relative to the quite simple way that
such a wrapper (almost certainly) can be written.

However, if you can become really, really sure, that Guile in fact is
the culprit (try AT LEAST something like '(execlp "sleep" "1234")'
instead of '(execlp "ssh" ...)' before):

What system?  What version of Guile?

I am running recent Arch Linux x86_64.

Best wishes
Sebastian



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: how to kill child process?
  2020-08-24 18:47           ` Sebastian Miele
@ 2020-08-25 18:21             ` vapnik spaknik via General Guile related discussions
  0 siblings, 0 replies; 11+ messages in thread
From: vapnik spaknik via General Guile related discussions @ 2020-08-25 18:21 UTC (permalink / raw)
  To: Sebastian Miele; +Cc: guile-user

 On Monday, August 24, 2020, 07:47:42 PM GMT+1, Sebastian Miele <sebastian.miele@gmail.com> wrote:

>When I put
>
>  (let ((pid  (primitive-fork))
>        (host        THE-HOST)
>        (control  "~/.ssh/%C"))
>    (if (eq? 0 pid)
>        (execlp "ssh" "ssh"
>                "-F" "none"
>                "-S" control
>                "-N" "-M"
>                host)
>        (begin
>          (display pid)
>          (sleep 3600))))
>
>into a file '0.scm' and run it using, e.g., 'guile 0.scm' (tested with
>Guile 3.0.4, 2.2.6, and 1.8.8), and after that run 'pgrep -a ssh' in
>another terminal, I do get the same PIDs.

OK, I think I've found the problem; I have firejail installed, so when I run ssh it actually runs firejail, which in turn runs ssh as a child process, and so the pid reported by guile doesn't match the pid of the ssh process.
If I replace "ssh" with "/usr/bin/ssh" they match. 

Thanks for your help.  


^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2020-08-25 18:21 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <2139767403.5164633.1598212258730.ref@mail.yahoo.com>
2020-08-23 19:50 ` how to kill child process? vapnik spaknik
2020-08-23 20:31   ` Sebastian Miele
2020-08-23 23:08     ` Sebastian Miele
2020-08-24 11:07     ` vapnik spaknik via General Guile related discussions
2020-08-24 12:05   ` Sebastian Miele
2020-08-24 13:15     ` vapnik spaknik via General Guile related discussions
2020-08-24 14:27       ` Sebastian Miele
2020-08-24 14:33         ` Sebastian Miele
2020-08-24 16:51         ` vapnik spaknik via General Guile related discussions
2020-08-24 18:47           ` Sebastian Miele
2020-08-25 18:21             ` vapnik spaknik via General Guile related discussions

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).