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

Eric Blake eblake at redhat.com
Thu Aug 16 23:07:31 UTC 2012


On 08/09/2012 09:20 AM, Daniel P. Berrange wrote:
> From: "Daniel P. Berrange" <berrange at 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 at 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
bug...

> +
> +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 at redhat.com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 620 bytes
Desc: OpenPGP digital signature
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20120816/d8b635d5/attachment-0001.sig>


More information about the libvir-list mailing list