[libvirt] [PATCH 08/10] Introduce new APIs for spawning processes

Daniel P. Berrange berrange at redhat.com
Tue Nov 23 10:06:01 UTC 2010


On Mon, Nov 22, 2010 at 03:30:35PM -0700, Eric Blake wrote:
> On 11/19/2010 05:16 PM, Eric Blake wrote:
> > On 11/18/2010 02:55 AM, Daniel P. Berrange wrote:
> >> On Wed, Nov 17, 2010 at 09:29:00PM -0700, Eric Blake wrote:
> >>> From: Daniel P. Berrange <berrange at redhat.com>
> >>>
> >>> This introduces a new set of APIs in src/util/command.h
> >>> to use for invoking commands. This is intended to replace
> >>> all current usage of virRun and virExec variants, with a
> >>> more flexible and less error prone API.
> >>>
> >>
> >>
> >> My code forgot to ever close() the fds in cmd->preserve. We definitely
> >> need todo it in virCommandFree(), but there's a small argument to say
> >> we should also do it in virCommandRun/virCommandRunAsync so that if
> >> the caller keeps the virCommandPtr alive for a long time, we don't
> >> have the open FDs.
> > 
> > I'll look into this more.
> 
> On thinking about this more, I'm thinking that the user should be able
> to request whether the fd remains open after the command has been
> executed (for example, the client may want to share an fd among multiple
> child processes, in which case each virCommandRun must not close the
> fd); doable by adding another argument to virCommandPreserveFD.
> 
> > 
> >>
> >> It would also be useful to have a generic API for logging info about
> >> the command to an FD (to let us remove that logging code from UML
> >> and QEMU & LXC drivers).
> >>
> >> eg
> >>
> >> +void virCommandWriteArgLog(virCommandPtr cmd, int logfd)
> 
> Okay, I see how you added that in your variant in today's locking
> series, along with virCommandToString; now folded into my v2.

Ah yes, I forgot to mention that - it came in useful when
converting the QEMU driver to the new APIs.

> @@ -117,20 +121,25 @@ virCommandNewArgs(const char *const*args)
>  /*
>   * Preserve the specified file descriptor in the child, instead of
>   * closing it.  FD must not be one of the three standard streams.
> + * If transfer is true, then fd will be closed in the parent after
> + * a call to Run/RunAsync, otherwise caller is still responsible for fd.
>   */
>  void
> -virCommandPreserveFD(virCommandPtr cmd, int fd)
> +virCommandPreserveFD(virCommandPtr cmd, int fd, bool transfer)

How about having two separate methods ?

  virCommandPreserveFD
  virCommandTransferFD

Means you don't have to remember whether true means transfer
or don't transfer 

> @@ -868,6 +961,13 @@ virCommandRunAsync(virCommandPtr cmd, pid_t *pid)
>      VIR_DEBUG("Command result %d, with PID %d",
>                ret, (int)cmd->pid);
> 
> +    for (i = STDERR_FILENO + 1; i < FD_SETSIZE; i++) {
> +        if (FD_ISSET(i, &cmd->transfer)) {
> +            int tmpfd = i;
> +            VIR_FORCE_CLOSE(tmpfd);
> +        }
> +    }
> +
>      if (ret == 0 && pid)
>          *pid = cmd->pid;

I think we also need duplicate this in virCommandFree(), because
there may be scenarios where we get 1/2 way through populating
a virCommandPtr instance, and then some other error means we have
to stop & free it, without ever getting to virCommandRunAsync.

Daniel




More information about the libvir-list mailing list