[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Re: [libvirt] [PATCH 12/23] Add JSON serialization of virLockSpacePtr objects for process re-exec()

On 08/09/2012 09:20 AM, Daniel P. Berrange wrote:
> From: "Daniel P. Berrange" <berrange redhat com>
> Add two new APIs virLockSpaceNewPostExecRestart and
> virLockSpacePreExecRestart which allow a virLockSpacePtr
> object to be created from a JSON object and saved to a
> JSON object, for the purposes of re-exec'ing a process.
> As well as saving the state in JSON format, the second
> method will disable the O_CLOEXEC flag so that the open
> file descriptors are preserved across the process re-exec()
> Signed-off-by: Daniel P. Berrange <berrange redhat com>
> ---

Is virLockSpacePreExecRestart called in the parent prior to forking
(mostly good, with one caveat) or in the child between fork and exec
(bad, since you malloc and do a lot of other non-async-safe stuff)?  If
the latter, we risk deadlock; if the former, then you have at least one

> +
> +virLockSpacePtr virLockSpaceNewPostExecRestart(virJSONValuePtr object)
> +{
> +    virLockSpacePtr lockspace;
> +    virJSONValuePtr resources;
> +    int n;
> +    size_t i;
> +
> +    VIR_DEBUG("object=%p", object);

Would it be any better to pretty-print the contents of object instead of
just listing its address?

> +        if (virJSONValueObjectGetNumberInt(child, "fd", &res->fd) < 0) {
> +            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> +                           _("Missing resource fd in JSON document"));
> +            virLockSpaceResourceFree(res);
> +            goto error;
> +        }
> +        if (virSetInherit(res->fd, false) < 0) {
> +            virReportSystemError(errno, "%s",
> +                                 _("Cannot enable close-on-exec flag"));
> +            goto error;

Is the reparse loop called while the exec'd process is still
single-threaded, so as to avoid any races with the fds that are not yet
re-marked CLOEXEC?

> +
> +virJSONValuePtr virLockSpacePreExecRestart(virLockSpacePtr lockspace)
> +{

> +
> +        if (virSetInherit(res->fd, true) < 0) {
> +            virReportSystemError(errno, "%s",
> +                                 _("Cannot disable close-on-exec flag"));
> +            goto error;
> +        }

...clearing O_CLOEXEC in the parent is wrong.  You cannot clear
O_CLOEXEC until you are in the child (so as not to leak into any other
child process spawned by another thread), which really means that you
have to use virCommandPreserveFD instead of virSetInherit (virCommand
will then call virSetInherit in the child, between fork and exec, on
your behalf).  But that makes it sound like you need to pass a
virCommandPtr in to this function, in addition to the lockspace.

Overall, looks like a mostly sane serialization - simpler than coding it
up in XML, and still robust to pass between parent and child, but you do
need to solve the CLOEXEC safety issues.

Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org

Attachment: signature.asc
Description: OpenPGP digital signature

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]