Re: [libvirt] PATCH: 5/5: Make all code use virExec

2008-08-29 Thread Jim Meyering
Daniel P. Berrange [EMAIL PROTECTED] wrote:
...
 +/* Like virFileReadLimFP, but use a file descriptor rather than a FILE*.  */
 +int __virFileReadLimFD(int fd_arg, int maxlen, char **buf)
 +{
 +int fd = dup (fd_arg);
 +if (0 = fd) {

 Can we stick to 'fd = 0' or 'fd  0' or 'fd == -1'. I find
 the reversed constant-first conditionals rather painful to read.
 Always have to stop and think about them for too long.

Sure.  I've just adjusted it like this:

-if (0 = fd) {
+if (fd = 0) {

--
Libvir-list mailing list
Libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] PATCH: 5/5: Make all code use virExec

2008-08-20 Thread Jim Meyering
Daniel P. Berrange [EMAIL PROTECTED] wrote:
 This final patch switches over all places which do fork()/exec() to use the
 new enhanced virExec() code. A fair amount of code is deleted, but that's
 not the whole story - the new impl is more robust that most of the existing
 code we're deleting here.

Nice clean-up!

 diff -r 2591ebc40bd7 src/bridge.c
...
 @@ -680,7 +645,10 @@

  argv[n++] = NULL;

 -retval = brctlSpawn(argv);
 +if (virRun(NULL, argv, NULL)  0)
 +retval = errno;

Using errno here isn't always kosher, since _virExec doesn't always
preserve it when things go wrong (the ReportError call and close
calls after cleanup: can clobber errno).
But one can argue that it doesn't matter too much, since virExec
does diagnose each failure.  However, that would suggest not
using errno upon virRun failure.

...
 -retval = brctlSpawn(argv);
 +if (virRun(NULL, argv, NULL)  0)
 +retval = errno;

Likewise.

...
 diff -r 2591ebc40bd7 src/qemu_conf.c
 --- a/src/qemu_conf.c Tue Aug 12 15:29:29 2008 +0100
 +++ b/src/qemu_conf.c Tue Aug 12 15:33:42 2008 +0100
 @@ -397,116 +397,88 @@


  int qemudExtractVersionInfo(const char *qemu, int *version, int *flags) {
 +const char *const qemuarg[] = { qemu, -help, NULL };
 +const char *const qemuenv[] = { LANG=C, NULL };

If you have to use just one environment variable, use LC_ALL=C.
It trumps all others, when it comes to locale-related things.

  pid_t child;
 -int newstdout[2];
 +int newstdout = -1;
 +char help[8192]; /* Ought to be enough to hold QEMU help screen */
 +int got = 0, ret = -1, status;
 +int major, minor, micro;
 +int ver;

If you make the above 4 variables unsigned
and adjust the %d formats accordingly, the version
parsing will be a little tighter.

  if (flags)
  *flags = 0;
  if (version)
  *version = 0;

 -if (pipe(newstdout)  0) {
 +if (virExec(NULL, qemuarg, qemuenv, child,
 +-1, newstdout, NULL, VIR_EXEC_NONE)  0)
  return -1;
 +
 +
 +while (got  (sizeof(help)-1)) {
 +int len;
 +if ((len = read(newstdout, help+got, sizeof(help)-got-1)) = 0) {
 +if (!len)
 +break;
 +if (errno == EINTR)
 +continue;
 +goto cleanup2;
 +}
 +got += len;
 +}

Any reason not to use saferead in place of this while-loop?

 +help[got] = '\0';
 +
 +if (sscanf(help, QEMU PC emulator version %d.%d.%d, major,minor, 
 micro) != 3) {
 +goto cleanup2;
  }

 -if ((child = fork())  0) {
 -close(newstdout[0]);
 -close(newstdout[1]);
 -return -1;
 +ver = (major * 1000 * 1000) + (minor * 1000) + micro;
 +if (version)
 +*version = ver;
 +if (flags) {
 +if (strstr(help, -no-kqemu))
 +*flags |= QEMUD_CMD_FLAG_KQEMU;
 +if (strstr(help, -no-reboot))
 +*flags |= QEMUD_CMD_FLAG_NO_REBOOT;
 +if (strstr(help, -name))
 +*flags |= QEMUD_CMD_FLAG_NAME;
 +if (strstr(help, -drive))
 +*flags |= QEMUD_CMD_FLAG_DRIVE;
 +if (strstr(help, boot=on))
 +*flags |= QEMUD_CMD_FLAG_DRIVE_BOOT;
 +if (ver = 9000)
 +*flags |= QEMUD_CMD_FLAG_VNC_COLON;
 +}
 +ret = 0;
 +
 +qemudDebug(Version %d %d %d  Cooked version: %d, with flags ? %d,

If version can really be NULL, as the above if (version) tests
suggest, then you'll want to change *version here, to e.g.,
version ? *version : NA

Same for *flags.

 +   major, minor, micro, *version, *flags);
 +
 +cleanup2:
 +if (close(newstdout)  0)
 +ret = -1;
 +
 +rewait:
 +if (waitpid(child, status, 0) != child) {
 +if (errno == EINTR)
 +goto rewait;
 +
 +qemudLog(QEMUD_ERR,
 + _(Unexpected exit status from qemu %d pid %lu),
 + status, (unsigned long)child);

You've probably already fixed this, but status here is a
combination of exit status and signal number.

 +ret = -1;
 +}
 +/* Check  log unexpected exit status, but don't fail,
 + * as there's really no need to throw an error if we did
 + * actually read a valid version number above */
 +if (WEXITSTATUS(status) != 0) {
 +qemudLog(QEMUD_WARN,
 + _(Unexpected exit status '%d', qemu probably failed),
 + status);
  }
...
  int qemudExtractVersion(virConnectPtr conn,
 diff -r 2591ebc40bd7 src/remote_internal.c
 --- a/src/remote_internal.c   Tue Aug 12 15:29:29 2008 +0100
 +++ b/src/remote_internal.c   Tue Aug 12 15:33:42 2008 +0100
 @@ -72,6 +72,7 @@
  #include remote_internal.h
  #include remote_protocol.h
  #include memory.h
 +#include util.h

  #define DEBUG(fmt,...) VIR_DEBUG(__FILE__, fmt,__VA_ARGS__)
  #define DEBUG0(msg) VIR_DEBUG(__FILE__, %s, msg)
 @@ -221,61 +222,21 @@
  remoteForkDaemon(virConnectPtr conn)
  {
  const char 

Re: [libvirt] PATCH: 5/5: Make all code use virExec

2008-08-13 Thread Daniel P. Berrange
This final patch switches over all places which do fork()/exec() to use the
new enhanced virExec() code. A fair amount of code is deleted, but that's
not the whole story - the new impl is more robust that most of the existing
code we're deleting here.

 bridge.c  |   51 +++-
 proxy_internal.c  |   25 +---
 qemu_conf.c   |  168 ++
 remote_internal.c |   88 
 4 files changed, 100 insertions(+), 232 deletions(-)


Daniel

diff -r 2591ebc40bd7 src/bridge.c
--- a/src/bridge.c  Tue Aug 12 15:29:29 2008 +0100
+++ b/src/bridge.c  Tue Aug 12 15:33:42 2008 +0100
@@ -46,6 +46,7 @@
 
 #include internal.h
 #include memory.h
+#include util.h
 
 #define MAX_BRIDGE_ID 256
 
@@ -596,42 +597,6 @@
 return brGetInetAddr(ctl, ifname, SIOCGIFNETMASK, addr, maxlen);
 }
 
-static int
-brctlSpawn(char * const *argv)
-{
-pid_t pid, ret;
-int status;
-int null = -1;
-
-if ((null = open(_PATH_DEVNULL, O_RDONLY))  0)
-return errno;
-
-pid = fork();
-if (pid == -1) {
-int saved_errno = errno;
-close(null);
-return saved_errno;
-}
-
-if (pid == 0) { /* child */
-dup2(null, STDIN_FILENO);
-dup2(null, STDOUT_FILENO);
-dup2(null, STDERR_FILENO);
-close(null);
-
-execvp(argv[0], argv);
-
-_exit (1);
-}
-
-close(null);
-
-while ((ret = waitpid(pid, status, 0) == -1)  errno == EINTR);
-if (ret == -1)
-return errno;
-
-return (WIFEXITED(status)  WEXITSTATUS(status) == 0) ? 0 : EINVAL;
-}
 
 /**
  * brSetForwardDelay:
@@ -649,7 +614,7 @@
   const char *bridge,
   int delay)
 {
-char **argv;
+const char **argv;
 int retval = ENOMEM;
 int n;
 char delayStr[30];
@@ -680,7 +645,10 @@
 
 argv[n++] = NULL;
 
-retval = brctlSpawn(argv);
+if (virRun(NULL, argv, NULL)  0)
+retval = errno;
+else
+retval = 0;
 
  error:
 if (argv) {
@@ -709,7 +677,7 @@
const char *bridge,
int enable)
 {
-char **argv;
+const char **argv;
 int retval = ENOMEM;
 int n;
 
@@ -737,7 +705,10 @@
 
 argv[n++] = NULL;
 
-retval = brctlSpawn(argv);
+if (virRun(NULL, argv, NULL)  0)
+retval = errno;
+else
+retval = 0;
 
  error:
 if (argv) {
diff -r 2591ebc40bd7 src/proxy_internal.c
--- a/src/proxy_internal.c  Tue Aug 12 15:29:29 2008 +0100
+++ b/src/proxy_internal.c  Tue Aug 12 15:33:42 2008 +0100
@@ -162,6 +162,7 @@
 {
 const char *proxyPath = virProxyFindServerPath();
 int ret, pid, status;
+const char *proxyarg[2];
 
 if (!proxyPath) {
 fprintf(stderr, failed to find libvirt_proxy\n);
@@ -171,27 +172,11 @@
 if (debug)
 fprintf(stderr, Asking to launch %s\n, proxyPath);
 
-/* Become a daemon */
-pid = fork();
-if (pid == 0) {
-long open_max;
-long i;
+proxyarg[0] = proxyPath;
+proxyarg[1] = NULL;
 
-/* don't hold open fd opened from the client of the library */
-open_max = sysconf (_SC_OPEN_MAX);
-for (i = 0; i  open_max; i++)
-fcntl (i, F_SETFD, FD_CLOEXEC);
-
-setsid();
-if (fork() == 0) {
-execl(proxyPath, proxyPath, NULL);
-fprintf(stderr, _(failed to exec %s\n), proxyPath);
-}
-/*
- * calling exit() generate troubles for termination handlers
- */
-_exit(0);
-}
+if (virExec(NULL, proxyarg, NULL, pid, -1, NULL, NULL, VIR_EXEC_DAEMON)  
0)
+fprintf(stderr, Failed to fork libvirt_proxy\n);
 
 /*
  * do a waitpid on the intermediate process to avoid zombies.
diff -r 2591ebc40bd7 src/qemu_conf.c
--- a/src/qemu_conf.c   Tue Aug 12 15:29:29 2008 +0100
+++ b/src/qemu_conf.c   Tue Aug 12 15:33:42 2008 +0100
@@ -397,116 +397,88 @@
 
 
 int qemudExtractVersionInfo(const char *qemu, int *version, int *flags) {
+const char *const qemuarg[] = { qemu, -help, NULL };
+const char *const qemuenv[] = { LANG=C, NULL };
 pid_t child;
-int newstdout[2];
+int newstdout = -1;
+char help[8192]; /* Ought to be enough to hold QEMU help screen */
+int got = 0, ret = -1, status;
+int major, minor, micro;
+int ver;
 
 if (flags)
 *flags = 0;
 if (version)
 *version = 0;
 
-if (pipe(newstdout)  0) {
+if (virExec(NULL, qemuarg, qemuenv, child,
+-1, newstdout, NULL, VIR_EXEC_NONE)  0)
 return -1;
+
+
+while (got  (sizeof(help)-1)) {
+int len;
+if ((len = read(newstdout, help+got, sizeof(help)-got-1)) = 0) {
+if (!len)
+break;
+if (errno == EINTR)
+continue;
+goto cleanup2;
+}
+got += len;
+}
+help[got] = '\0';
+
+if (sscanf(help, QEMU PC emulator version %d.%d.%d,