On Fri, Feb 20, 2009 at 02:38:05PM +0000, Daniel P. Berrange wrote: > I think we need to move place where we set the exec context to after > the fork() call, ideally to be the very last call made before the > actual execve(). > > We do not currently have an easy way todo this, but I have the exact > same problem in my patches to integrate with cgroups - I need to add > the new PID to the appropriate cgroup immediately before exec'ing. > So i suggest the following patch whichs a generic callback to the > virExec() call, so we can implant the neccessary logic after the fork() > and just before the real execve(), and safely in the child process. > > To use this, we'd make qemudStartVM() pass in a virExecHook callback > which does the call to qemudDomainSetSecurityLabel() I've committed this patch to CVS now. > diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms > --- a/src/libvirt_private.syms > +++ b/src/libvirt_private.syms > @@ -291,6 +291,7 @@ virEnumToString; > virEventAddHandle; > virEventRemoveHandle; > virExec; > +virExecWithHook; > virSetNonBlock; > virFormatMacAddr; > virGetHostname; > diff --git a/src/util.c b/src/util.c > --- a/src/util.c > +++ b/src/util.c > @@ -199,7 +199,10 @@ __virExec(virConnectPtr conn, > const fd_set *keepfd, > pid_t *retpid, > int infd, int *outfd, int *errfd, > - int flags) { > + int flags, > + virExecHook hook, > + void *data) > +{ > pid_t pid; > int null, i, openmax; > int pipeout[2] = {-1,-1}; > @@ -411,6 +414,9 @@ __virExec(virConnectPtr conn, > childerr != childout) > close(childerr); > > + if (hook) > + (hook)(data); > + > if (envp) > execve(argv[0], (char **) argv, (char**)envp); > else > @@ -445,13 +451,16 @@ __virExec(virConnectPtr conn, > } > > int > -virExec(virConnectPtr conn, > - const char *const*argv, > - const char *const*envp, > - const fd_set *keepfd, > - pid_t *retpid, > - int infd, int *outfd, int *errfd, > - int flags) { > +virExecWithHook(virConnectPtr conn, > + const char *const*argv, > + const char *const*envp, > + const fd_set *keepfd, > + pid_t *retpid, > + int infd, int *outfd, int *errfd, > + int flags, > + virExecHook hook, > + void *data) > +{ > char *argv_str; > > if ((argv_str = virArgvToString(argv)) == NULL) { > @@ -462,7 +471,21 @@ virExec(virConnectPtr conn, > VIR_FREE(argv_str); > > return __virExec(conn, argv, envp, keepfd, retpid, infd, outfd, errfd, > - flags); > + flags, hook, data); > +} > + > +int > +virExec(virConnectPtr conn, > + const char *const*argv, > + const char *const*envp, > + const fd_set *keepfd, > + pid_t *retpid, > + int infd, int *outfd, int *errfd, > + int flags) > +{ > + return virExecWithHook(conn, argv, envp, keepfd, retpid, > + infd, outfd, errfd, > + flags, NULL, NULL); > } > > static int > @@ -580,7 +603,7 @@ virRun(virConnectPtr conn, > > if ((execret = __virExec(conn, argv, NULL, NULL, > &childpid, -1, &outfd, &errfd, > - VIR_EXEC_NONE)) < 0) { > + VIR_EXEC_NONE, NULL, NULL)) < 0) { > ret = execret; > goto error; > } > diff --git a/src/util.h b/src/util.h > --- a/src/util.h > +++ b/src/util.h > @@ -40,6 +40,21 @@ enum { > > int virSetNonBlock(int fd); > > +/* This will execute in the context of the first child > + * immediately after fork() */ > +typedef int (*virExecHook)(void *data); > + > +int virExecWithHook(virConnectPtr conn, > + const char *const*argv, > + const char *const*envp, > + const fd_set *keepfd, > + int *retpid, > + int infd, > + int *outfd, > + int *errfd, > + int flags, > + virExecHook hook, > + void *data); > int virExec(virConnectPtr conn, > const char *const*argv, > const char *const*envp, > > Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :| -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list