[libvirt] PATCH: 10/25: Remove use of strerror()

Daniel P. Berrange berrange at redhat.com
Tue Jan 20 12:46:11 UTC 2009


On Mon, Jan 19, 2009 at 11:40:56AM +0100, Jim Meyering wrote:
> "Daniel P. Berrange" <berrange at redhat.com> wrote:
> > The strerror() method is not guarenteed to be re-entrant, which is
> > rather a pain because the strerror_r() method is rather unpleasant
> ...
> 
> Good work.
> A couple of small problems and a question:
> 
> ...
> > @@ -614,8 +618,9 @@ int main(int argc, char *argv[])
> >
> >          if (pid > 0) {
> >              if ((rc = virFileWritePid(LXC_STATE_DIR, name, pid)) != 0) {
> > -                fprintf(stderr, _("Unable to write pid file: %s\n"),
> > -                        strerror(rc));
> > +                virReportSystemError(NULL, errno,
> > +                                     _("Unable to write pid file '%s/%s.pid'"),
> > +                                     LXC_STATE_DIR, name);
> >                  _exit(1);
> >              }
> >
> 
> Looks like that should be "rc", not "errno".
> 
> ...
> > @@ -471,9 +474,9 @@ networkAddMasqueradingIptablesRules(virC
> >                                           network->def->network,
> >                                           network->def->bridge,
> >                                           network->def->forwardDev))) {
> > -        networkReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
> > -                         _("failed to add iptables rule to allow forwarding to '%s' : %s\n"),
> > -                         network->def->bridge, strerror(err));
> > +        virReportSystemError(conn, err,
> > +                             _("failed to add iptables rule to allow forwarding to '%s'"),
> > +                             network->def->bridge);
> >          goto masqerr2;
> >      }
> >
> 
> There's a stray trailing newline, above.
> Obviously it was there before your changes, too.
> 
> ...
> > @@ -3455,23 +3452,23 @@ static int qemudDomainSetAutostart(virDo
> >              int err;
> >
> >              if ((err = virFileMakePath(driver->autostartDir))) {
> > -                qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
> > -                                 _("cannot create autostart directory %s: %s"),
> > -                                 driver->autostartDir, strerror(err));
> > +                virReportSystemError(dom->conn, errno,
> > +                                     _("cannot create autostart directory %s"),
> > +                                     driver->autostartDir);
> 
> I think you want to retain the use of "err", above,
> since virFileMakePath maps a missing / to EINVAL.
> 
> > diff --git a/src/remote_internal.c b/src/remote_internal.c
> > diff --git a/src/storage_conf.c b/src/storage_conf.c
> > --- a/src/storage_conf.c
> > +++ b/src/storage_conf.c
> > @@ -43,6 +43,8 @@
> >  #include "util.h"
> >  #include "memory.h"
> >
> > +#define VIR_FROM_THIS VIR_FROM_STORAGE
> > +
> >  /* Work around broken limits.h on debian etch */
> >  #if defined __GNUC__ && defined _GCC_LIMITS_H_ && ! defined ULLONG_MAX
> >  # define ULLONG_MAX   ULONG_LONG_MAX
> > @@ -1405,9 +1407,9 @@ virStoragePoolObjSaveDef(virConnectPtr c
> >          char path[PATH_MAX];
> >
> >          if ((err = virFileMakePath(driver->configDir))) {
> > -            virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
> > -                                  _("cannot create config directory %s: %s"),
> > -                                  driver->configDir, strerror(err));
> > +            virStorageReportError(conn, errno,
> > +                                  _("cannot create config directory %s"),
> > +                                  driver->configDir);
> 
> Same here.
> 
> Incidentally, virFileMakePath will have to go, eventually.  Not only
> is it recursive in the number of components of the name being created,
> but allocating PATH_MAX for each stack frame is very wasteful, and might
> make it easy to blow the stack/DoS -- if there's a way to make libvirtd
> call it with an abusive argument.  Worst still, it creates directories
> with mkdir(path, 0777).  No virFileMakePath caller is careful to chmod
> _all_ of the possibly-just-created directories, and even if they all were,
> there'd still be a race.

I'm not sure about the mkdir 0777 mode - it will be modulated by the
process umask which will typically be  002 (regular user) or 022 (root).
It may be worth checking the callers of this to see if this will be a
problem or not.

As for the stack/recursion issue, the impl is fairly naive. It can be
trivially re-written to do one single strdup() of the incoming path,
and then implement the whole thing using iteration instead of recursion.

Finally, the malicious user supplied data issue - reasonably sure we
only use directories based off getpwuid / /etc/libvirt/libvirtd.conf
and don't allow user to supply arbitrary paths, but again worth checking
the callers.

> > diff --git a/src/test.c b/src/test.c
> ...
> > @@ -336,7 +339,7 @@ static int testOpenFromFile(virConnectPt
> >      virDomainObjPtr dom;
> >      testConnPtr privconn;
> >      if (VIR_ALLOC(privconn) < 0) {
> > -        testError(NULL, VIR_ERR_NO_MEMORY, "testConn");
> > +        virReportOOMError(conn);
> 
> I don't remember the rules for NULL vs non-NULL conn.
> Is this s/NULL/conn/ transform valid?
> I think there's one more like it.

Here is an update with the fixes you mention in this mail, and 
re-diffed based on latest CVS.

Daniel

diff --git a/.x-sc_avoid_write b/.x-sc_avoid_write
--- a/.x-sc_avoid_write
+++ b/.x-sc_avoid_write
@@ -1,4 +1,5 @@
 ^src/util\.c$
 ^src/xend_internal\.c$
 ^src/util-lib\.c$
+^qemud/qemud.c$
 ^gnulib/
diff --git a/autobuild.sh b/autobuild.sh
--- a/autobuild.sh
+++ b/autobuild.sh
@@ -65,6 +65,7 @@ if [ -x /usr/bin/i686-pc-mingw32-gcc ]; 
     --build=$(uname -m)-pc-linux \
     --host=i686-pc-mingw32 \
     --prefix="$AUTOBUILD_INSTALL_ROOT/i686-pc-mingw32/sys-root/mingw" \
+    --enable-compile-warnings=error \
     --without-sasl \
     --without-avahi \
     --without-polkit \
diff --git a/configure.in b/configure.in
--- a/configure.in
+++ b/configure.in
@@ -74,6 +74,9 @@ AC_SYS_LARGEFILE
 dnl Availability of various common functions (non-fatal if missing).
 AC_CHECK_FUNCS([cfmakeraw regexec uname sched_getaffinity getuid getgid])
 
+dnl Availability of various not common threadsafe functions
+AC_CHECK_FUNCS([strerror_r])
+
 dnl Availability of various common headers (non-fatal if missing).
 AC_CHECK_HEADERS([pwd.h paths.h regex.h sys/syslimits.h sys/utsname.h sys/wait.h winsock2.h sched.h termios.h sys/poll.h syslog.h])
 
diff --git a/po/POTFILES.in b/po/POTFILES.in
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -38,6 +38,7 @@ src/virsh.c
 src/virterror.c
 src/xen_inotify.c
 src/xen_internal.c
+src/xen_unified.c
 src/xend_internal.c
 src/xm_internal.c
 src/xml.c
diff --git a/src/domain_conf.c b/src/domain_conf.c
--- a/src/domain_conf.c
+++ b/src/domain_conf.c
@@ -40,6 +40,8 @@
 #include "buf.h"
 #include "c-ctype.h"
 
+#define VIR_FROM_THIS VIR_FROM_DOMAIN
+
 VIR_ENUM_IMPL(virDomainVirt, VIR_DOMAIN_VIRT_LAST,
               "qemu",
               "kqemu",
@@ -1913,8 +1915,7 @@ static virDomainDefPtr virDomainDefParse
         int err;
         if ((err = virUUIDGenerate(def->uuid))) {
             virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                                 _("Failed to generate UUID: %s"),
-                                 strerror(err));
+                                 "%s", _("Failed to generate UUID"));
             goto error;
         }
     } else {
@@ -3404,33 +3405,33 @@ int virDomainSaveXML(virConnectPtr conn,
         goto cleanup;
 
     if ((err = virFileMakePath(configDir))) {
-        virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                              _("cannot create config directory %s: %s"),
-                             configDir, strerror(err));
+        virReportSystemError(conn, errno,
+                             _("cannot create config directory '%s'"),
+                             configDir);
         goto cleanup;
     }
 
     if ((fd = open(configFile,
                    O_WRONLY | O_CREAT | O_TRUNC,
                    S_IRUSR | S_IWUSR )) < 0) {
-        virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                             _("cannot create config file %s: %s"),
-                             configFile, strerror(errno));
+        virReportSystemError(conn, errno,
+                             _("cannot create config file '%s'"),
+                             configFile);
         goto cleanup;
     }
 
     towrite = strlen(xml);
     if (safewrite(fd, xml, towrite) < 0) {
-        virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                             _("cannot write config file %s: %s"),
-                             configFile, strerror(errno));
+        virReportSystemError(conn, errno,
+                             _("cannot write config file '%s'"),
+                             configFile);
         goto cleanup;
     }
 
     if (close(fd) < 0) {
-        virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                             _("cannot save config file %s: %s"),
-                             configFile, strerror(errno));
+        virReportSystemError(conn, errno,
+                             _("cannot save config file '%s'"),
+                             configFile);
         goto cleanup;
     }
 
@@ -3529,9 +3530,9 @@ int virDomainLoadAllConfigs(virConnectPt
     if (!(dir = opendir(configDir))) {
         if (errno == ENOENT)
             return 0;
-        virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                              _("Failed to open dir '%s': %s"),
-                              configDir, strerror(errno));
+        virReportSystemError(conn, errno,
+                             _("Failed to open dir '%s'"),
+                             configDir);
         return -1;
     }
 
@@ -3583,9 +3584,9 @@ int virDomainDeleteConfig(virConnectPtr 
 
     if (unlink(configFile) < 0 &&
         errno != ENOENT) {
-        virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                             _("cannot remove config for %s: %s"),
-                             dom->def->name, strerror(errno));
+        virReportSystemError(conn, errno,
+                             _("cannot remove config %s"),
+                             configFile);
         goto cleanup;
     }
 
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -321,6 +321,8 @@ virUUIDParse;
 virReportErrorHelper;
 virErrorMsg;
 virRaiseError;
+virReportSystemErrorFull;
+virReportOOMErrorFull;
 
 
 # xml.h
diff --git a/src/lxc_container.c b/src/lxc_container.c
--- a/src/lxc_container.c
+++ b/src/lxc_container.c
@@ -48,6 +48,8 @@
 #include "memory.h"
 #include "veth.h"
 
+#define VIR_FROM_THIS VIR_FROM_LXC
+
 /*
  * GLibc headers are behind the kernel, so we define these
  * constants if they're not present already.
@@ -118,14 +120,14 @@ static int lxcContainerSetStdio(int cont
     int open_max, i;
 
     if (setsid() < 0) {
-        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("setsid failed: %s"), strerror(errno));
+        virReportSystemError(NULL, errno, "%s",
+                             _("setsid failed"));
         goto cleanup;
     }
 
     if (ioctl(ttyfd, TIOCSCTTY, NULL) < 0) {
-        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("ioctl(TIOCSTTY) failed: %s"), strerror(errno));
+        virReportSystemError(NULL, errno, "%s",
+                             _("ioctl(TIOCSTTY) failed"));
         goto cleanup;
     }
 
@@ -137,20 +139,20 @@ static int lxcContainerSetStdio(int cont
             close(i);
 
     if (dup2(ttyfd, 0) < 0) {
-        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("dup2(stdin) failed: %s"), strerror(errno));
+        virReportSystemError(NULL, errno, "%s",
+                             _("dup2(stdin) failed"));
         goto cleanup;
     }
 
     if (dup2(ttyfd, 1) < 0) {
-        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("dup2(stdout) failed: %s"), strerror(errno));
+        virReportSystemError(NULL, errno, "%s",
+                             _("dup2(stdout) failed"));
         goto cleanup;
     }
 
     if (dup2(ttyfd, 2) < 0) {
-        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("dup2(stderr) failed: %s"), strerror(errno));
+        virReportSystemError(NULL, errno, "%s",
+                             _("dup2(stderr) failed"));
         goto cleanup;
     }
 
@@ -177,9 +179,8 @@ int lxcContainerSendContinue(int control
 
     writeCount = safewrite(control, &msg, sizeof(msg));
     if (writeCount != sizeof(msg)) {
-        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("unable to send container continue message: %s"),
-                 strerror(errno));
+        virReportSystemError(NULL, errno, "%s",
+                             _("unable to send container continue message"));
         goto error_out;
     }
 
@@ -207,9 +208,8 @@ static int lxcContainerWaitForContinue(i
     readLen = saferead(control, &msg, sizeof(msg));
     if (readLen != sizeof(msg) ||
         msg != LXC_CONTINUE_MSG) {
-        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("Failed to read the container continue message: %s"),
-                 strerror(errno));
+        virReportSystemError(NULL, errno, "%s",
+                             _("Failed to read the container continue message"));
         return -1;
     }
     close(control);
@@ -266,27 +266,28 @@ static int lxcContainerChildMountSort(co
 
 static int lxcContainerPivotRoot(virDomainFSDefPtr root)
 {
+    int rc;
     char *oldroot;
 
     /* First step is to ensure the new root itself is
        a mount point */
     if (mount(root->src, root->src, NULL, MS_BIND, NULL) < 0) {
-        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("failed to bind new root %s: %s"),
-                 root->src, strerror(errno));
+        virReportSystemError(NULL, errno,
+                             _("failed to bind new root %s"),
+                             root->src);
         return -1;
     }
 
     if (virAsprintf(&oldroot, "%s/.oldroot", root->src) < 0) {
-        lxcError(NULL, NULL, VIR_ERR_NO_MEMORY, NULL);
+        virReportOOMError(NULL);
         return -1;
     }
 
-    if (virFileMakePath(oldroot) < 0) {
+    if ((rc = virFileMakePath(oldroot)) < 0) {
         VIR_FREE(oldroot);
-        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("failed to create %s: %s"),
-                 oldroot, strerror(errno));
+        virReportSystemError(NULL, rc,
+                             _("failed to create %s"),
+                             oldroot);
         return -1;
     }
 
@@ -294,9 +295,9 @@ static int lxcContainerPivotRoot(virDoma
      * this and will soon be unmounted completely */
     if (pivot_root(root->src, oldroot) < 0) {
         VIR_FREE(oldroot);
-        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("failed to pivot root %s to %s: %s"),
-                 oldroot, root->src, strerror(errno));
+        virReportSystemError(NULL, errno,
+                             _("failed to pivot root %s to %s"),
+                             oldroot, root->src);
         return -1;
     }
     VIR_FREE(oldroot);
@@ -312,6 +313,7 @@ static int lxcContainerPivotRoot(virDoma
 static int lxcContainerPopulateDevices(void)
 {
     int i;
+    int rc;
     const struct {
         int maj;
         int min;
@@ -326,11 +328,14 @@ static int lxcContainerPopulateDevices(v
         { LXC_DEV_MAJ_MEMORY, LXC_DEV_MIN_URANDOM, 0666, "/dev/urandom" },
     };
 
-    if (virFileMakePath("/dev") < 0 ||
-        mount("none", "/dev", "tmpfs", 0, NULL) < 0) {
-        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("failed to mount /dev tmpfs for container: %s"),
-                 strerror(errno));
+    if ((rc = virFileMakePath("/dev")) < 0) {
+        virReportSystemError(NULL, rc, "%s",
+                             _("cannot create /dev/"));
+        return -1;
+    }
+    if (mount("none", "/dev", "tmpfs", 0, NULL) < 0) {
+        virReportSystemError(NULL, errno, "%s",
+                             _("failed to mount /dev tmpfs"));
         return -1;
     }
     /* Move old devpts into container, since we have to
@@ -339,12 +344,15 @@ static int lxcContainerPopulateDevices(v
        XXX This sucks, we need to figure out how to get our
        own private devpts for isolation
     */
-    if (virFileMakePath("/dev/pts") < 0 ||
-        mount("/.oldroot/dev/pts", "/dev/pts", NULL,
+    if ((rc = virFileMakePath("/dev/pts") < 0)) {
+        virReportSystemError(NULL, rc, "%s",
+                             _("cannot create /dev/pts"));
+        return -1;
+    }
+    if (mount("/.oldroot/dev/pts", "/dev/pts", NULL,
               MS_MOVE, NULL) < 0) {
-        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("failed to move /dev/pts into container: %s"),
-                 strerror(errno));
+        virReportSystemError(NULL, errno, "%s",
+                             _("failed to move /dev/pts into container"));
         return -1;
     }
 
@@ -353,9 +361,9 @@ static int lxcContainerPopulateDevices(v
         dev_t dev = makedev(devs[i].maj, devs[i].min);
         if (mknod(devs[i].path, 0, dev) < 0 ||
             chmod(devs[i].path, devs[i].mode)) {
-            lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                     _("failed to make device %s: %s"),
-                     devs[i].path, strerror(errno));
+            virReportSystemError(NULL, errno,
+                                 _("failed to make device %s"),
+                                 devs[i].path);
             return -1;
         }
     }
@@ -382,12 +390,19 @@ static int lxcContainerMountNewFS(virDom
             return -1;
         }
 
-        if (virFileMakePath(vmDef->fss[i]->dst) < 0 ||
-            mount(src, vmDef->fss[i]->dst, NULL, MS_BIND, NULL) < 0) {
+        if (virFileMakePath(vmDef->fss[i]->dst) < 0) {
+            virReportSystemError(NULL, errno,
+                                 _("failed to create %s"),
+                                 vmDef->fss[i]->dst);
             VIR_FREE(src);
-            lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                     _("failed to mount %s at %s for container: %s"),
-                     vmDef->fss[i]->src, vmDef->fss[i]->dst, strerror(errno));
+            return -1;
+        }
+        if (mount(src, vmDef->fss[i]->dst, NULL, MS_BIND, NULL) < 0) {
+            VIR_FREE(src);
+            virReportSystemError(NULL, errno,
+                                 _("failed to mount %s at %s"),
+                                 vmDef->fss[i]->src,
+                                 vmDef->fss[i]->dst);
             return -1;
         }
         VIR_FREE(src);
@@ -406,9 +421,8 @@ static int lxcContainerUnmountOldFS(void
     int i;
 
     if (!(procmnt = setmntent("/proc/mounts", "r"))) {
-        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("failed to read /proc/mounts: %s"),
-                 strerror(errno));
+        virReportSystemError(NULL, errno, "%s",
+                             _("failed to read /proc/mounts"));
         return -1;
     }
     while ((mntent = getmntent(procmnt)) != NULL) {
@@ -433,9 +447,9 @@ static int lxcContainerUnmountOldFS(void
 
     for (i = 0 ; i < nmounts ; i++) {
         if (umount(mounts[i]) < 0) {
-            lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                     _("failed to unmount %s: %s"),
-                     mounts[i], strerror(errno));
+            virReportSystemError(NULL, errno,
+                                 _("failed to unmount '%s'"),
+                                 mounts[i]);
             return -1;
         }
         VIR_FREE(mounts[i]);
@@ -458,9 +472,8 @@ static int lxcContainerSetupPivotRoot(vi
 
     if (virFileMakePath("/proc") < 0 ||
         mount("none", "/proc", "proc", 0, NULL) < 0) {
-        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("failed to mount /proc for container: %s"),
-                 strerror(errno));
+        virReportSystemError(NULL, errno, "%s",
+                             _("failed to mount /proc"));
         return -1;
     }
 
@@ -492,18 +505,18 @@ static int lxcContainerSetupExtraMounts(
                   NULL,
                   MS_BIND,
                   NULL) < 0) {
-            lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                     _("failed to mount %s at %s for container: %s"),
-                     vmDef->fss[i]->src, vmDef->fss[i]->dst, strerror(errno));
+            virReportSystemError(NULL, errno,
+                                 _("failed to mount %s at %s"),
+                                 vmDef->fss[i]->src,
+                                 vmDef->fss[i]->dst);
             return -1;
         }
     }
 
     /* mount /proc */
     if (mount("lxcproc", "/proc", "proc", 0, NULL) < 0) {
-        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("failed to mount /proc for container: %s"),
-                 strerror(errno));
+        virReportSystemError(NULL, errno, "%s",
+                             _("failed to mount /proc"));
         return -1;
     }
 
@@ -557,8 +570,9 @@ static int lxcContainerChild( void *data
 
     ttyfd = open(argv->ttyPath, O_RDWR|O_NOCTTY);
     if (ttyfd < 0) {
-        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("open(%s) failed: %s"), argv->ttyPath, strerror(errno));
+        virReportSystemError(NULL, errno,
+                             _("failed to open %s"),
+                             argv->ttyPath);
         return -1;
     }
 
@@ -618,8 +632,8 @@ int lxcContainerStart(virDomainDefPtr de
     DEBUG("clone() returned, %d", pid);
 
     if (pid < 0) {
-        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("clone() failed, %s"), strerror(errno));
+        virReportSystemError(NULL, errno, "%s",
+                             _("failed to run clone container"));
         return -1;
     }
 
diff --git a/src/lxc_controller.c b/src/lxc_controller.c
--- a/src/lxc_controller.c
+++ b/src/lxc_controller.c
@@ -45,6 +45,8 @@
 #include "util.h"
 #include "cgroup.h"
 
+#define VIR_FROM_THIS VIR_FROM_LXC
+
 struct cgroup_device_policy {
     char type;
     int major;
@@ -109,8 +111,8 @@ static int lxcSetContainerResources(virD
     rc = virCgroupAddTask(cgroup, getpid());
 out:
     if (rc != 0) {
-        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("Failed to set lxc resources: %s\n"), strerror(-rc));
+        virReportSystemError(NULL, -rc, "%s",
+                             _("Failed to set lxc resources"));
         virCgroupRemove(cgroup);
     }
 
@@ -135,9 +137,9 @@ static int lxcMonitorServer(const char *
     struct sockaddr_un addr;
 
     if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
-        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("failed to create server socket %s: %s"),
-                 sockpath, strerror(errno));
+        virReportSystemError(NULL, errno,
+                             _("failed to create server socket '%s'"),
+                             sockpath);
         goto error;
     }
 
@@ -147,15 +149,15 @@ static int lxcMonitorServer(const char *
     strncpy(addr.sun_path, sockpath, sizeof(addr.sun_path));
 
     if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
-        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("failed to bind server socket %s: %s"),
-                 sockpath, strerror(errno));
+        virReportSystemError(NULL, errno,
+                             _("failed to bind server socket '%s'"),
+                             sockpath);
         goto error;
     }
     if (listen(fd, 30 /* backlog */ ) < 0) {
-        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("failed to listen server socket %s: %s"),
-                 sockpath, strerror(errno));
+        virReportSystemError(NULL, errno,
+                             _("failed to listen server socket %s"),
+                             sockpath);
         goto error;
     }
 
@@ -187,14 +189,16 @@ static int lxcFdForward(int readFd, int 
             goto cleanup;
         }
 
-        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("read of fd %d failed: %s"), readFd, strerror(errno));
+        virReportSystemError(NULL, errno,
+                             _("read of fd %d failed"),
+                             readFd);
         goto cleanup;
     }
 
     if (1 != (safewrite(writeFd, buf, 1))) {
-        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("write to fd %d failed: %s"), writeFd, strerror(errno));
+        virReportSystemError(NULL, errno,
+                             _("write to fd %d failed"),
+                             writeFd);
         goto cleanup;
     }
 
@@ -244,8 +248,8 @@ static int lxcControllerMain(int monitor
     /* create the epoll fild descriptor */
     epollFd = epoll_create(2);
     if (0 > epollFd) {
-        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("epoll_create(2) failed: %s"), strerror(errno));
+        virReportSystemError(NULL, errno, "%s",
+                             _("epoll_create(2) failed"));
         goto cleanup;
     }
 
@@ -254,30 +258,30 @@ static int lxcControllerMain(int monitor
     epollEvent.events = EPOLLIN|EPOLLET;    /* edge triggered */
     epollEvent.data.fd = appPty;
     if (0 > epoll_ctl(epollFd, EPOLL_CTL_ADD, appPty, &epollEvent)) {
-        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("epoll_ctl(appPty) failed: %s"), strerror(errno));
+        virReportSystemError(NULL, errno, "%s",
+                             _("epoll_ctl(appPty) failed"));
         goto cleanup;
     }
     epollEvent.data.fd = contPty;
     if (0 > epoll_ctl(epollFd, EPOLL_CTL_ADD, contPty, &epollEvent)) {
-        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("epoll_ctl(contPty) failed: %s"), strerror(errno));
+        virReportSystemError(NULL, errno, "%s",
+                             _("epoll_ctl(contPty) failed"));
         goto cleanup;
     }
 
     epollEvent.events = EPOLLIN;
     epollEvent.data.fd = monitor;
     if (0 > epoll_ctl(epollFd, EPOLL_CTL_ADD, monitor, &epollEvent)) {
-        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("epoll_ctl(contPty) failed: %s"), strerror(errno));
+        virReportSystemError(NULL, errno, "%s",
+                             _("epoll_ctl(contPty) failed"));
         goto cleanup;
     }
 
     epollEvent.events = EPOLLHUP;
     epollEvent.data.fd = client;
     if (0 > epoll_ctl(epollFd, EPOLL_CTL_ADD, client, &epollEvent)) {
-        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("epoll_ctl(contPty) failed: %s"), strerror(errno));
+        virReportSystemError(NULL, errno, "%s",
+                             _("epoll_ctl(contPty) failed"));
         goto cleanup;
     }
 
@@ -296,14 +300,14 @@ static int lxcControllerMain(int monitor
                 epollEvent.events = EPOLLHUP;
                 epollEvent.data.fd = client;
                 if (0 > epoll_ctl(epollFd, EPOLL_CTL_ADD, client, &epollEvent)) {
-                    lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                             _("epoll_ctl(contPty) failed: %s"), strerror(errno));
+                    virReportSystemError(NULL, errno, "%s",
+                                         _("epoll_ctl(contPty) failed"));
                     goto cleanup;
                 }
             } else if (client != -1 && epollEvent.data.fd == client) {
                 if (0 > epoll_ctl(epollFd, EPOLL_CTL_DEL, client, &epollEvent)) {
-                    lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                             _("epoll_ctl(contPty) failed: %s"), strerror(errno));
+                    virReportSystemError(NULL, errno, "%s",
+                                         _("epoll_ctl(contPty) failed"));
                     goto cleanup;
                 }
                 close(client);
@@ -340,8 +344,8 @@ static int lxcControllerMain(int monitor
             }
 
             /* error */
-            lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                     _("epoll_wait() failed: %s"), strerror(errno));
+            virReportSystemError(NULL, errno, "%s",
+                                 _("epoll_wait() failed"));
             goto cleanup;
 
         }
@@ -438,16 +442,16 @@ lxcControllerRun(virDomainDefPtr def,
     pid_t container = -1;
 
     if (socketpair(PF_UNIX, SOCK_STREAM, 0, control) < 0) {
-        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("sockpair failed: %s"), strerror(errno));
+        virReportSystemError(NULL, errno, "%s",
+                             _("sockpair failed"));
         goto cleanup;
     }
 
     if (virFileOpenTty(&containerPty,
                        &containerPtyPath,
                        0) < 0) {
-        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("failed to allocate tty: %s"), strerror(errno));
+        virReportSystemError(NULL, errno, "%s",
+                             _("failed to allocate tty"));
         goto cleanup;
     }
 
@@ -528,18 +532,18 @@ int main(int argc, char *argv[])
 
         case 'n':
             if ((name = strdup(optarg)) == NULL) {
-                fprintf(stderr, "%s", strerror(errno));
+                virReportOOMError(NULL);
                 goto cleanup;
             }
             break;
 
         case 'v':
             if (VIR_REALLOC_N(veths, nveths+1) < 0) {
-                fprintf(stderr, "cannot allocate veths %s", strerror(errno));
+                virReportOOMError(NULL);
                 goto cleanup;
             }
             if ((veths[nveths++] = strdup(optarg)) == NULL) {
-                fprintf(stderr, "cannot allocate veth name %s", strerror(errno));
+                virReportOOMError(NULL);
                 goto cleanup;
             }
             break;
@@ -614,8 +618,9 @@ int main(int argc, char *argv[])
 
         if (pid > 0) {
             if ((rc = virFileWritePid(LXC_STATE_DIR, name, pid)) != 0) {
-                fprintf(stderr, _("Unable to write pid file: %s\n"),
-                        strerror(rc));
+                virReportSystemError(NULL, rc,
+                                     _("Unable to write pid file '%s/%s.pid'"),
+                                     LXC_STATE_DIR, name);
                 _exit(1);
             }
 
@@ -627,22 +632,22 @@ int main(int argc, char *argv[])
 
         /* Don't hold onto any cwd we inherit from libvirtd either */
         if (chdir("/") < 0) {
-            fprintf(stderr, _("Unable to change to root dir: %s\n"),
-                    strerror(errno));
+            virReportSystemError(NULL, errno, "%s",
+                                 _("Unable to change to root dir"));
             goto cleanup;
         }
 
         if (setsid() < 0) {
-            fprintf(stderr, _("Unable to become session leader: %s\n"),
-                    strerror(errno));
+            virReportSystemError(NULL, errno, "%s",
+                                 _("Unable to become session leader"));
             goto cleanup;
         }
     }
 
     /* Accept initial client which is the libvirtd daemon */
     if ((client = accept(monitor, NULL, 0)) < 0) {
-        fprintf(stderr, _("Failed connection from LXC driver: %s\n"),
-                strerror(errno));
+        virReportSystemError(NULL, errno, "%s",
+                             _("Failed connection from LXC driver"));
         goto cleanup;
     }
 
diff --git a/src/lxc_driver.c b/src/lxc_driver.c
--- a/src/lxc_driver.c
+++ b/src/lxc_driver.c
@@ -49,6 +49,8 @@
 #include "cgroup.h"
 
 
+#define VIR_FROM_THIS VIR_FROM_LXC
+
 static int lxcStartup(void);
 static int lxcShutdown(void);
 static lxc_driver_t *lxc_driver = NULL;
@@ -467,9 +469,9 @@ static int lxcVMCleanup(virConnectPtr co
         ; /* empty */
 
     if ((waitRc != vm->pid) && (errno != ECHILD)) {
-        lxcError(conn, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("waitpid failed to wait for container %d: %d %s"),
-                 vm->pid, waitRc, strerror(errno));
+        virReportSystemError(conn, errno,
+                             _("waitpid failed to wait for container %d: %d"),
+                             vm->pid, waitRc);
     }
 
     rc = 0;
@@ -579,17 +581,15 @@ static int lxcSetupInterfaces(virConnect
         }
 
         if (0 != (rc = brAddInterface(brctl, bridge, parentVeth))) {
-            lxcError(conn, NULL, VIR_ERR_INTERNAL_ERROR,
-                     _("failed to add %s device to %s: %s"),
-                     parentVeth,
-                     bridge,
-                     strerror(rc));
+            virReportSystemError(conn, rc,
+                                 _("failed to add %s device to %s"),
+                                 parentVeth, bridge);
             goto error_exit;
         }
 
         if (0 != (rc = vethInterfaceUpOrDown(parentVeth, 1))) {
-            lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                     _("failed to enable parent ns veth device: %d"), rc);
+            virReportSystemError(conn, rc, "%s",
+                                 _("failed to enable parent ns veth device"));
             goto error_exit;
         }
 
@@ -618,9 +618,8 @@ static int lxcMonitorClient(virConnectPt
     }
 
     if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
-        lxcError(conn, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("failed to create client socket: %s"),
-                 strerror(errno));
+        virReportSystemError(conn, errno, "%s",
+                             _("failed to create client socket"));
         goto error;
     }
 
@@ -629,9 +628,8 @@ static int lxcMonitorClient(virConnectPt
     strncpy(addr.sun_path, sockpath, sizeof(addr.sun_path));
 
     if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
-        lxcError(conn, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("failed to connect to client socket: %s"),
-                 strerror(errno));
+        virReportSystemError(conn, errno, "%s",
+                             _("failed to connect to client socket"));
         goto error;
     }
 
@@ -662,9 +660,9 @@ static int lxcVmTerminate(virConnectPtr 
 
     if (kill(vm->pid, signum) < 0) {
         if (errno != ESRCH) {
-            lxcError(conn, NULL, VIR_ERR_INTERNAL_ERROR,
-                     _("failed to kill pid %d: %s"),
-                     vm->pid, strerror(errno));
+            virReportSystemError(conn, errno,
+                                 _("failed to kill pid %d"),
+                                 vm->pid);
             return -1;
         }
     }
@@ -794,9 +792,9 @@ static int lxcControllerStart(virConnect
      */
     while ((rc = waitpid(child, &status, 0) == -1) && errno == EINTR);
     if (rc == -1) {
-        lxcError(conn, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("cannot wait for '%s': %s"),
-                 largv[0], strerror(errno));
+        virReportSystemError(conn, errno,
+                             _("cannot wait for '%s'"),
+                             largv[0]);
         goto cleanup;
     }
 
@@ -848,10 +846,10 @@ static int lxcVmStart(virConnectPtr conn
     unsigned int nveths = 0;
     char **veths = NULL;
 
-    if (virFileMakePath(driver->logDir) < 0) {
-        lxcError(conn, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("cannot create log directory %s: %s"),
-                 driver->logDir, strerror(rc));
+    if ((rc = virFileMakePath(driver->logDir)) < 0) {
+        virReportSystemError(conn, rc,
+                             _("cannot create log directory '%s'"),
+                             driver->logDir);
         return -1;
     }
 
@@ -863,9 +861,8 @@ static int lxcVmStart(virConnectPtr conn
 
     /* open parent tty */
     if (virFileOpenTty(&parentTty, &parentTtyPath, 1) < 0) {
-        lxcError(conn, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("failed to allocate tty: %s"),
-                 strerror(errno));
+        virReportSystemError(conn, errno, "%s",
+                             _("failed to allocate tty"));
         goto cleanup;
     }
     if (vm->def->console &&
@@ -887,9 +884,9 @@ static int lxcVmStart(virConnectPtr conn
 
     if ((logfd = open(logfile, O_WRONLY | O_TRUNC | O_CREAT,
              S_IRUSR|S_IWUSR)) < 0) {
-        lxcError(conn, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("failed to open %s: %s"), logfile,
-                 strerror(errno));
+        virReportSystemError(conn, errno,
+                             _("failed to open '%s'"),
+                             logfile);
         goto cleanup;
     }
 
@@ -907,9 +904,9 @@ static int lxcVmStart(virConnectPtr conn
 
     /* And get its pid */
     if ((rc = virFileReadPid(driver->stateDir, vm->def->name, &vm->pid)) != 0) {
-        lxcError(conn, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("Failed to read pid file %s/%s.pid: %s"),
-                 driver->stateDir, vm->def->name, strerror(rc));
+        virReportSystemError(conn, rc,
+                             _("Failed to read pid file %s/%s.pid"),
+                             driver->stateDir, vm->def->name);
         rc = -1;
         goto cleanup;
     }
@@ -1272,11 +1269,7 @@ static int lxcVersion(virConnectPtr conn
     int min;
     int rev;
 
-    if (uname(&ver) != 0) {
-        lxcError(conn, NULL, VIR_ERR_INTERNAL_ERROR,
-                 _("uname(): %s"), strerror(errno));
-        return -1;
-    }
+    uname(&ver);
 
     if (sscanf(ver.release, "%i.%i.%i", &maj, &min, &rev) != 3) {
         lxcError(conn, NULL, VIR_ERR_INTERNAL_ERROR,
diff --git a/src/network_conf.c b/src/network_conf.c
--- a/src/network_conf.c
+++ b/src/network_conf.c
@@ -43,6 +43,8 @@
 #include "buf.h"
 #include "c-ctype.h"
 
+#define VIR_FROM_THIS VIR_FROM_NETWORK
+
 VIR_ENUM_DECL(virNetworkForward)
 
 VIR_ENUM_IMPL(virNetworkForward,
@@ -332,7 +334,7 @@ virNetworkDefParseXML(virConnectPtr conn
         int err;
         if ((err = virUUIDGenerate(def->uuid))) {
             virNetworkReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                             _("Failed to generate UUID: %s"), strerror(err));
+                                  "%s", _("Failed to generate UUID"));
             goto error;
         }
     } else {
@@ -667,40 +669,40 @@ int virNetworkSaveConfig(virConnectPtr c
         goto cleanup;
 
     if ((err = virFileMakePath(configDir))) {
-        virNetworkReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                              _("cannot create config directory %s: %s"),
-                              configDir, strerror(err));
+        virReportSystemError(conn, err,
+                             _("cannot create config directory '%s'"),
+                             configDir);
         goto cleanup;
     }
 
     if ((err = virFileMakePath(autostartDir))) {
-        virNetworkReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                              _("cannot create autostart directory %s: %s"),
-                              autostartDir, strerror(err));
+        virReportSystemError(conn, err,
+                             _("cannot create autostart directory '%s'"),
+                             autostartDir);
         goto cleanup;
     }
 
     if ((fd = open(net->configFile,
                    O_WRONLY | O_CREAT | O_TRUNC,
                    S_IRUSR | S_IWUSR )) < 0) {
-        virNetworkReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                              _("cannot create config file %s: %s"),
-                              net->configFile, strerror(errno));
+        virReportSystemError(conn, errno,
+                             _("cannot create config file '%s'"),
+                             net->configFile);
         goto cleanup;
     }
 
     towrite = strlen(xml);
     if (safewrite(fd, xml, towrite) < 0) {
-        virNetworkReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                              _("cannot write config file %s: %s"),
-                              net->configFile, strerror(errno));
+        virReportSystemError(conn, errno,
+                             _("cannot write config file '%s'"),
+                             net->configFile);
         goto cleanup;
     }
 
     if (close(fd) < 0) {
-        virNetworkReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                              _("cannot save config file %s: %s"),
-                              net->configFile, strerror(errno));
+        virReportSystemError(conn, errno,
+                             _("cannot save config file '%s'"),
+                             net->configFile);
         goto cleanup;
     }
 
@@ -777,9 +779,9 @@ int virNetworkLoadAllConfigs(virConnectP
     if (!(dir = opendir(configDir))) {
         if (errno == ENOENT)
             return 0;
-        virNetworkReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                              _("Failed to open dir '%s': %s"),
-                              configDir, strerror(errno));
+        virReportSystemError(conn, errno,
+                             _("Failed to open dir '%s'"),
+                             configDir);
         return -1;
     }
 
@@ -821,9 +823,9 @@ int virNetworkDeleteConfig(virConnectPtr
     unlink(net->autostartLink);
 
     if (unlink(net->configFile) < 0) {
-        virNetworkReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                              _("cannot remove config for %s: %s"),
-                              net->def->name, strerror(errno));
+        virReportSystemError(conn, errno,
+                             _("cannot remove config file '%s'"),
+                             net->configFile);
         return -1;
     }
 
diff --git a/src/network_driver.c b/src/network_driver.c
--- a/src/network_driver.c
+++ b/src/network_driver.c
@@ -57,6 +57,9 @@
 #include "iptables.h"
 #include "bridge.h"
 
+
+#define VIR_FROM_THIS VIR_FROM_NETWORK
+
 /* Main driver state */
 struct network_driver {
     virMutex lock;
@@ -460,9 +463,9 @@ networkAddMasqueradingIptablesRules(virC
                                           network->def->network,
                                           network->def->bridge,
                                           network->def->forwardDev))) {
-        networkReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("failed to add iptables rule to allow forwarding from '%s' : %s\n"),
-                         network->def->bridge, strerror(err));
+        virReportSystemError(conn, err,
+                             _("failed to add iptables rule to allow forwarding from '%s'"),
+                             network->def->bridge);
         goto masqerr1;
     }
 
@@ -471,9 +474,9 @@ networkAddMasqueradingIptablesRules(virC
                                          network->def->network,
                                          network->def->bridge,
                                          network->def->forwardDev))) {
-        networkReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("failed to add iptables rule to allow forwarding to '%s' : %s\n"),
-                         network->def->bridge, strerror(err));
+        virReportSystemError(conn, err,
+                             _("failed to add iptables rule to allow forwarding to '%s'"),
+                             network->def->bridge);
         goto masqerr2;
     }
 
@@ -481,9 +484,9 @@ networkAddMasqueradingIptablesRules(virC
     if ((err = iptablesAddForwardMasquerade(driver->iptables,
                                             network->def->network,
                                             network->def->forwardDev))) {
-        networkReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("failed to add iptables rule to enable masquerading : %s\n"),
-                         strerror(err));
+        virReportSystemError(conn, err,
+                             _("failed to add iptables rule to enable masquerading to '%s'\n"),
+                             network->def->forwardDev ? network->def->forwardDev : NULL);
         goto masqerr3;
     }
 
@@ -513,9 +516,9 @@ networkAddRoutingIptablesRules(virConnec
                                           network->def->network,
                                           network->def->bridge,
                                           network->def->forwardDev))) {
-        networkReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("failed to add iptables rule to allow routing from '%s' : %s\n"),
-                         network->def->bridge, strerror(err));
+        virReportSystemError(conn, err,
+                             _("failed to add iptables rule to allow routing from '%s'"),
+                             network->def->bridge);
         goto routeerr1;
     }
 
@@ -524,9 +527,9 @@ networkAddRoutingIptablesRules(virConnec
                                          network->def->network,
                                          network->def->bridge,
                                          network->def->forwardDev))) {
-        networkReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("failed to add iptables rule to allow routing to '%s' : %s\n"),
-                         network->def->bridge, strerror(err));
+        virReportSystemError(conn, err,
+                             _("failed to add iptables rule to allow routing to '%s'"),
+                             network->def->bridge);
         goto routeerr2;
     }
 
@@ -557,31 +560,31 @@ networkAddIptablesRules(virConnectPtr co
 
     /* allow DHCP requests through to dnsmasq */
     if ((err = iptablesAddTcpInput(driver->iptables, network->def->bridge, 67))) {
-        networkReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("failed to add iptables rule to allow DHCP requests from '%s' : %s"),
-                         network->def->bridge, strerror(err));
+        virReportSystemError(conn, err,
+                             _("failed to add iptables rule to allow DHCP requests from '%s'"),
+                             network->def->bridge);
         goto err1;
     }
 
     if ((err = iptablesAddUdpInput(driver->iptables, network->def->bridge, 67))) {
-        networkReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("failed to add iptables rule to allow DHCP requests from '%s' : %s"),
-                         network->def->bridge, strerror(err));
+        virReportSystemError(conn, err,
+                             _("failed to add iptables rule to allow DHCP requests from '%s'"),
+                             network->def->bridge);
         goto err2;
     }
 
     /* allow DNS requests through to dnsmasq */
     if ((err = iptablesAddTcpInput(driver->iptables, network->def->bridge, 53))) {
-        networkReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("failed to add iptables rule to allow DNS requests from '%s' : %s"),
-                         network->def->bridge, strerror(err));
+        virReportSystemError(conn, err,
+                             _("failed to add iptables rule to allow DNS requests from '%s'"),
+                             network->def->bridge);
         goto err3;
     }
 
     if ((err = iptablesAddUdpInput(driver->iptables, network->def->bridge, 53))) {
-        networkReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("failed to add iptables rule to allow DNS requests from '%s' : %s"),
-                         network->def->bridge, strerror(err));
+        virReportSystemError(conn, err,
+                             _("failed to add iptables rule to allow DNS requests from '%s'"),
+                             network->def->bridge);
         goto err4;
     }
 
@@ -589,24 +592,24 @@ networkAddIptablesRules(virConnectPtr co
     /* Catch all rules to block forwarding to/from bridges */
 
     if ((err = iptablesAddForwardRejectOut(driver->iptables, network->def->bridge))) {
-        networkReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("failed to add iptables rule to block outbound traffic from '%s' : %s"),
-                         network->def->bridge, strerror(err));
+        virReportSystemError(conn, err,
+                             _("failed to add iptables rule to block outbound traffic from '%s'"),
+                             network->def->bridge);
         goto err5;
     }
 
     if ((err = iptablesAddForwardRejectIn(driver->iptables, network->def->bridge))) {
-        networkReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("failed to add iptables rule to block inbound traffic to '%s' : %s"),
-                         network->def->bridge, strerror(err));
+        virReportSystemError(conn, err,
+                             _("failed to add iptables rule to block inbound traffic to '%s'"),
+                             network->def->bridge);
         goto err6;
     }
 
     /* Allow traffic between guests on the same bridge */
     if ((err = iptablesAddForwardAllowCross(driver->iptables, network->def->bridge))) {
-        networkReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("failed to add iptables rule to allow cross bridge traffic on '%s' : %s"),
-                         network->def->bridge, strerror(err));
+        virReportSystemError(conn, err,
+                             _("failed to add iptables rule to allow cross bridge traffic on '%s'"),
+                             network->def->bridge);
         goto err7;
     }
 
@@ -711,15 +714,15 @@ static int networkStartNetworkDaemon(vir
     }
 
     if (!driver->brctl && (err = brInit(&driver->brctl))) {
-        networkReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("cannot initialize bridge support: %s"), strerror(err));
+        virReportSystemError(conn, err, "%s",
+                             _("cannot initialize bridge support"));
         return -1;
     }
 
     if ((err = brAddBridge(driver->brctl, &network->def->bridge))) {
-        networkReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("cannot create bridge '%s' : %s"),
-                         network->def->bridge, strerror(err));
+        virReportSystemError(conn, err,
+                             _("cannot create bridge '%s'"),
+                             network->def->bridge);
         return -1;
     }
 
@@ -732,25 +735,25 @@ static int networkStartNetworkDaemon(vir
 
     if (network->def->ipAddress &&
         (err = brSetInetAddress(driver->brctl, network->def->bridge, network->def->ipAddress))) {
-        networkReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("cannot set IP address on bridge '%s' to '%s' : %s"),
-                         network->def->bridge, network->def->ipAddress, strerror(err));
+        virReportSystemError(conn, err,
+                             _("cannot set IP address on bridge '%s' to '%s'"),
+                             network->def->bridge, network->def->ipAddress);
         goto err_delbr;
     }
 
     if (network->def->netmask &&
         (err = brSetInetNetmask(driver->brctl, network->def->bridge, network->def->netmask))) {
-        networkReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("cannot set netmask on bridge '%s' to '%s' : %s"),
-                         network->def->bridge, network->def->netmask, strerror(err));
+        virReportSystemError(conn, err,
+                             _("cannot set netmask on bridge '%s' to '%s'"),
+                             network->def->bridge, network->def->netmask);
         goto err_delbr;
     }
 
     if (network->def->ipAddress &&
         (err = brSetInterfaceUp(driver->brctl, network->def->bridge, 1))) {
-        networkReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("failed to bring the bridge '%s' up : %s"),
-                         network->def->bridge, strerror(err));
+        virReportSystemError(conn, err,
+                             _("failed to bring the bridge '%s' up"),
+                             network->def->bridge);
         goto err_delbr;
     }
 
@@ -759,8 +762,8 @@ static int networkStartNetworkDaemon(vir
 
     if (network->def->forwardType != VIR_NETWORK_FORWARD_NONE &&
         !networkEnableIpForwarding()) {
-        networkReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("failed to enable IP forwarding : %s"), strerror(err));
+        virReportSystemError(conn, errno, "%s",
+                             _("failed to enable IP forwarding"));
         goto err_delbr2;
     }
 
@@ -1249,23 +1252,23 @@ static int networkSetAutostart(virNetwor
             int err;
 
             if ((err = virFileMakePath(driver->networkAutostartDir))) {
-                networkReportError(net->conn, NULL, net, VIR_ERR_INTERNAL_ERROR,
-                                   _("cannot create autostart directory %s: %s"),
-                                   driver->networkAutostartDir, strerror(err));
+                virReportSystemError(net->conn, errno,
+                                     _("cannot create autostart directory '%s'"),
+                                     driver->networkAutostartDir);
                 goto cleanup;
             }
 
             if (symlink(network->configFile, network->autostartLink) < 0) {
-                networkReportError(net->conn, NULL, net, VIR_ERR_INTERNAL_ERROR,
-                                   _("Failed to create symlink '%s' to '%s': %s"),
-                                   network->autostartLink, network->configFile, strerror(errno));
+                virReportSystemError(net->conn, errno,
+                                     _("Failed to create symlink '%s' to '%s'"),
+                                     network->autostartLink, network->configFile);
                 goto cleanup;
             }
         } else {
             if (unlink(network->autostartLink) < 0 && errno != ENOENT && errno != ENOTDIR) {
-                networkReportError(net->conn, NULL, net, VIR_ERR_INTERNAL_ERROR,
-                                   _("Failed to delete symlink '%s': %s"),
-                                   network->autostartLink, strerror(errno));
+                virReportSystemError(net->conn, errno,
+                                     _("Failed to delete symlink '%s'"),
+                                     network->autostartLink);
                 goto cleanup;
             }
         }
diff --git a/src/nodeinfo.c b/src/nodeinfo.c
--- a/src/nodeinfo.c
+++ b/src/nodeinfo.c
@@ -45,6 +45,9 @@
 #include "util.h"
 #include "virterror_internal.h"
 
+
+#define VIR_FROM_THIS VIR_FROM_NONE
+
 #ifdef __linux__
 #define CPUINFO_PATH "/proc/cpuinfo"
 
@@ -135,12 +138,8 @@ int virNodeInfoPopulate(virConnectPtr co
 #ifdef HAVE_UNAME
     struct utsname info;
 
-    if (uname(&info) < 0) {
-        virRaiseError(conn, NULL, NULL, 0, VIR_ERR_INTERNAL_ERROR,
-                        VIR_ERR_ERROR, NULL, NULL, NULL, 0, 0,
-                        "cannot extract machine type %s", strerror(errno));
-        return -1;
-    }
+    uname(&info);
+
     strncpy(nodeinfo->model, info.machine, sizeof(nodeinfo->model)-1);
     nodeinfo->model[sizeof(nodeinfo->model)-1] = '\0';
 
@@ -155,9 +154,8 @@ int virNodeInfoPopulate(virConnectPtr co
     int ret;
     FILE *cpuinfo = fopen(CPUINFO_PATH, "r");
     if (!cpuinfo) {
-        virRaiseError(conn, NULL, NULL, 0, VIR_ERR_INTERNAL_ERROR,
-                        VIR_ERR_ERROR, NULL, NULL, NULL, 0, 0,
-                        "cannot open %s %s", CPUINFO_PATH, strerror(errno));
+        virReportSystemError(conn, errno,
+                             _("cannot open %s"), CPUINFO_PATH);
         return -1;
     }
     ret = linuxNodeInfoCPUPopulate(conn, cpuinfo, nodeinfo);
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -69,6 +69,8 @@
 #include "uuid.h"
 #include "domain_conf.h"
 
+#define VIR_FROM_THIS VIR_FROM_QEMU
+
 /* For storing short-lived temporary files. */
 #define TEMPDIR LOCAL_STATE_DIR "/cache/libvirt"
 
@@ -153,9 +155,7 @@ qemudLogFD(virConnectPtr conn, const cha
 
     if ((ret = snprintf(logfile, sizeof(logfile), "%s/%s.log", logDir, name))
         < 0 || ret >= sizeof(logfile)) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("failed to build logfile name %s/%s.log"),
-                         logDir, name);
+        virReportOOMError(conn);
         return -1;
     }
 
@@ -165,15 +165,14 @@ qemudLogFD(virConnectPtr conn, const cha
     else
         logmode |= O_APPEND;
     if ((fd = open(logfile, logmode, S_IRUSR | S_IWUSR)) < 0) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("failed to create logfile %s: %s"),
-                         logfile, strerror(errno));
+        virReportSystemError(conn, errno,
+                             _("failed to create logfile %s"),
+                             logfile);
         return -1;
     }
     if (qemudSetCloseExec(fd) < 0) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("Unable to set VM logfile close-on-exec flag %s"),
-                         strerror(errno));
+        virReportSystemError(conn, errno, "%s",
+                             _("Unable to set VM logfile close-on-exec flag"));
         close(fd);
         return -1;
     }
@@ -527,9 +526,9 @@ qemudReadMonitorOutput(virConnectPtr con
                 continue;
 
             if (errno != EAGAIN) {
-                qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                                 _("Failure while reading %s startup output: %s"),
-                                 what, strerror(errno));
+                virReportSystemError(conn, errno,
+                                     _("Failure while reading %s startup output"),
+                                     what);
                 return -1;
             }
 
@@ -540,9 +539,9 @@ qemudReadMonitorOutput(virConnectPtr con
                 return -1;
             } else if (ret == -1) {
                 if (errno != EINTR) {
-                    qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                                     _("Failure while reading %s startup output: %s"),
-                                     what, strerror(errno));
+                    virReportSystemError(conn, errno,
+                                         _("Failure while reading %s startup output"),
+                                         what);
                     return -1;
                 }
             } else {
@@ -867,9 +866,8 @@ qemudInitCpus(virConnectPtr conn,
     for (i = 0 ; i < vm->nvcpupids ; i++) {
         if (sched_setaffinity(vm->vcpupids[i],
                               sizeof(mask), &mask) < 0) {
-            qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                             _("failed to set CPU affinity %s"),
-                             strerror(errno));
+            virReportSystemError(conn, errno, "%s",
+                                 _("failed to set CPU affinity"));
             return -1;
         }
     }
@@ -964,9 +962,9 @@ static int qemudStartVMDaemon(virConnect
     }
 
     if (virFileMakePath(driver->logDir) < 0) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("cannot create log directory %s: %s"),
-                         driver->logDir, strerror(errno));
+        virReportSystemError(conn, errno,
+                             _("cannot create log directory %s"),
+                             driver->logDir);
         return -1;
     }
 
@@ -984,10 +982,9 @@ static int qemudStartVMDaemon(virConnect
      * in a sub-process so its hard to feed back a useful error
      */
     if (stat(emulator, &sb) < 0) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("Cannot find QEMU binary %s: %s"),
-                         emulator,
-                         strerror(errno));
+        virReportSystemError(conn, errno,
+                             _("Cannot find QEMU binary %s"),
+                             emulator);
         return -1;
     }
 
@@ -2252,9 +2249,9 @@ static int qemudDomainSave(virDomainPtr 
     }
 
     if (close(fd) < 0) {
-        qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
-                         _("unable to save file %s %s"),
-                         path, strerror(errno));
+        virReportSystemError(dom->conn, errno,
+                             _("unable to save file %s"),
+                             path);
         goto cleanup;
     }
     fd = -1;
@@ -2415,8 +2412,8 @@ qemudDomainPinVcpu(virDomainPtr dom,
 
     if (vm->vcpupids != NULL) {
         if (sched_setaffinity(vm->vcpupids[vcpu], sizeof(mask), &mask) < 0) {
-            qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_ARG,
-                             _("cannot set affinity: %s"), strerror(errno));
+            virReportSystemError(dom->conn, errno, "%s",
+                                 _("cannot set affinity"));
             goto cleanup;
         }
     } else {
@@ -2484,8 +2481,8 @@ qemudDomainGetVcpus(virDomainPtr dom,
                     CPU_ZERO(&mask);
 
                     if (sched_getaffinity(vm->vcpupids[v], sizeof(mask), &mask) < 0) {
-                        qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_ARG,
-                                         _("cannot get affinity: %s"), strerror(errno));
+                        virReportSystemError(dom->conn, errno, "%s",
+                                             _("cannot get affinity"));
                         goto cleanup;
                     }
 
@@ -3468,23 +3465,23 @@ static int qemudDomainSetAutostart(virDo
             int err;
 
             if ((err = virFileMakePath(driver->autostartDir))) {
-                qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
-                                 _("cannot create autostart directory %s: %s"),
-                                 driver->autostartDir, strerror(err));
+                virReportSystemError(dom->conn, err,
+                                     _("cannot create autostart directory %s"),
+                                     driver->autostartDir);
                 goto cleanup;
             }
 
             if (symlink(configFile, autostartLink) < 0) {
-                qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
-                                 _("Failed to create symlink '%s to '%s': %s"),
-                                 autostartLink, configFile, strerror(errno));
+                virReportSystemError(dom->conn, errno,
+                                     _("Failed to create symlink '%s to '%s'"),
+                                     autostartLink, configFile);
                 goto cleanup;
             }
         } else {
             if (unlink(autostartLink) < 0 && errno != ENOENT && errno != ENOTDIR) {
-                qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
-                                 _("Failed to delete symlink '%s': %s"),
-                                 autostartLink, strerror(errno));
+                virReportSystemError(dom->conn, errno,
+                                     _("Failed to delete symlink '%s'"),
+                                     autostartLink);
                 goto cleanup;
             }
         }
diff --git a/src/remote_internal.c b/src/remote_internal.c
--- a/src/remote_internal.c
+++ b/src/remote_internal.c
@@ -88,6 +88,8 @@
 #include "util.h"
 #include "event.h"
 
+#define VIR_FROM_THIS VIR_FROM_REMOTE
+
 #ifdef WIN32
 #define pipe(fds) _pipe(fds,4096, _O_BINARY)
 #endif
@@ -586,9 +588,9 @@ doRemoteOpen (virConnectPtr conn,
         }
 
         freeaddrinfo (res);
-        errorf (conn, VIR_ERR_SYSTEM_ERROR,
-                _("unable to connect to '%s': %s"),
-                priv->hostname, strerror (saved_errno));
+        virReportSystemError(conn, saved_errno,
+                             _("unable to connect to '%s'"),
+                             priv->hostname);
         goto failed;
 
        tcp_connected:
@@ -607,9 +609,9 @@ doRemoteOpen (virConnectPtr conn,
                 uid_t uid = getuid();
 
                 if (!(pw = getpwuid(uid))) {
-                    errorf (conn, VIR_ERR_SYSTEM_ERROR,
-                            _("unable to lookup user '%d': %s"),
-                            uid, strerror (errno));
+                    virReportSystemError(conn, errno,
+                                         _("unable to lookup user '%d'"),
+                                         uid);
                     goto failed;
                 }
 
@@ -641,9 +643,8 @@ doRemoteOpen (virConnectPtr conn,
       autostart_retry:
         priv->sock = socket (AF_UNIX, SOCK_STREAM, 0);
         if (priv->sock == -1) {
-            errorf (conn, VIR_ERR_SYSTEM_ERROR,
-                    _("unable to create socket %s"),
-                    strerror (errno));
+            virReportSystemError(conn, errno, "%s",
+                                 _("unable to create socket"));
             goto failed;
         }
         if (connect (priv->sock, (struct sockaddr *) &addr, sizeof addr) == -1) {
@@ -665,9 +666,9 @@ doRemoteOpen (virConnectPtr conn,
                     goto autostart_retry;
                 }
             }
-            errorf (conn, VIR_ERR_SYSTEM_ERROR,
-                    _("unable to connect to '%s': %s"),
-                    sockname, strerror (errno));
+            virReportSystemError(conn, errno,
+                                 _("unable to connect to '%s'"),
+                                 sockname);
             goto failed;
         }
 
@@ -725,9 +726,8 @@ doRemoteOpen (virConnectPtr conn,
          * to faff around with two file descriptors (a la 'pipe(2)').
          */
         if (socketpair (PF_UNIX, SOCK_STREAM, 0, sv) == -1) {
-            errorf (conn, VIR_ERR_SYSTEM_ERROR,
-                    _("unable to create socket pair %s"),
-                    strerror (errno));
+            virReportSystemError(conn, errno, "%s",
+                                 _("unable to create socket pair"));
             goto failed;
         }
 
@@ -754,16 +754,14 @@ doRemoteOpen (virConnectPtr conn,
     } /* switch (transport) */
 
     if (virSetNonBlock(priv->sock) < 0) {
-        errorf (conn, VIR_ERR_SYSTEM_ERROR,
-                _("unable to make socket non-blocking %s"),
-                strerror(errno));
+        virReportSystemError(conn, errno, "%s",
+                             _("unable to make socket non-blocking"));
         goto failed;
     }
 
     if (pipe(wakeupFD) < 0) {
-        errorf (conn, VIR_ERR_SYSTEM_ERROR,
-                _("unable to make pipe %s"),
-                strerror(errno));
+        virReportSystemError(conn, errno, "%s",
+                             _("unable to make pipe"));
         goto failed;
     }
     priv->wakeupReadFD = wakeupFD[0];
@@ -1004,9 +1002,9 @@ check_cert_file (virConnectPtr conn, con
 {
     struct stat sb;
     if (stat(file, &sb) < 0) {
-        errorf(conn, VIR_ERR_RPC,
-               _("Cannot access %s '%s': %s (%d)"),
-               type, file, strerror(errno), errno);
+        virReportSystemError(conn, errno,
+                             _("Cannot access %s '%s'"),
+                             type, file);
         return -1;
     }
     return 0;
@@ -1193,9 +1191,8 @@ verify_certificate (virConnectPtr conn A
     }
 
     if ((now = time(NULL)) == ((time_t)-1)) {
-        errorf (conn, VIR_ERR_SYSTEM_ERROR,
-                _("cannot get current time: %s"),
-                strerror (errno));
+        virReportSystemError(conn, errno, "%s",
+                             _("cannot get current time"));
         return -1;
     }
 
@@ -5180,10 +5177,8 @@ remoteAuthSASL (virConnectPtr conn, stru
     /* Get local address in form  IPADDR:PORT */
     salen = sizeof(sa);
     if (getsockname(priv->sock, (struct sockaddr*)&sa, &salen) < 0) {
-        virRaiseError (in_open ? NULL : conn, NULL, NULL, VIR_FROM_REMOTE,
-                         VIR_ERR_AUTH_FAILED, VIR_ERR_ERROR, NULL, NULL, NULL, 0, 0,
-                         _("failed to get sock address %d (%s)"),
-                         errno, strerror(errno));
+        virReportSystemError(in_open ? NULL : conn, errno, "%s",
+                             _("failed to get sock address"));
         goto cleanup;
     }
     if ((localAddr = addrToString(&sa, salen)) == NULL)
@@ -5192,10 +5187,8 @@ remoteAuthSASL (virConnectPtr conn, stru
     /* Get remote address in form  IPADDR:PORT */
     salen = sizeof(sa);
     if (getpeername(priv->sock, (struct sockaddr*)&sa, &salen) < 0) {
-        virRaiseError (in_open ? NULL : conn, NULL, NULL, VIR_FROM_REMOTE,
-                         VIR_ERR_AUTH_FAILED, VIR_ERR_ERROR, NULL, NULL, NULL, 0, 0,
-                         _("failed to get peer address %d (%s)"),
-                         errno, strerror(errno));
+        virReportSystemError(in_open ? NULL : conn, errno, "%s",
+                             _("failed to get peer address"));
         goto cleanup;
     }
     if ((remoteAddr = addrToString(&sa, salen)) == NULL)
@@ -5721,8 +5714,8 @@ processCallWrite(virConnectPtr conn,
             if (errno == EWOULDBLOCK)
                 return 0;
 
-            error (in_open ? NULL : conn,
-                   VIR_ERR_SYSTEM_ERROR, strerror (errno));
+            virReportSystemError(in_open ? NULL : conn, errno,
+                                 "%s", _("cannot send data"));
             return -1;
 
         }
@@ -5771,10 +5764,8 @@ processCallRead(virConnectPtr conn,
                 if (errno == EWOULDBLOCK)
                     return 0;
 
-                errorf (in_open ? NULL : conn,
-                        VIR_ERR_SYSTEM_ERROR,
-                        _("failed to read from socket %s"),
-                        strerror (errno));
+                virReportSystemError(in_open ? NULL : conn, errno,
+                                     "%s", _("cannot recv data"));
             } else {
                 errorf (in_open ? NULL : conn,
                         VIR_ERR_SYSTEM_ERROR,
diff --git a/src/storage_backend.c b/src/storage_backend.c
--- a/src/storage_backend.c
+++ b/src/storage_backend.c
@@ -62,6 +62,8 @@
 #endif
 
 
+#define VIR_FROM_THIS VIR_FROM_STORAGE
+
 static virStorageBackendPtr backends[] = {
 #if WITH_STORAGE_DIR
     &virStorageBackendDirectory,
@@ -104,9 +106,9 @@ virStorageBackendUpdateVolInfo(virConnec
     int ret, fd;
 
     if ((fd = open(vol->target.path, O_RDONLY)) < 0) {
-        virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                              _("cannot open volume '%s': %s"),
-                              vol->target.path, strerror(errno));
+        virReportSystemError(conn, errno,
+                             _("cannot open volume '%s'"),
+                             vol->target.path);
         return -1;
     }
 
@@ -163,9 +165,9 @@ virStorageBackendUpdateVolInfoFD(virConn
 #endif
 
     if (fstat(fd, &sb) < 0) {
-        virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                              _("cannot stat file '%s': %s"),
-                              vol->target.path, strerror(errno));
+        virReportSystemError(conn, errno,
+                             _("cannot stat file '%s'"),
+                             vol->target.path);
         return -1;
     }
 
@@ -195,9 +197,9 @@ virStorageBackendUpdateVolInfoFD(virConn
          */
         end = lseek(fd, 0, SEEK_END);
         if (end == (off_t)-1) {
-            virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                                  _("cannot seek to end of file '%s':%s"),
-                                  vol->target.path, strerror(errno));
+            virReportSystemError(conn, errno,
+                                 _("cannot seek to end of file '%s'"),
+                                 vol->target.path);
             return -1;
         }
         vol->allocation = end;
@@ -215,16 +217,16 @@ virStorageBackendUpdateVolInfoFD(virConn
 
         start = lseek(fd, 0, SEEK_SET);
         if (start < 0) {
-            virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                                  _("cannot seek to beginning of file '%s':%s"),
-                                  vol->target.path, strerror(errno));
+            virReportSystemError(conn, errno,
+                                 _("cannot seek to beginning of file '%s'"),
+                                 vol->target.path);
             return -1;
         }
         bytes = saferead(fd, buffer, sizeof(buffer));
         if (bytes < 0) {
-            virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                                  _("cannot read beginning of file '%s':%s"),
-                                  vol->target.path, strerror(errno));
+            virReportSystemError(conn, errno,
+                                 _("cannot read beginning of file '%s'"),
+                                 vol->target.path);
             return -1;
         }
 
@@ -248,9 +250,9 @@ virStorageBackendUpdateVolInfoFD(virConn
 #if HAVE_SELINUX
     if (fgetfilecon(fd, &filecon) == -1) {
         if (errno != ENODATA && errno != ENOTSUP) {
-            virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                                  _("cannot get file context of %s: %s"),
-                                  vol->target.path, strerror(errno));
+            virReportSystemError(conn, errno,
+                                 _("cannot get file context of '%s'"),
+                                 vol->target.path);
             return -1;
         } else {
             vol->target.perms.label = NULL;
@@ -258,7 +260,7 @@ virStorageBackendUpdateVolInfoFD(virConn
     } else {
         vol->target.perms.label = strdup(filecon);
         if (vol->target.perms.label == NULL) {
-            virStorageReportError(conn, VIR_ERR_NO_MEMORY, "%s", _("context"));
+            virReportOOMError(conn);
             return -1;
         }
         freecon(filecon);
@@ -341,10 +343,9 @@ virStorageBackendStablePath(virConnectPt
             usleep(100 * 1000);
             goto reopen;
         }
-        virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                              _("cannot read dir %s: %s"),
-                              pool->def->target.path,
-                              strerror(errno));
+        virReportSystemError(conn, errno,
+                             _("cannot read dir '%s'"),
+                             pool->def->target.path);
         return NULL;
     }
 
@@ -359,7 +360,7 @@ virStorageBackendStablePath(virConnectPt
 
         if (VIR_ALLOC_N(stablepath, strlen(pool->def->target.path) +
                         1 + strlen(dent->d_name) + 1) < 0) {
-            virStorageReportError(conn, VIR_ERR_NO_MEMORY, "%s", _("path"));
+            virReportOOMError(conn);
             closedir(dh);
             return NULL;
         }
@@ -386,7 +387,7 @@ virStorageBackendStablePath(virConnectPt
     stablepath = strdup(devpath);
 
     if (stablepath == NULL)
-        virStorageReportError(conn, VIR_ERR_NO_MEMORY, "%s", _("dup path"));
+        virReportOOMError(conn);
 
     return stablepath;
 }
@@ -423,7 +424,7 @@ virStorageBackendRunProgRegex(virConnect
 
     /* Compile all regular expressions */
     if (VIR_ALLOC_N(reg, nregex) < 0) {
-        virStorageReportError(conn, VIR_ERR_NO_MEMORY, "%s", _("regex"));
+        virReportOOMError(conn);
         return -1;
     }
 
@@ -448,13 +449,11 @@ virStorageBackendRunProgRegex(virConnect
 
     /* Storage for matched variables */
     if (VIR_ALLOC_N(groups, totgroups) < 0) {
-        virStorageReportError(conn, VIR_ERR_NO_MEMORY,
-                              "%s", _("regex groups"));
+        virReportOOMError(conn);
         goto cleanup;
     }
     if (VIR_ALLOC_N(vars, maxvars+1) < 0) {
-        virStorageReportError(conn, VIR_ERR_NO_MEMORY,
-                              "%s", _("regex groups"));
+        virReportOOMError(conn);
         goto cleanup;
     }
 
@@ -490,8 +489,7 @@ virStorageBackendRunProgRegex(virConnect
                     line[vars[j+1].rm_eo] = '\0';
                     if ((groups[ngroup++] =
                          strdup(line + vars[j+1].rm_so)) == NULL) {
-                        virStorageReportError(conn, VIR_ERR_NO_MEMORY,
-                                              "%s", _("regex groups"));
+                        virReportOOMError(conn);
                         goto cleanup;
                     }
                 }
@@ -538,9 +536,9 @@ virStorageBackendRunProgRegex(virConnect
         return -1;
 
     if (err == -1) {
-        virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                              _("failed to wait for command: %s"),
-                              strerror(errno));
+        virReportSystemError(conn, errno,
+                             _("failed to wait for command '%s'"),
+                             prog[0]);
         return -1;
     } else {
         if (WIFEXITED(exitstatus)) {
@@ -588,8 +586,7 @@ virStorageBackendRunProgNul(virConnectPt
         return -1;
 
     if (VIR_ALLOC_N(v, n_columns) < 0) {
-        virStorageReportError(conn, VIR_ERR_NO_MEMORY,
-                              "%s", _("n_columns too large"));
+        virReportOOMError(conn);
         return -1;
     }
     for (i = 0; i < n_columns; i++)
@@ -636,8 +633,8 @@ virStorageBackendRunProgNul(virConnectPt
     if (feof (fp))
         err = 0;
     else
-        virStorageReportError (conn, VIR_ERR_INTERNAL_ERROR,
-                               _("read error: %s"), strerror (errno));
+        virReportSystemError(conn, errno,
+                             _("read error on pipe to '%s'"), prog[0]);
 
  cleanup:
     for (i = 0; i < n_columns; i++)
@@ -657,9 +654,9 @@ virStorageBackendRunProgNul(virConnectPt
         return -1;
 
     if (w_err == -1) {
-        virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                              _("failed to wait for command: %s"),
-                              strerror(errno));
+        virReportSystemError(conn, errno,
+                             _("failed to wait for command '%s'"),
+                             prog[0]);
         return -1;
     } else {
         if (WIFEXITED(exitstatus)) {
diff --git a/src/storage_backend_disk.c b/src/storage_backend_disk.c
--- a/src/storage_backend_disk.c
+++ b/src/storage_backend_disk.c
@@ -32,6 +32,8 @@
 #include "util.h"
 #include "memory.h"
 
+#define VIR_FROM_THIS VIR_FROM_STORAGE
+
 #define PARTHELPER BINDIR "/libvirt_parthelper"
 
 static int
@@ -44,13 +46,13 @@ virStorageBackendDiskMakeDataVol(virConn
 
     if (vol == NULL) {
         if (VIR_ALLOC(vol) < 0) {
-            virStorageReportError(conn, VIR_ERR_NO_MEMORY, "%s", _("volume"));
+            virReportOOMError(conn);
             return -1;
         }
 
         if (VIR_REALLOC_N(pool->volumes.objs,
                           pool->volumes.count+1) < 0) {
-            virStorageReportError(conn, VIR_ERR_NO_MEMORY, "%s", _("volume"));
+            virReportOOMError(conn);
             virStorageVolDefFree(vol);
             return -1;
         }
@@ -61,14 +63,14 @@ virStorageBackendDiskMakeDataVol(virConn
          */
         tmp = strrchr(groups[0], '/');
         if ((vol->name = strdup(tmp ? tmp + 1 : groups[0])) == NULL) {
-            virStorageReportError(conn, VIR_ERR_NO_MEMORY, "%s", _("volume"));
+            virReportOOMError(conn);
             return -1;
         }
     }
 
     if (vol->target.path == NULL) {
         if ((devpath = strdup(groups[0])) == NULL) {
-            virStorageReportError(conn, VIR_ERR_NO_MEMORY, "%s", _("volume"));
+            virReportOOMError(conn);
             return -1;
         }
 
@@ -89,15 +91,14 @@ virStorageBackendDiskMakeDataVol(virConn
     if (vol->key == NULL) {
         /* XXX base off a unique key of the underlying disk */
         if ((vol->key = strdup(vol->target.path)) == NULL) {
-            virStorageReportError(conn, VIR_ERR_NO_MEMORY, "%s", _("volume"));
+            virReportOOMError(conn);
             return -1;
         }
     }
 
     if (vol->source.extents == NULL) {
         if (VIR_ALLOC(vol->source.extents) < 0) {
-            virStorageReportError(conn, VIR_ERR_NO_MEMORY,
-                                  "%s", _("volume extents"));
+            virReportOOMError(conn);
             return -1;
         }
         vol->source.nextent = 1;
@@ -118,7 +119,7 @@ virStorageBackendDiskMakeDataVol(virConn
 
         if ((vol->source.extents[0].path =
              strdup(pool->def->source.devices[0].path)) == NULL) {
-            virStorageReportError(conn, VIR_ERR_NO_MEMORY, "%s", _("extents"));
+            virReportOOMError(conn);
             return -1;
         }
     }
@@ -367,9 +368,9 @@ virStorageBackendDiskDeleteVol(virConnec
 
     if ((n = readlink(vol->target.path, devpath, sizeof(devpath))) < 0 &&
         errno != EINVAL) {
-        virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                              _("Couldn't read volume target path '%s'. %s"),
-                              vol->target.path, strerror(errno));
+        virReportSystemError(conn, errno,
+                             _("Couldn't read volume target path '%s'"),
+                             vol->target.path);
         return -1;
     } else if (n <= 0) {
         strncpy(devpath, vol->target.path, PATH_MAX);
diff --git a/src/storage_backend_fs.c b/src/storage_backend_fs.c
--- a/src/storage_backend_fs.c
+++ b/src/storage_backend_fs.c
@@ -122,6 +122,7 @@ const struct FileTypeInfo const fileType
     */
 };
 
+#define VIR_FROM_THIS VIR_FROM_STORAGE
 
 
 
@@ -136,9 +137,9 @@ static int virStorageBackendProbeFile(vi
     int len, i, ret;
 
     if ((fd = open(def->target.path, O_RDONLY)) < 0) {
-        virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                              _("cannot open volume '%s': %s"),
-                              def->target.path, strerror(errno));
+        virReportSystemError(conn, errno,
+                             _("cannot open volume '%s'"),
+                             def->target.path);
         return -1;
     }
 
@@ -148,9 +149,9 @@ static int virStorageBackendProbeFile(vi
     }
 
     if ((len = read(fd, head, sizeof(head))) < 0) {
-        virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                              _("cannot read header '%s': %s"),
-                              def->target.path, strerror(errno));
+        virReportSystemError(conn, errno,
+                             _("cannot read header '%s'"),
+                             def->target.path);
         close(fd);
         return -1;
     }
@@ -277,7 +278,7 @@ virStorageBackendFileSystemNetFindPoolSo
     }
 
     if (VIR_REALLOC_N(state->list.sources, state->list.nsources+1) < 0) {
-        virStorageReportError(conn, VIR_ERR_NO_MEMORY, NULL);
+        virReportOOMError(conn);
         return -1;
     }
     memset(state->list.sources + state->list.nsources, 0, sizeof(*state->list.sources));
@@ -335,7 +336,7 @@ virStorageBackendFileSystemNetFindPoolSo
 
     xpath_ctxt = xmlXPathNewContext(doc);
     if (xpath_ctxt == NULL) {
-        virStorageReportError(conn, VIR_ERR_NO_MEMORY, "%s", _("xpath_ctxt"));
+        virReportOOMError(conn);
         goto cleanup;
     }
 
@@ -354,7 +355,7 @@ virStorageBackendFileSystemNetFindPoolSo
 
     retval = virStoragePoolSourceListFormat(conn, &state.list);
     if (retval == NULL) {
-        virStorageReportError(conn, VIR_ERR_NO_MEMORY, "%s", _("retval"));
+        virReportOOMError(conn);
         goto cleanup;
     }
 
@@ -387,9 +388,9 @@ virStorageBackendFileSystemIsMounted(vir
     struct mntent *ent;
 
     if ((mtab = fopen(_PATH_MOUNTED, "r")) == NULL) {
-        virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                              _("cannot read %s: %s"),
-                              _PATH_MOUNTED, strerror(errno));
+        virReportSystemError(conn, errno,
+                             _("cannot read mount list '%s'"),
+                             _PATH_MOUNTED);
         return -1;
     }
 
@@ -485,7 +486,7 @@ virStorageBackendFileSystemMount(virConn
     if (pool->def->type == VIR_STORAGE_POOL_NETFS) {
         if (VIR_ALLOC_N(src, strlen(pool->def->source.host.name) +
                         1 + strlen(pool->def->source.dir) + 1) < 0) {
-            virStorageReportError(conn, VIR_ERR_NO_MEMORY, "%s", _("source"));
+            virReportOOMError(conn);
             return -1;
         }
         strcpy(src, pool->def->source.host.name);
@@ -493,7 +494,7 @@ virStorageBackendFileSystemMount(virConn
         strcat(src, pool->def->source.dir);
     } else {
         if ((src = strdup(pool->def->source.devices[0].path)) == NULL) {
-            virStorageReportError(conn, VIR_ERR_NO_MEMORY, "%s", _("source"));
+            virReportOOMError(conn);
             return -1;
         }
     }
@@ -600,10 +601,11 @@ virStorageBackendFileSystemBuild(virConn
                                  virStoragePoolObjPtr pool,
                                  unsigned int flags ATTRIBUTE_UNUSED)
 {
-    if (virFileMakePath(pool->def->target.path) < 0) {
-        virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                              _("cannot create path '%s': %s"),
-                              pool->def->target.path, strerror(errno));
+    int err;
+    if ((err = virFileMakePath(pool->def->target.path)) < 0) {
+        virReportSystemError(conn, err,
+                             _("cannot create path '%s'"),
+                             pool->def->target.path);
         return -1;
     }
 
@@ -625,9 +627,9 @@ virStorageBackendFileSystemRefresh(virCo
     virStorageVolDefPtr vol = NULL;
 
     if (!(dir = opendir(pool->def->target.path))) {
-        virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                              _("cannot open path '%s': %s"),
-                              pool->def->target.path, strerror(errno));
+        virReportSystemError(conn, errno,
+                             _("cannot open path '%s'"),
+                             pool->def->target.path);
         goto cleanup;
     }
 
@@ -674,9 +676,9 @@ virStorageBackendFileSystemRefresh(virCo
 
 
     if (statvfs(pool->def->target.path, &sb) < 0) {
-        virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                              _("cannot statvfs path '%s': %s"),
-                              pool->def->target.path, strerror(errno));
+        virReportSystemError(conn, errno,
+                             _("cannot statvfs path '%s'"),
+                             pool->def->target.path);
         return -1;
     }
     pool->def->capacity = ((unsigned long long)sb.f_frsize *
@@ -688,7 +690,7 @@ virStorageBackendFileSystemRefresh(virCo
     return 0;
 
 no_memory:
-    virStorageReportError(conn, VIR_ERR_NO_MEMORY, NULL);
+    virReportOOMError(conn);
     /* fallthrough */
 
  cleanup:
@@ -740,9 +742,9 @@ virStorageBackendFileSystemDelete(virCon
     /* XXX delete all vols first ? */
 
     if (unlink(pool->def->target.path) < 0) {
-        virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                              _("cannot unlink path '%s': %s"),
-                              pool->def->target.path, strerror(errno));
+        virReportSystemError(conn, errno,
+                             _("cannot unlink path '%s'"),
+                             pool->def->target.path);
         return -1;
     }
 
@@ -764,7 +766,7 @@ virStorageBackendFileSystemVolCreate(vir
 
     if (VIR_ALLOC_N(vol->target.path, strlen(pool->def->target.path) +
                     1 + strlen(vol->name) + 1) < 0) {
-        virStorageReportError(conn, VIR_ERR_NO_MEMORY, "%s", _("target"));
+        virReportOOMError(conn);
         return -1;
     }
     vol->type = VIR_STORAGE_VOL_FILE;
@@ -773,17 +775,16 @@ virStorageBackendFileSystemVolCreate(vir
     strcat(vol->target.path, vol->name);
     vol->key = strdup(vol->target.path);
     if (vol->key == NULL) {
-        virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                              "%s", _("storage vol key"));
+        virReportOOMError(conn);
         return -1;
     }
 
     if (vol->target.format == VIR_STORAGE_VOL_FILE_RAW) {
         if ((fd = open(vol->target.path, O_RDWR | O_CREAT | O_EXCL,
                        vol->target.perms.mode)) < 0) {
-            virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                                  _("cannot create path '%s': %s"),
-                                  vol->target.path, strerror(errno));
+            virReportSystemError(conn, errno,
+                                 _("cannot create path '%s'"),
+                                 vol->target.path);
             return -1;
         }
 
@@ -798,9 +799,9 @@ virStorageBackendFileSystemVolCreate(vir
                 if (bytes > remain)
                     bytes = remain;
                 if ((bytes = safewrite(fd, zeros, bytes)) < 0) {
-                    virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                                          _("cannot fill file '%s': %s"),
-                                          vol->target.path, strerror(errno));
+                    virReportSystemError(conn, errno,
+                                         _("cannot fill file '%s'"),
+                                         vol->target.path);
                     unlink(vol->target.path);
                     close(fd);
                     return -1;
@@ -811,25 +812,25 @@ virStorageBackendFileSystemVolCreate(vir
 
         /* Now seek to final size, possibly making the file sparse */
         if (ftruncate(fd, vol->capacity) < 0) {
-            virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                                  _("cannot extend file '%s': %s"),
-                                  vol->target.path, strerror(errno));
+            virReportSystemError(conn, errno,
+                                 _("cannot extend file '%s'"),
+                                 vol->target.path);
             unlink(vol->target.path);
             close(fd);
             return -1;
         }
     } else if (vol->target.format == VIR_STORAGE_VOL_FILE_DIR) {
         if (mkdir(vol->target.path, vol->target.perms.mode) < 0) {
-            virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                                  _("cannot create path '%s': %s"),
-                                  vol->target.path, strerror(errno));
+            virReportSystemError(conn, errno,
+                                 _("cannot create path '%s'"),
+                                 vol->target.path);
             return -1;
         }
 
         if ((fd = open(vol->target.path, O_RDWR)) < 0) {
-            virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                                  _("cannot read path '%s': %s"),
-                                  vol->target.path, strerror(errno));
+            virReportSystemError(conn, errno,
+                                 _("cannot read path '%s'"),
+                                 vol->target.path);
             return -1;
         }
     } else {
@@ -862,9 +863,9 @@ virStorageBackendFileSystemVolCreate(vir
         }
 
         if ((fd = open(vol->target.path, O_RDONLY)) < 0) {
-            virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                                  _("cannot read path '%s': %s"),
-                                  vol->target.path, strerror(errno));
+            virReportSystemError(conn, errno,
+                                 _("cannot read path '%s'"),
+                                 vol->target.path);
             unlink(vol->target.path);
             return -1;
         }
@@ -897,9 +898,9 @@ virStorageBackendFileSystemVolCreate(vir
         }
 
         if ((fd = open(vol->target.path, O_RDONLY)) < 0) {
-            virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                                  _("cannot read path '%s': %s"),
-                                  vol->target.path, strerror(errno));
+            virReportSystemError(conn, errno,
+                                 _("cannot read path '%s'"),
+                                 vol->target.path);
             unlink(vol->target.path);
             return -1;
         }
@@ -914,18 +915,18 @@ virStorageBackendFileSystemVolCreate(vir
     /* We can only chown/grp if root */
     if (getuid() == 0) {
         if (fchown(fd, vol->target.perms.uid, vol->target.perms.gid) < 0) {
-            virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                                  _("cannot set file owner '%s': %s"),
-                                  vol->target.path, strerror(errno));
+            virReportSystemError(conn, errno,
+                                 _("cannot set file owner '%s'"),
+                                 vol->target.path);
             unlink(vol->target.path);
             close(fd);
             return -1;
         }
     }
     if (fchmod(fd, vol->target.perms.mode) < 0) {
-        virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                              _("cannot set file mode '%s': %s"),
-                              vol->target.path, strerror(errno));
+        virReportSystemError(conn, errno,
+                             _("cannot set file mode '%s'"),
+                             vol->target.path);
         unlink(vol->target.path);
         close(fd);
         return -1;
@@ -939,9 +940,9 @@ virStorageBackendFileSystemVolCreate(vir
     }
 
     if (close(fd) < 0) {
-        virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                              _("cannot close file '%s': %s"),
-                              vol->target.path, strerror(errno));
+        virReportSystemError(conn, errno,
+                             _("cannot close file '%s'"),
+                             vol->target.path);
         unlink(vol->target.path);
         return -1;
     }
@@ -962,9 +963,9 @@ virStorageBackendFileSystemVolDelete(vir
     if (unlink(vol->target.path) < 0) {
         /* Silently ignore failures where the vol has already gone away */
         if (errno != ENOENT) {
-            virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                                  _("cannot unlink file '%s': %s"),
-                                  vol->target.path, strerror(errno));
+            virReportSystemError(conn, errno,
+                                 _("cannot unlink file '%s'"),
+                                 vol->target.path);
             return -1;
         }
     }
diff --git a/src/storage_backend_iscsi.c b/src/storage_backend_iscsi.c
--- a/src/storage_backend_iscsi.c
+++ b/src/storage_backend_iscsi.c
@@ -39,6 +39,9 @@
 #include "util.h"
 #include "memory.h"
 
+#define VIR_FROM_THIS VIR_FROM_STORAGE
+
+
 static int
 virStorageBackendISCSITargetIP(virConnectPtr conn,
                                const char *hostname,
@@ -204,9 +207,9 @@ virStorageBackendISCSINewLun(virConnectP
             usleep(100 * 1000);
             goto reopen;
         }
-        virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                              _("cannot open %s: %s"),
-                              devpath, strerror(errno));
+        virReportSystemError(conn, errno,
+                             _("cannot open '%s'"),
+                             devpath);
         goto cleanup;
     }
 
@@ -322,9 +325,9 @@ virStorageBackendISCSIFindLUNs(virConnec
 
     sysdir = opendir(sysfs_path);
     if (sysdir == NULL) {
-        virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                              _("Failed to opendir sysfs path %s: %s"),
-                              sysfs_path, strerror(errno));
+        virReportSystemError(conn, errno,
+                             _("Failed to opendir sysfs path '%s'"),
+                             sysfs_path);
         return -1;
     }
     while ((sys_dirent = readdir(sysdir))) {
@@ -354,10 +357,9 @@ virStorageBackendISCSIFindLUNs(virConnec
     n = scandir(sysfs_path, &namelist, notdotdir, versionsort);
     if (n <= 0) {
         /* we didn't find any reasonable entries; return failure */
-        virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                              _("Failed to find any LUNs for session %s: %s"),
-                              session, strerror(errno));
-
+        virReportSystemError(conn, errno,
+                             _("Failed to find any LUNs for session '%s'"),
+                             session);
         return -1;
     }
 
@@ -407,9 +409,9 @@ virStorageBackendISCSIFindLUNs(virConnec
 
             sysdir = opendir(sysfs_path);
             if (sysdir == NULL) {
-                virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                                      _("Failed to opendir sysfs path %s: %s"),
-                                      sysfs_path, strerror(errno));
+                virReportSystemError(conn, errno,
+                                     _("Failed to opendir sysfs path '%s'"),
+                                     sysfs_path);
                 retval = -1;
                 goto namelist_cleanup;
             }
@@ -443,9 +445,9 @@ virStorageBackendISCSIFindLUNs(virConnec
                      host, bus, target, lun);
             sysdir = opendir(sysfs_path);
             if (sysdir == NULL) {
-                virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                                      _("Failed to opendir sysfs path %s: %s"),
-                                      sysfs_path, strerror(errno));
+                virReportSystemError(conn, errno,
+                                     _("Failed to opendir sysfs path '%s'"),
+                                     sysfs_path);
                 retval = -1;
                 goto namelist_cleanup;
             }
diff --git a/src/storage_backend_logical.c b/src/storage_backend_logical.c
--- a/src/storage_backend_logical.c
+++ b/src/storage_backend_logical.c
@@ -37,6 +37,8 @@
 #include "util.h"
 #include "memory.h"
 
+#define VIR_FROM_THIS VIR_FROM_STORAGE
+
 #define PV_BLANK_SECTOR_SIZE 512
 
 
@@ -400,22 +402,22 @@ virStorageBackendLogicalBuildPool(virCon
          * rather than trying to figure out if we're a disk or partition
          */
         if ((fd = open(pool->def->source.devices[i].path, O_WRONLY)) < 0) {
-            virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                                  _("cannot open device %s"),
-                                  strerror(errno));
+            virReportSystemError(conn, errno,
+                                 _("cannot open device '%s'"),
+                                 pool->def->source.devices[i].path);
             goto cleanup;
         }
         if (safewrite(fd, zeros, sizeof(zeros)) < 0) {
-            virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                                  _("cannot clear device header %s"),
-                                  strerror(errno));
+            virReportSystemError(conn, errno,
+                                 _("cannot clear device header of '%s'"),
+                                 pool->def->source.devices[i].path);
             close(fd);
             goto cleanup;
         }
         if (close(fd) < 0) {
-            virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                                  _("cannot close device %s"),
-                                  strerror(errno));
+            virReportSystemError(conn, errno,
+                                 _("cannot close device '%s'"),
+                                 pool->def->source.devices[i].path);
             goto cleanup;
         }
 
@@ -538,10 +540,9 @@ virStorageBackendLogicalDeletePool(virCo
         pvargv[1] = pool->def->source.devices[i].path;
         if (virRun(conn, pvargv, NULL) < 0) {
             error = -1;
-            virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                                  _("cannot remove PV device %s: %s"),
-                                  pool->def->source.devices[i].path,
-                                  strerror(errno));
+            virReportSystemError(conn, errno,
+                                 _("cannot remove PV device '%s'"),
+                                 pool->def->source.devices[i].path);
             break;
         }
     }
@@ -591,41 +592,41 @@ virStorageBackendLogicalCreateVol(virCon
         return -1;
 
     if ((fd = open(vol->target.path, O_RDONLY)) < 0) {
-        virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                              _("cannot read path '%s': %s"),
-                              vol->target.path, strerror(errno));
+        virReportSystemError(conn, errno,
+                             _("cannot read path '%s'"),
+                             vol->target.path);
         goto cleanup;
     }
 
     /* We can only chown/grp if root */
     if (getuid() == 0) {
         if (fchown(fd, vol->target.perms.uid, vol->target.perms.gid) < 0) {
-            virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                                  _("cannot set file owner '%s': %s"),
-                                  vol->target.path, strerror(errno));
+            virReportSystemError(conn, errno,
+                                 _("cannot set file owner '%s'"),
+                                 vol->target.path);
             goto cleanup;
         }
     }
     if (fchmod(fd, vol->target.perms.mode) < 0) {
-        virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                              _("cannot set file mode '%s': %s"),
-                              vol->target.path, strerror(errno));
+        virReportSystemError(conn, errno,
+                             _("cannot set file mode '%s'"),
+                             vol->target.path);
         goto cleanup;
     }
 
     if (close(fd) < 0) {
-        virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                              _("cannot close file '%s': %s"),
-                              vol->target.path, strerror(errno));
+        virReportSystemError(conn, errno,
+                             _("cannot close file '%s'"),
+                             vol->target.path);
         goto cleanup;
     }
     fd = -1;
 
     /* Fill in data about this new vol */
     if (virStorageBackendLogicalFindLVs(conn, pool, vol) < 0) {
-        virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                              _("cannot find newly created volume '%s': %s"),
-                              vol->target.path, strerror(errno));
+        virReportSystemError(conn, errno,
+                             _("cannot find newly created volume '%s'"),
+                             vol->target.path);
         goto cleanup;
     }
 
diff --git a/src/storage_conf.c b/src/storage_conf.c
--- a/src/storage_conf.c
+++ b/src/storage_conf.c
@@ -43,6 +43,8 @@
 #include "util.h"
 #include "memory.h"
 
+#define VIR_FROM_THIS VIR_FROM_STORAGE
+
 /* Work around broken limits.h on debian etch */
 #if defined __GNUC__ && defined _GCC_LIMITS_H_ && ! defined ULLONG_MAX
 # define ULLONG_MAX   ULONG_LONG_MAX
@@ -1405,9 +1407,9 @@ virStoragePoolObjSaveDef(virConnectPtr c
         char path[PATH_MAX];
 
         if ((err = virFileMakePath(driver->configDir))) {
-            virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                                  _("cannot create config directory %s: %s"),
-                                  driver->configDir, strerror(err));
+            virStorageReportError(conn, err,
+                                  _("cannot create config directory %s"),
+                                  driver->configDir);
             return -1;
         }
 
@@ -1448,24 +1450,24 @@ virStoragePoolObjSaveDef(virConnectPtr c
     if ((fd = open(pool->configFile,
                    O_WRONLY | O_CREAT | O_TRUNC,
                    S_IRUSR | S_IWUSR )) < 0) {
-        virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                              _("cannot create config file %s: %s"),
-                              pool->configFile, strerror(errno));
+        virReportSystemError(conn, errno,
+                             _("cannot create config file %s"),
+                             pool->configFile);
         goto cleanup;
     }
 
     towrite = strlen(xml);
     if (safewrite(fd, xml, towrite) != towrite) {
-        virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                              _("cannot write config file %s: %s"),
-                              pool->configFile, strerror(errno));
+        virReportSystemError(conn, errno,
+                             _("cannot write config file %s"),
+                             pool->configFile);
         goto cleanup;
     }
 
     if (close(fd) < 0) {
-        virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                              _("cannot save config file %s: %s"),
-                              pool->configFile, strerror(errno));
+        virReportSystemError(conn, errno,
+                             _("cannot save config file %s"),
+                             pool->configFile);
         goto cleanup;
     }
 
diff --git a/src/storage_driver.c b/src/storage_driver.c
--- a/src/storage_driver.c
+++ b/src/storage_driver.c
@@ -41,6 +41,8 @@
 #include "memory.h"
 #include "storage_backend.h"
 
+#define VIR_FROM_THIS VIR_FROM_STORAGE
+
 #define storageLog(msg...) fprintf(stderr, msg)
 
 static virStorageDriverStatePtr driverState;
@@ -379,8 +381,7 @@ storageListPools(virConnectPtr conn,
         if (virStoragePoolObjIsActive(driver->pools.objs[i])) {
             if (!(names[got] = strdup(driver->pools.objs[i]->def->name))) {
                 virStoragePoolObjUnlock(driver->pools.objs[i]);
-                virStorageReportError(conn, VIR_ERR_NO_MEMORY,
-                                      "%s", _("names"));
+                virReportOOMError(conn);
                 goto cleanup;
             }
             got++;
@@ -428,8 +429,7 @@ storageListDefinedPools(virConnectPtr co
         if (!virStoragePoolObjIsActive(driver->pools.objs[i])) {
             if (!(names[got] = strdup(driver->pools.objs[i]->def->name))) {
                 virStoragePoolObjUnlock(driver->pools.objs[i]);
-                virStorageReportError(conn, VIR_ERR_NO_MEMORY,
-                                      "%s", _("names"));
+                virReportOOMError(conn);
                 goto cleanup;
             }
             got++;
@@ -952,25 +952,24 @@ storagePoolSetAutostart(virStoragePoolPt
             int err;
 
             if ((err = virFileMakePath(driver->autostartDir))) {
-                virStorageReportError(obj->conn, VIR_ERR_INTERNAL_ERROR,
-                                      _("cannot create autostart directory %s: %s"),
-                                      driver->autostartDir, strerror(err));
+                virReportSystemError(obj->conn, err,
+                                     _("cannot create autostart directory %s"),
+                                     driver->autostartDir);
                 goto cleanup;
             }
 
             if (symlink(pool->configFile, pool->autostartLink) < 0) {
-                virStorageReportError(obj->conn, VIR_ERR_INTERNAL_ERROR,
-                                      _("Failed to create symlink '%s' to '%s': %s"),
-                                      pool->autostartLink, pool->configFile,
-                                      strerror(errno));
+                virReportSystemError(obj->conn, errno,
+                                     _("Failed to create symlink '%s' to '%s'"),
+                                     pool->autostartLink, pool->configFile);
                 goto cleanup;
             }
         } else {
             if (unlink(pool->autostartLink) < 0 &&
                 errno != ENOENT && errno != ENOTDIR) {
-                virStorageReportError(obj->conn, VIR_ERR_INTERNAL_ERROR,
-                                      _("Failed to delete symlink '%s': %s"),
-                                      pool->autostartLink, strerror(errno));
+                virReportSystemError(obj->conn, errno,
+                                     _("Failed to delete symlink '%s'"),
+                                     pool->autostartLink);
                 goto cleanup;
             }
         }
@@ -1042,8 +1041,7 @@ storagePoolListVolumes(virStoragePoolPtr
 
     for (i = 0 ; i < pool->volumes.count && n < maxnames ; i++) {
         if ((names[n++] = strdup(pool->volumes.objs[i]->name)) == NULL) {
-            virStorageReportError(obj->conn, VIR_ERR_NO_MEMORY,
-                                  "%s", _("name"));
+            virReportOOMError(obj->conn);
             goto cleanup;
         }
     }
@@ -1224,7 +1222,7 @@ storageVolumeCreateXML(virStoragePoolPtr
 
     if (VIR_REALLOC_N(pool->volumes.objs,
                       pool->volumes.count+1) < 0) {
-        virStorageReportError(obj->conn, VIR_ERR_NO_MEMORY, NULL);
+        virReportOOMError(obj->conn);
         goto cleanup;
     }
 
@@ -1453,7 +1451,7 @@ storageVolumeGetPath(virStorageVolPtr ob
 
     ret = strdup(vol->target.path);
     if (ret == NULL)
-        virStorageReportError(obj->conn, VIR_ERR_NO_MEMORY, "%s", _("path"));
+        virReportOOMError(obj->conn);
 
 cleanup:
     if (pool)
diff --git a/src/test.c b/src/test.c
--- a/src/test.c
+++ b/src/test.c
@@ -46,6 +46,8 @@
 #include "xml.h"
 #include "threads.h"
 
+#define VIR_FROM_THIS VIR_FROM_TEST
+
 #define MAX_CPUS 128
 
 struct _testCell {
@@ -154,7 +156,7 @@ testBuildCapabilities(virConnectPtr conn
     return caps;
 
 no_memory:
-    testError(conn, VIR_ERR_NO_MEMORY, NULL);
+    virReportOOMError(conn);
     virCapabilitiesFree(caps);
     return NULL;
 }
@@ -195,7 +197,7 @@ static const char *defaultPoolXML =
 static const unsigned long long defaultPoolCap = (100 * 1024 * 1024 * 1024ull);
 static const unsigned long long defaultPoolAlloc = 0;
 
-static int testStoragePoolObjSetDefaults(virStoragePoolObjPtr pool);
+static int testStoragePoolObjSetDefaults(virConnectPtr conn, virStoragePoolObjPtr pool);
 
 static int testOpenDefault(virConnectPtr conn) {
     int u;
@@ -209,7 +211,7 @@ static int testOpenDefault(virConnectPtr
     virStoragePoolObjPtr poolobj = NULL;
 
     if (VIR_ALLOC(privconn) < 0) {
-        testError(conn, VIR_ERR_NO_MEMORY, "testConn");
+        virReportOOMError(conn);
         return VIR_DRV_OPEN_ERROR;
     }
     if (virMutexInit(&privconn->lock) < 0) {
@@ -223,7 +225,8 @@ static int testOpenDefault(virConnectPtr
     conn->privateData = privconn;
 
     if (gettimeofday(&tv, NULL) < 0) {
-        testError(NULL, VIR_ERR_INTERNAL_ERROR, "%s", _("getting time of day"));
+        virReportSystemError(conn, errno,
+                             "%s", _("getting time of day"));
         goto error;
     }
 
@@ -276,7 +279,7 @@ static int testOpenDefault(virConnectPtr
         goto error;
     }
 
-    if (testStoragePoolObjSetDefaults(poolobj) == -1) {
+    if (testStoragePoolObjSetDefaults(conn, poolobj) == -1) {
         virStoragePoolObjUnlock(poolobj);
         goto error;
     }
@@ -336,7 +339,7 @@ static int testOpenFromFile(virConnectPt
     virDomainObjPtr dom;
     testConnPtr privconn;
     if (VIR_ALLOC(privconn) < 0) {
-        testError(NULL, VIR_ERR_NO_MEMORY, "testConn");
+        virReportOOMError(conn);
         return VIR_DRV_OPEN_ERROR;
     }
     if (virMutexInit(&privconn->lock) < 0) {
@@ -353,9 +356,9 @@ static int testOpenFromFile(virConnectPt
         goto error;
 
     if ((fd = open(file, O_RDONLY)) < 0) {
-        testError(NULL, VIR_ERR_INTERNAL_ERROR,
-                  _("loading host definition file '%s': %s"),
-                  file, strerror(errno));
+        virReportSystemError(NULL, errno,
+                             _("loading host definition file '%s'"),
+                             file);
         goto error;
     }
 
@@ -573,7 +576,7 @@ static int testOpenFromFile(virConnectPt
             goto error;
         }
 
-        if (testStoragePoolObjSetDefaults(pool) == -1) {
+        if (testStoragePoolObjSetDefaults(conn, pool) == -1) {
             virStoragePoolObjUnlock(pool);
             goto error;
         }
@@ -673,8 +676,8 @@ static char *testGetHostname (virConnect
 
     result = virGetHostname();
     if (result == NULL) {
-        testError (conn, VIR_ERR_SYSTEM_ERROR, "%s",
-                   strerror (errno));
+        virReportSystemError(conn, errno,
+                             "%s", _("cannot lookup hostname"));
         return NULL;
     }
     /* Caller frees this string. */
@@ -703,7 +706,7 @@ static char *testGetCapabilities (virCon
     char *xml;
     testDriverLock(privconn);
     if ((xml = virCapabilitiesFormatXML(privconn->caps)) == NULL)
-        testError(conn, VIR_ERR_NO_MEMORY, NULL);
+        virReportOOMError(conn);
     testDriverUnlock(privconn);
     return xml;
 }
@@ -1111,42 +1114,42 @@ static int testDomainSave(virDomainPtr d
 
     xml = testDomainDumpXML(domain, 0);
     if (xml == NULL) {
-        testError(domain->conn, VIR_ERR_INTERNAL_ERROR,
-                  _("saving domain '%s' failed to allocate space for metadata: %s"),
-                  domain->name, strerror(errno));
+        virReportSystemError(domain->conn, errno,
+                             _("saving domain '%s' failed to allocate space for metadata"),
+                             domain->name);
         goto cleanup;
     }
 
     if ((fd = open(path, O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR)) < 0) {
-        testError(domain->conn, VIR_ERR_INTERNAL_ERROR,
-                  _("saving domain '%s' to '%s': open failed: %s"),
-                  domain->name, path, strerror(errno));
+        virReportSystemError(domain->conn, errno,
+                             _("saving domain '%s' to '%s': open failed"),
+                             domain->name, path);
         goto cleanup;
     }
     len = strlen(xml);
     if (safewrite(fd, TEST_SAVE_MAGIC, sizeof(TEST_SAVE_MAGIC)) < 0) {
-        testError(domain->conn, VIR_ERR_INTERNAL_ERROR,
-                  _("saving domain '%s' to '%s': write failed: %s"),
-                  domain->name, path, strerror(errno));
+        virReportSystemError(domain->conn, errno,
+                             _("saving domain '%s' to '%s': write failed"),
+                             domain->name, path);
         goto cleanup;
     }
     if (safewrite(fd, (char*)&len, sizeof(len)) < 0) {
-        testError(domain->conn, VIR_ERR_INTERNAL_ERROR,
-                  _("saving domain '%s' to '%s': write failed: %s"),
-                  domain->name, path, strerror(errno));
+        virReportSystemError(domain->conn, errno,
+                             _("saving domain '%s' to '%s': write failed"),
+                             domain->name, path);
         goto cleanup;
     }
     if (safewrite(fd, xml, len) < 0) {
-        testError(domain->conn, VIR_ERR_INTERNAL_ERROR,
-                  _("saving domain '%s' to '%s': write failed: %s"),
-                  domain->name, path, strerror(errno));
+        virReportSystemError(domain->conn, errno,
+                             _("saving domain '%s' to '%s': write failed"),
+                             domain->name, path);
         goto cleanup;
     }
 
     if (close(fd) < 0) {
-        testError(domain->conn, VIR_ERR_INTERNAL_ERROR,
-                  _("saving domain '%s' to '%s': write failed: %s"),
-                  domain->name, path, strerror(errno));
+        virReportSystemError(domain->conn, errno,
+                             _("saving domain '%s' to '%s': write failed"),
+                             domain->name, path);
         goto cleanup;
     }
     fd = -1;
@@ -1189,13 +1192,15 @@ static int testDomainRestore(virConnectP
     int ret = -1;
 
     if ((fd = open(path, O_RDONLY)) < 0) {
-        testError(conn, VIR_ERR_INTERNAL_ERROR,
-                  "%s", _("cannot read domain image"));
+        virReportSystemError(conn, errno,
+                             _("cannot read domain image '%s'"),
+                             path);
         goto cleanup;
     }
-    if (read(fd, magic, sizeof(magic)) != sizeof(magic)) {
-        testError(conn, VIR_ERR_INTERNAL_ERROR,
-                  "%s", _("incomplete save header"));
+    if (saferead(fd, magic, sizeof(magic)) != sizeof(magic)) {
+        virReportSystemError(conn, errno,
+                             _("incomplete save header in '%s'"),
+                             path);
         goto cleanup;
     }
     if (memcmp(magic, TEST_SAVE_MAGIC, sizeof(magic))) {
@@ -1203,9 +1208,10 @@ static int testDomainRestore(virConnectP
                   "%s", _("mismatched header magic"));
         goto cleanup;
     }
-    if (read(fd, (char*)&len, sizeof(len)) != sizeof(len)) {
-        testError(conn, VIR_ERR_INTERNAL_ERROR,
-                  "%s", _("failed to read metadata length"));
+    if (saferead(fd, (char*)&len, sizeof(len)) != sizeof(len)) {
+        virReportSystemError(conn, errno,
+                             _("failed to read metadata length in '%s'"),
+                             path);
         goto cleanup;
     }
     if (len < 1 || len > 8192) {
@@ -1214,12 +1220,12 @@ static int testDomainRestore(virConnectP
         goto cleanup;
     }
     if (VIR_ALLOC_N(xml, len+1) < 0) {
-        testError(conn, VIR_ERR_NO_MEMORY, "xml");
+        virReportOOMError(conn);
         goto cleanup;
     }
-    if (read(fd, xml, len) != len) {
-        testError(conn, VIR_ERR_INTERNAL_ERROR,
-                  "%s", _("incomplete metdata"));
+    if (saferead(fd, xml, len) != len) {
+        virReportSystemError(conn, errno,
+                             _("incomplete metdata in '%s'"), path);
         goto cleanup;
     }
     xml[len] = '\0';
@@ -1269,21 +1275,21 @@ static int testDomainCoreDump(virDomainP
     }
 
     if ((fd = open(to, O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR)) < 0) {
-        testError(domain->conn, VIR_ERR_INTERNAL_ERROR,
-                  _("domain '%s' coredump: failed to open %s: %s"),
-                  domain->name, to, strerror (errno));
+        virReportSystemError(domain->conn, errno,
+                             _("domain '%s' coredump: failed to open %s"),
+                             domain->name, to);
         goto cleanup;
     }
     if (safewrite(fd, TEST_SAVE_MAGIC, sizeof(TEST_SAVE_MAGIC)) < 0) {
-        testError(domain->conn, VIR_ERR_INTERNAL_ERROR,
-                  _("domain '%s' coredump: failed to write header to %s: %s"),
-                  domain->name, to, strerror (errno));
+        virReportSystemError(domain->conn, errno,
+                             _("domain '%s' coredump: failed to write header to %s"),
+                             domain->name, to);
         goto cleanup;
     }
     if (close(fd) < 0) {
-        testError(domain->conn, VIR_ERR_INTERNAL_ERROR,
-                  _("domain '%s' coredump: write failed: %s: %s"),
-                  domain->name, to, strerror (errno));
+        virReportSystemError(domain->conn, errno,
+                             _("domain '%s' coredump: write failed: %s"),
+                             domain->name, to);
         goto cleanup;
     }
     privdom->state = VIR_DOMAIN_SHUTOFF;
@@ -1306,7 +1312,7 @@ cleanup:
 static char *testGetOSType(virDomainPtr dom) {
     char *ret = strdup("linux");
     if (!ret)
-        testError(dom->conn, VIR_ERR_NO_MEMORY, NULL);
+        virReportOOMError(dom->conn);
     return ret;
 }
 
@@ -1491,7 +1497,7 @@ static int testListDefinedDomains(virCon
     return n;
 
 no_memory:
-    testError(conn, VIR_ERR_NO_MEMORY, NULL);
+    virReportOOMError(conn);
     for (n = 0 ; n < maxnames ; n++)
         VIR_FREE(names[n]);
     testDriverUnlock(privconn);
@@ -1682,7 +1688,7 @@ static char *testDomainGetSchedulerType(
     *nparams = 1;
     type = strdup("fair");
     if (!type)
-        testError(domain->conn, VIR_ERR_NO_MEMORY, "schedular");
+        virReportOOMError(domain->conn);
 
     return type;
 }
@@ -1864,7 +1870,7 @@ static int testListNetworks(virConnectPt
     return n;
 
 no_memory:
-    testError(conn, VIR_ERR_NO_MEMORY, NULL);
+    virReportOOMError(conn);
     for (n = 0 ; n < nnames ; n++)
         VIR_FREE(names[n]);
     testDriverUnlock(privconn);
@@ -1907,7 +1913,7 @@ static int testListDefinedNetworks(virCo
     return n;
 
 no_memory:
-    testError(conn, VIR_ERR_NO_MEMORY, NULL);
+    virReportOOMError(conn);
     for (n = 0 ; n < nnames ; n++)
         VIR_FREE(names[n]);
     testDriverUnlock(privconn);
@@ -2099,7 +2105,7 @@ static char *testNetworkGetBridgeName(vi
 
     if (privnet->def->bridge &&
         !(bridge = strdup(privnet->def->bridge))) {
-        testError(network->conn, VIR_ERR_NO_MEMORY, "network");
+        virReportOOMError(network->conn);
         goto cleanup;
     }
 
@@ -2164,7 +2170,8 @@ cleanup:
  * Storage Driver routines
  */
 
-static int testStoragePoolObjSetDefaults(virStoragePoolObjPtr pool) {
+static int testStoragePoolObjSetDefaults(virConnectPtr conn,
+                                         virStoragePoolObjPtr pool) {
 
     pool->def->capacity = defaultPoolCap;
     pool->def->allocation = defaultPoolAlloc;
@@ -2172,7 +2179,7 @@ static int testStoragePoolObjSetDefaults
 
     pool->configFile = strdup("\0");
     if (!pool->configFile) {
-        testError(NULL, VIR_ERR_NO_MEMORY, "configFile");
+        virReportOOMError(conn);
         return -1;
     }
 
@@ -2284,7 +2291,7 @@ testStorageListPools(virConnectPtr conn,
     return n;
 
 no_memory:
-    testError(conn, VIR_ERR_NO_MEMORY, NULL);
+    virReportOOMError(conn);
     for (n = 0 ; n < nnames ; n++)
         VIR_FREE(names[n]);
     testDriverUnlock(privconn);
@@ -2331,7 +2338,7 @@ testStorageListDefinedPools(virConnectPt
     return n;
 
 no_memory:
-    testError(conn, VIR_ERR_NO_MEMORY, NULL);
+    virReportOOMError(conn);
     for (n = 0 ; n < nnames ; n++)
         VIR_FREE(names[n]);
     testDriverUnlock(privconn);
@@ -2408,7 +2415,7 @@ testStoragePoolCreate(virConnectPtr conn
     }
     def = NULL;
 
-    if (testStoragePoolObjSetDefaults(pool) == -1) {
+    if (testStoragePoolObjSetDefaults(conn, pool) == -1) {
         virStoragePoolObjRemove(&privconn->pools, pool);
         pool = NULL;
         goto cleanup;
@@ -2447,7 +2454,7 @@ testStoragePoolDefine(virConnectPtr conn
     }
     def = NULL;
 
-    if (testStoragePoolObjSetDefaults(pool) == -1) {
+    if (testStoragePoolObjSetDefaults(conn, pool) == -1) {
         virStoragePoolObjRemove(&privconn->pools, pool);
         pool = NULL;
         goto cleanup;
@@ -2806,7 +2813,7 @@ testStoragePoolListVolumes(virStoragePoo
 
     for (i = 0 ; i < privpool->volumes.count && n < maxnames ; i++) {
         if ((names[n++] = strdup(privpool->volumes.objs[i]->name)) == NULL) {
-            testError(pool->conn, VIR_ERR_NO_MEMORY, "%s", _("name"));
+            virReportOOMError(pool->conn);
             goto cleanup;
         }
     }
@@ -2986,14 +2993,14 @@ testStorageVolumeCreateXML(virStoragePoo
 
     if (VIR_REALLOC_N(privpool->volumes.objs,
                       privpool->volumes.count+1) < 0) {
-        testError(pool->conn, VIR_ERR_NO_MEMORY, NULL);
+        virReportOOMError(pool->conn);
         goto cleanup;
     }
 
     if (VIR_ALLOC_N(privvol->target.path,
                     strlen(privpool->def->target.path) +
                     1 + strlen(privvol->name) + 1) < 0) {
-        testError(pool->conn, VIR_ERR_NO_MEMORY, "%s", _("target"));
+        virReportOOMError(pool->conn);
         goto cleanup;
     }
 
@@ -3002,8 +3009,7 @@ testStorageVolumeCreateXML(virStoragePoo
     strcat(privvol->target.path, privvol->name);
     privvol->key = strdup(privvol->target.path);
     if (privvol->key == NULL) {
-        testError(pool->conn, VIR_ERR_INTERNAL_ERROR, "%s",
-                  _("storage vol key"));
+        virReportOOMError(pool->conn);
         goto cleanup;
     }
 
@@ -3224,7 +3230,7 @@ testStorageVolumeGetPath(virStorageVolPt
 
     ret = strdup(privvol->target.path);
     if (ret == NULL)
-        testError(vol->conn, VIR_ERR_NO_MEMORY, "%s", _("path"));
+        virReportOOMError(vol->conn);
 
 cleanup:
     if (privpool)
diff --git a/src/uml_driver.c b/src/uml_driver.c
--- a/src/uml_driver.c
+++ b/src/uml_driver.c
@@ -64,6 +64,8 @@
 #include "datatypes.h"
 #include "logging.h"
 
+#define VIR_FROM_THIS VIR_FROM_UML
+
 /* For storing short-lived temporary files. */
 #define TEMPDIR LOCAL_STATE_DIR "/cache/libvirt"
 
@@ -159,7 +161,7 @@ umlIdentifyOneChrPTY(virConnectPtr conn,
     char *res = NULL;
     int retries = 0;
     if (virAsprintf(&cmd, "config %s%d", dev, def->dstPort) < 0) {
-        umlReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, NULL);
+        virReportOOMError(conn);
         return -1;
     }
 requery:
@@ -168,7 +170,7 @@ requery:
     if (STRPREFIX(res, "pts:")) {
         VIR_FREE(def->data.file.path);
         if ((def->data.file.path = strdup(res + 4)) == NULL) {
-            umlReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, NULL);
+            virReportOOMError(conn);
             VIR_FREE(res);
             VIR_FREE(cmd);
             return -1;
@@ -523,7 +525,7 @@ static int umlReadPidFile(virConnectPtr 
     vm->pid = -1;
     if (virAsprintf(&pidfile, "%s/%s/pid",
                     driver->monitorDir, vm->def->name) < 0) {
-        umlReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, NULL);
+        virReportOOMError(conn);
         return -1;
     }
 
@@ -549,9 +551,9 @@ reopen:
 
  cleanup:
     if (rc != 0)
-        umlReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                       _("failed to read pid: %s: %s"),
-                       pidfile, strerror(errno));
+        virReportSystemError(conn, errno,
+                             _("failed to read pid: %s"),
+                             pidfile);
     VIR_FREE(pidfile);
     return rc;
 }
@@ -564,7 +566,7 @@ static int umlMonitorAddress(virConnectP
 
     if (virAsprintf(&sockname, "%s/%s/mconsole",
                     driver->monitorDir, vm->def->name) < 0) {
-        umlReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, NULL);
+        virReportOOMError(conn);
         return -1;
     }
 
@@ -597,16 +599,16 @@ restat:
     }
 
     if ((vm->monitor = socket(PF_UNIX, SOCK_DGRAM, 0)) < 0) {
-        umlReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                       _("cannot open socket %s"), strerror(errno));
+        virReportSystemError(conn, errno,
+                             "%s", _("cannot open socket"));
         return -1;
     }
 
     memset(addr.sun_path, 0, sizeof addr.sun_path);
     sprintf(addr.sun_path + 1, "%u", getpid());
     if (bind(vm->monitor, (struct sockaddr *)&addr, sizeof addr) < 0) {
-        umlReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                       _("cannot bind socket %s"), strerror(errno));
+        virReportSystemError(conn, errno,
+                             "%s", _("cannot bind socket"));
         close(vm->monitor);
         vm->monitor = -1;
         return -1;
@@ -658,9 +660,9 @@ static int umlMonitorCommand(virConnectP
     req.version = MONITOR_VERSION;
     req.length = strlen(cmd);
     if (req.length > (MONITOR_BUFLEN-1)) {
-        umlReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                       _("cannot send too long command %s: %s"),
-                       cmd, strerror(EINVAL));
+        virReportSystemError(conn, EINVAL,
+                             _("cannot send too long command %s (%d bytes)"),
+                             cmd, req.length);
         return -1;
     }
     strncpy(req.data, cmd, req.length);
@@ -668,9 +670,9 @@ static int umlMonitorCommand(virConnectP
 
     if (sendto(vm->monitor, &req, sizeof req, 0,
                (struct sockaddr *)&addr, sizeof addr) != (sizeof req)) {
-        umlReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                       _("cannot send command %s: %s"),
-                       cmd, strerror(errno));
+        virReportSystemError(conn, errno,
+                             _("cannot send command %s"),
+                             cmd);
         return -1;
     }
 
@@ -678,15 +680,14 @@ static int umlMonitorCommand(virConnectP
         addrlen = sizeof(addr);
         if (recvfrom(vm->monitor, &res, sizeof res, 0,
                      (struct sockaddr *)&addr, &addrlen) < 0) {
-            umlReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                           _("cannot read reply %s: %s"),
-                           cmd, strerror(errno));
+            virReportSystemError(conn, errno,
+                                 _("cannot read reply %s"),
+                                 cmd);
             goto error;
         }
 
         if (VIR_REALLOC_N(retdata, retlen + res.length) < 0) {
-            umlReportError(conn, NULL, NULL,
-                           VIR_ERR_NO_MEMORY, NULL);
+            virReportOOMError(conn);
             goto error;
         }
         memcpy(retdata + retlen, res.data, res.length);
@@ -740,39 +741,38 @@ static int umlStartVMDaemon(virConnectPt
      * in a sub-process so its hard to feed back a useful error
      */
     if (stat(vm->def->os.kernel, &sb) < 0) {
-        umlReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                       _("Cannot find UML kernel %s: %s"),
-                       vm->def->os.kernel, strerror(errno));
+        virReportSystemError(conn, errno,
+                             _("Cannot find UML kernel %s"),
+                             vm->def->os.kernel);
         return -1;
     }
 
     if (virFileMakePath(driver->logDir) < 0) {
-        umlReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                       _("cannot create log directory %s"),
-                       driver->logDir);
+        virReportSystemError(conn, errno,
+                             _("cannot create log directory %s"),
+                             driver->logDir);
         return -1;
     }
 
     if (virAsprintf(&logfile, "%s/%s.log",
                     driver->logDir, vm->def->name) < 0) {
-        umlReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, NULL);
+        virReportOOMError(conn);
         return -1;
     }
 
     if ((logfd = open(logfile, O_CREAT | O_TRUNC | O_WRONLY,
                       S_IRUSR | S_IWUSR)) < 0) {
-        umlReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                       _("failed to create logfile %s: %s"),
-                       logfile, strerror(errno));
+        virReportSystemError(conn, errno,
+                             _("failed to create logfile %s"),
+                             logfile);
         VIR_FREE(logfile);
         return -1;
     }
     VIR_FREE(logfile);
 
     if (umlSetCloseExec(logfd) < 0) {
-        umlReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                       _("Unable to set VM logfile close-on-exec flag %s"),
-                       strerror(errno));
+        virReportSystemError(conn, errno,
+                             "%s", _("Unable to set VM logfile close-on-exec flag"));
         close(logfd);
         return -1;
     }
@@ -909,7 +909,7 @@ static virDrvOpenStatus umlOpen(virConne
     } else {
         conn->uri = xmlParseURI(uid ? "uml:///session" : "uml:///system");
         if (!conn->uri) {
-            umlReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,NULL);
+            virReportOOMError(conn);
             return VIR_DRV_OPEN_ERROR;
         }
     }
@@ -946,8 +946,7 @@ static char *umlGetCapabilities(virConne
 
     umlDriverLock(driver);
     if ((xml = virCapabilitiesFormatXML(driver->caps)) == NULL)
-        umlReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
-                 "%s", _("failed to allocate space for capabilities support"));
+        virReportOOMError(conn);
     umlDriverUnlock(driver);
 
     return xml;
@@ -1157,8 +1156,8 @@ umlGetHostname (virConnectPtr conn)
 
     result = virGetHostname();
     if (result == NULL) {
-        umlReportError (conn, NULL, NULL, VIR_ERR_SYSTEM_ERROR,
-                          "%s", strerror (errno));
+        virReportSystemError(conn, errno,
+                             "%s", _("cannot lookup hostname"));
         return NULL;
     }
     /* Caller frees this string. */
@@ -1326,8 +1325,7 @@ static char *umlDomainGetOSType(virDomai
     }
 
     if (!(type = strdup(vm->def->os.type)))
-        umlReportError(dom->conn, dom, NULL, VIR_ERR_NO_MEMORY,
-                         "%s", _("failed to allocate space for ostype"));
+        virReportOOMError(dom->conn);
 
 cleanup:
     if (vm)
@@ -1511,8 +1509,7 @@ static int umlListDefinedDomains(virConn
         virDomainObjLock(driver->domains.objs[i]);
         if (!virDomainIsActive(driver->domains.objs[i])) {
             if (!(names[got++] = strdup(driver->domains.objs[i]->def->name))) {
-                umlReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
-                                 "%s", _("failed to allocate space for VM name string"));
+                virReportOOMError(conn);
                 virDomainObjUnlock(driver->domains.objs[i]);
                 goto cleanup;
             }
@@ -1711,23 +1708,23 @@ static int umlDomainSetAutostart(virDoma
             int err;
 
             if ((err = virFileMakePath(driver->autostartDir))) {
-                umlReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
-                               _("cannot create autostart directory %s: %s"),
-                               driver->autostartDir, strerror(err));
+                virReportSystemError(dom->conn, err,
+                                     _("cannot create autostart directory %s"),
+                                     driver->autostartDir);
                 goto cleanup;
             }
 
             if (symlink(configFile, autostartLink) < 0) {
-                umlReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
-                               _("Failed to create symlink '%s to '%s': %s"),
-                               autostartLink, configFile, strerror(errno));
+                virReportSystemError(dom->conn, errno,
+                                     _("Failed to create symlink '%s to '%s'"),
+                                     autostartLink, configFile);
                 goto cleanup;
             }
         } else {
             if (unlink(autostartLink) < 0 && errno != ENOENT && errno != ENOTDIR) {
-                umlReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
-                               _("Failed to delete symlink '%s': %s"),
-                               autostartLink, strerror(errno));
+                virReportSystemError(dom->conn, errno,
+                                     _("Failed to delete symlink '%s'"),
+                                     autostartLink);
                 goto cleanup;
             }
         }
@@ -1786,8 +1783,8 @@ umlDomainBlockPeek (virDomainPtr dom,
         /* The path is correct, now try to open it and get its size. */
         fd = open (path, O_RDONLY);
         if (fd == -1) {
-            umlReportError (dom->conn, dom, NULL, VIR_ERR_SYSTEM_ERROR,
-                            "%s", strerror (errno));
+            virReportSystemError(dom->conn, errno,
+                                 _("cannot open %s"), path);
             goto cleanup;
         }
 
@@ -1797,8 +1794,8 @@ umlDomainBlockPeek (virDomainPtr dom,
          */
         if (lseek (fd, offset, SEEK_SET) == (off_t) -1 ||
             saferead (fd, buffer, size) == (ssize_t) -1) {
-            umlReportError (dom->conn, dom, NULL, VIR_ERR_SYSTEM_ERROR,
-                            "%s", strerror (errno));
+            virReportSystemError(dom->conn, errno,
+                                 _("cannot read %s"), path);
             goto cleanup;
         }
 
diff --git a/src/util.c b/src/util.c
--- a/src/util.c
+++ b/src/util.c
@@ -67,6 +67,7 @@
 
 #define virLog(msg...) fprintf(stderr, msg)
 
+#define VIR_FROM_THIS VIR_FROM_NONE
 
 #define ReportError(conn, code, fmt...)                                      \
         virReportErrorHelper(conn, VIR_FROM_NONE, code, __FILE__,          \
@@ -212,37 +213,36 @@ __virExec(virConnectPtr conn,
      */
     sigfillset(&newmask);
     if (pthread_sigmask(SIG_SETMASK, &newmask, &oldmask) != 0) {
-        ReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                    _("cannot block signals: %s"),
-                    strerror(errno));
+        virReportSystemError(conn, errno,
+                             "%s", _("cannot block signals"));
         return -1;
     }
 
     if ((null = open("/dev/null", O_RDONLY)) < 0) {
-        ReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                    _("cannot open %s: %s"),
-                    "/dev/null", strerror(errno));
+        virReportSystemError(conn, errno,
+                             _("cannot open %s"),
+                             "/dev/null");
         goto cleanup;
     }
 
     if (outfd != NULL) {
         if (*outfd == -1) {
             if (pipe(pipeout) < 0) {
-                ReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                            _("cannot create pipe: %s"), strerror(errno));
+                virReportSystemError(conn, errno,
+                                     "%s", _("cannot create pipe"));
                 goto cleanup;
             }
 
             if ((flags & VIR_EXEC_NONBLOCK) &&
                 virSetNonBlock(pipeout[0]) == -1) {
-                ReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                            "%s", _("Failed to set non-blocking file descriptor flag"));
+                virReportSystemError(conn, errno,
+                                     "%s", _("Failed to set non-blocking file descriptor flag"));
                 goto cleanup;
             }
 
             if (virSetCloseExec(pipeout[0]) == -1) {
-                ReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                            "%s", _("Failed to set close-on-exec file descriptor flag"));
+                virReportSystemError(conn, errno,
+                                     "%s", _("Failed to set close-on-exec file descriptor flag"));
                 goto cleanup;
             }
 
@@ -259,21 +259,21 @@ __virExec(virConnectPtr conn,
     if (errfd != NULL) {
         if (*errfd == -1) {
             if (pipe(pipeerr) < 0) {
-                ReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                            _("Failed to create pipe: %s"), strerror(errno));
+                virReportSystemError(conn, errno,
+                                     "%s", _("Failed to create pipe"));
                 goto cleanup;
             }
 
             if ((flags & VIR_EXEC_NONBLOCK) &&
                 virSetNonBlock(pipeerr[0]) == -1) {
-                ReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                            "%s", _("Failed to set non-blocking file descriptor flag"));
+                virReportSystemError(conn, errno,
+                                     "%s", _("Failed to set non-blocking file descriptor flag"));
                 goto cleanup;
             }
 
             if (virSetCloseExec(pipeerr[0]) == -1) {
-                ReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                            "%s", _("Failed to set close-on-exec file descriptor flag"));
+                virReportSystemError(conn, errno,
+                                     "%s", _("Failed to set close-on-exec file descriptor flag"));
                 goto cleanup;
             }
 
@@ -288,8 +288,8 @@ __virExec(virConnectPtr conn,
     }
 
     if ((pid = fork()) < 0) {
-        ReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                    _("cannot fork child process: %s"), strerror(errno));
+        virReportSystemError(conn, errno,
+                             "%s", _("cannot fork child process"));
         goto cleanup;
     }
 
@@ -307,9 +307,8 @@ __virExec(virConnectPtr conn,
         /* Restore our original signal mask now child is safely
            running */
         if (pthread_sigmask(SIG_SETMASK, &oldmask, NULL) != 0) {
-            ReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                        _("cannot unblock signals: %s"),
-                        strerror(errno));
+            virReportSystemError(conn, errno,
+                                 "%s", _("cannot unblock signals"));
             return -1;
         }
 
@@ -345,9 +344,8 @@ __virExec(virConnectPtr conn,
        and don't want to propagate that to children */
     sigemptyset(&newmask);
     if (pthread_sigmask(SIG_SETMASK, &newmask, NULL) != 0) {
-        ReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                    _("cannot unblock signals: %s"),
-                    strerror(errno));
+        virReportSystemError(conn, errno,
+                             "%s", _("cannot unblock signals"));
         return -1;
     }
 
@@ -363,24 +361,21 @@ __virExec(virConnectPtr conn,
 
     if (flags & VIR_EXEC_DAEMON) {
         if (setsid() < 0) {
-            ReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                        _("cannot become session leader: %s"),
-                        strerror(errno));
+            virReportSystemError(conn, errno,
+                                 "%s", _("cannot become session leader"));
             _exit(1);
         }
 
         if (chdir("/") < 0) {
-            ReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                        _("cannot change to root directory: %s"),
-                        strerror(errno));
+            virReportSystemError(conn, errno,
+                                 "%s", _("cannot change to root directory: %s"));
             _exit(1);
         }
 
         pid = fork();
         if (pid < 0) {
-            ReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                        _("cannot fork child process: %s"),
-                        strerror(errno));
+            virReportSystemError(conn, errno,
+                                 "%s", _("cannot fork child process"));
             _exit(1);
         }
 
@@ -390,20 +385,20 @@ __virExec(virConnectPtr conn,
 
 
     if (dup2(infd >= 0 ? infd : null, STDIN_FILENO) < 0) {
-        ReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                    _("failed to setup stdin file handle: %s"), strerror(errno));
+        virReportSystemError(conn, errno,
+                             "%s", _("failed to setup stdin file handle"));
         _exit(1);
     }
     if (childout > 0 &&
         dup2(childout, STDOUT_FILENO) < 0) {
-        ReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                    _("failed to setup stdout file handle: %s"), strerror(errno));
+        virReportSystemError(conn, errno,
+                             "%s", _("failed to setup stdout file handle"));
         _exit(1);
     }
     if (childerr > 0 &&
         dup2(childerr, STDERR_FILENO) < 0) {
-        ReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                    _("failed to setup stderr file handle: %s"), strerror(errno));
+        virReportSystemError(conn, errno,
+                             "%s", _("failed to setup stderr file handle"));
         _exit(1);
     }
 
@@ -419,9 +414,9 @@ __virExec(virConnectPtr conn,
     else
         execvp(argv[0], (char **) argv);
 
-    ReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                _("cannot execute binary '%s': %s"),
-                argv[0], strerror(errno));
+    virReportSystemError(conn, errno,
+                         _("cannot execute binary %s"),
+                         argv[0]);
 
     _exit(1);
 
@@ -535,8 +530,8 @@ virPipeReadUntilEOF(virConnectPtr conn, 
         continue;
 
     pollerr:
-        ReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                    _("poll error: %s"), strerror(errno));
+        virReportSystemError(conn, errno,
+                             "%s", _("poll error"));
         goto error;
     }
 
@@ -599,16 +594,15 @@ virRun(virConnectPtr conn,
     while ((waitret = waitpid(childpid, &exitstatus, 0) == -1) &&
             errno == EINTR);
     if (waitret == -1) {
-        ReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                    _("cannot wait for '%s': %s"),
-                    argv[0], strerror(errno));
+        virReportSystemError(conn, errno,
+                             _("cannot wait for '%s'"),
+                             argv[0]);
         goto error;
     }
 
     if (status == NULL) {
         errno = EINVAL;
         if (WIFEXITED(exitstatus) && WEXITSTATUS(exitstatus) != 0) {
-
             ReportError(conn, VIR_ERR_INTERNAL_ERROR,
                         _("'%s' exited with non-zero status %d and "
                           "signal %d: %s"), argv_str,
diff --git a/src/virterror.c b/src/virterror.c
--- a/src/virterror.c
+++ b/src/virterror.c
@@ -20,6 +20,7 @@
 #include "logging.h"
 #include "memory.h"
 #include "threads.h"
+#include "util.h"
 
 virThreadLocal virLastErr;
 
@@ -334,7 +335,7 @@ virResetLastError(void)
  * If the connection object was discovered to be invalid by
  * an API call, then the error will be reported against the
  * global error object.
- * 
+ *
  * Since 0.6.0, all errors reported in the per-connection object
  * are also duplicated in the global error object. As such an
  * application can always use virGetLastError(). This method
@@ -365,7 +366,7 @@ virConnGetLastError(virConnectPtr conn)
  * If the connection object was discovered to be invalid by
  * an API call, then the error will be reported against the
  * global error object.
- * 
+ *
  * Since 0.6.0, all errors reported in the per-connection object
  * are also duplicated in the global error object. As such an
  * application can always use virGetLastError(). This method
@@ -983,7 +984,7 @@ virErrorMsg(virErrorNumber error, const 
 void virReportErrorHelper(virConnectPtr conn, int domcode, int errcode,
                           const char *filename ATTRIBUTE_UNUSED,
                           const char *funcname ATTRIBUTE_UNUSED,
-                          long long linenr ATTRIBUTE_UNUSED,
+                          size_t linenr ATTRIBUTE_UNUSED,
                           const char *fmt, ...)
 {
     va_list args;
@@ -1005,3 +1006,69 @@ void virReportErrorHelper(virConnectPtr 
 }
 
 
+
+
+
+
+void virReportSystemErrorFull(virConnectPtr conn,
+                              int domcode,
+                              int theerrno,
+                              const char *filename ATTRIBUTE_UNUSED,
+                              const char *funcname ATTRIBUTE_UNUSED,
+                              size_t linenr ATTRIBUTE_UNUSED,
+                              const char *fmt, ...)
+{
+    va_list args;
+    char errorMessage[1024];
+    char systemError[1024];
+    char *theerrnostr;
+    const char *virerr;
+    char *combined = NULL;
+
+#ifdef HAVE_STRERROR_R
+#ifdef __USE_GNU
+    /* Annoying linux specific API contract */
+    theerrnostr = strerror_r(theerrno, systemError, sizeof(systemError));
+#else
+    strerror_r(theerrno, systemError, sizeof(systemError));
+    theerrnostr = systemError;
+#endif
+#else
+    /* Mingw lacks strerror_r() and its strerror() is definitely not
+     * threadsafe, so safest option is to just print the raw errno
+     * value - we can at least reliably & safely look it up in the
+     * header files for debug purposes
+     */
+    snprintf(systemError, sizeof(systemError), "errno=%d", theerrno);
+    theerrnostr = systemError;
+#endif
+
+    if (fmt) {
+        va_start(args, fmt);
+        vsnprintf(errorMessage, sizeof(errorMessage)-1, fmt, args);
+        va_end(args);
+    } else {
+        errorMessage[0] = '\0';
+    }
+
+    if (virAsprintf(&combined, "%s: %s", errorMessage, theerrnostr) < 0)
+        combined = theerrnostr; /* OOM, so lets just pass the strerror info as best effort */
+
+    virerr = virErrorMsg(VIR_ERR_SYSTEM_ERROR, (errorMessage[0] ? errorMessage : NULL));
+    virRaiseError(conn, NULL, NULL, domcode, VIR_ERR_SYSTEM_ERROR, VIR_ERR_ERROR,
+                  virerr, errorMessage, NULL, -1, -1, virerr, errorMessage);
+}
+
+
+void virReportOOMErrorFull(virConnectPtr conn,
+                           int domcode,
+                           const char *filename ATTRIBUTE_UNUSED,
+                           const char *funcname ATTRIBUTE_UNUSED,
+                           size_t linenr ATTRIBUTE_UNUSED)
+{
+    const char *virerr;
+
+    virerr = virErrorMsg(VIR_ERR_NO_MEMORY, NULL);
+    virRaiseError(conn, NULL, NULL, domcode, VIR_ERR_NO_MEMORY, VIR_ERR_ERROR,
+                  virerr, NULL, NULL, -1, -1, virerr, NULL);
+}
diff --git a/src/virterror_internal.h b/src/virterror_internal.h
--- a/src/virterror_internal.h
+++ b/src/virterror_internal.h
@@ -48,10 +48,36 @@ const char *virErrorMsg(virErrorNumber e
 void virReportErrorHelper(virConnectPtr conn, int domcode, int errcode,
                           const char *filename ATTRIBUTE_UNUSED,
                           const char *funcname ATTRIBUTE_UNUSED,
-                          long long linenr ATTRIBUTE_UNUSED,
+                          size_t linenr ATTRIBUTE_UNUSED,
                           const char *fmt, ...)
   ATTRIBUTE_FORMAT(printf, 7, 8);
 
+void virReportSystemErrorFull(virConnectPtr conn,
+                              int domcode,
+                              int theerrno,
+                              const char *filename,
+                              const char *funcname,
+                              size_t linenr,
+                              const char *fmt, ...)
+    ATTRIBUTE_FORMAT(printf, 7, 8);
+
+#define virReportSystemError(conn, theerrno, fmt,...)             \
+    virReportSystemErrorFull((conn),                              \
+                             VIR_FROM_THIS,                       \
+                             (theerrno),                          \
+                             __FILE__, __FUNCTION__, __LINE__,    \
+                             (fmt), __VA_ARGS__)
+
+void virReportOOMErrorFull(virConnectPtr conn,
+                           int domcode,
+                           const char *filename,
+                           const char *funcname,
+                           size_t linenr);
+
+#define virReportOOMError(conn)                         \
+    virReportOOMErrorFull((conn), VIR_FROM_THIS,        \
+                     __FILE__, __FUNCTION__, __LINE__)
+
 
 void virSetGlobalError(void);
 void virSetConnError(virConnectPtr conn);
diff --git a/src/xen_inotify.c b/src/xen_inotify.c
--- a/src/xen_inotify.c
+++ b/src/xen_inotify.c
@@ -41,6 +41,8 @@
 
 #include "xm_internal.h" /* for xenXMDomainConfigParse */
 
+#define VIR_FROM_THIS VIR_FROM_XEN_INOTIFY
+
 #define virXenInotifyError(conn, code, fmt...)                                 \
         virReportErrorHelper(NULL, VIR_FROM_XEN_INOTIFY, code, __FILE__,      \
                                __FUNCTION__, __LINE__, fmt)
@@ -390,9 +392,10 @@ xenInotifyOpen(virConnectPtr conn ATTRIB
         }
 
         /* populate initial list */
-         if (!(dh = opendir(configDir))) {
-            virXenInotifyError (NULL, VIR_ERR_INTERNAL_ERROR,
-                                 "%s", strerror(errno));
+        if (!(dh = opendir(configDir))) {
+            virReportSystemError(NULL, errno,
+                                 _("cannot open directory: %s"),
+                                 configDir);
             return -1;
         }
         while ((ent = readdir(dh))) {
diff --git a/src/xen_internal.c b/src/xen_internal.c
--- a/src/xen_internal.c
+++ b/src/xen_internal.c
@@ -58,6 +58,8 @@
 #include "capabilities.h"
 #include "memory.h"
 
+#define VIR_FROM_THIS VIR_FROM_XEN
+
 /*
  * so far there is 2 versions of the structures usable for doing
  * hypervisor calls.
@@ -2532,8 +2534,9 @@ xenHypervisorMakeCapabilities(virConnect
     cpuinfo = fopen ("/proc/cpuinfo", "r");
     if (cpuinfo == NULL) {
         if (errno != ENOENT) {
-            virXenError (conn, VIR_ERR_SYSTEM_ERROR,
-                         "/proc/cpuinfo: %s", strerror(errno));
+            virReportSystemError(conn, errno,
+                                 _("cannot read file %s"),
+                                 "/proc/cpuinfo");
             return NULL;
         }
     }
@@ -2542,9 +2545,9 @@ xenHypervisorMakeCapabilities(virConnect
     if (capabilities == NULL) {
         if (errno != ENOENT) {
             fclose(cpuinfo);
-            virXenError (conn, VIR_ERR_SYSTEM_ERROR,
-                         "/sys/hypervisor/properties/capabilities: %s",
-                         strerror(errno));
+            virReportSystemError(conn, errno,
+                                 _("cannot read file %s"),
+                                 "/sys/hypervisor/properties/capabilities");
             return NULL;
         }
     }
diff --git a/src/xen_unified.c b/src/xen_unified.c
--- a/src/xen_unified.c
+++ b/src/xen_unified.c
@@ -44,6 +44,8 @@
 #include "util.h"
 #include "memory.h"
 
+#define VIR_FROM_THIS VIR_FROM_XEN
+
 static int
 xenUnifiedNodeGetInfo (virConnectPtr conn, virNodeInfoPtr info);
 static int
@@ -451,7 +453,8 @@ xenUnifiedGetHostname (virConnectPtr con
 
     result = virGetHostname();
     if (result == NULL) {
-        xenUnifiedError (conn, VIR_ERR_SYSTEM_ERROR, "%s", strerror(errno));
+        virReportSystemError(conn, errno,
+                             "%s", _("cannot lookup hostname"));
         return NULL;
     }
     /* Caller frees this string. */
diff --git a/src/xend_internal.c b/src/xend_internal.c
--- a/src/xend_internal.c
+++ b/src/xend_internal.c
@@ -49,6 +49,8 @@
 /* required for cpumap_t */
 #include <xen/dom0_ops.h>
 
+#define VIR_FROM_THIS VIR_FROM_XEND
+
 #ifndef PROXY
 
 /*
@@ -4101,14 +4103,13 @@ xenDaemonDomainMigratePrepare (virConnec
     if (uri_in == NULL) {
         r = gethostname (hostname, HOST_NAME_MAX+1);
         if (r == -1) {
-            virXendError (dconn, VIR_ERR_SYSTEM_ERROR,
-                          _("gethostname failed: %s"), strerror (errno));
+            virReportSystemError(dconn, errno,
+                                 _("unable to resolve name %s"), hostname);
             return -1;
         }
         *uri_out = strdup (hostname);
         if (*uri_out == NULL) {
-            virXendError (dconn, VIR_ERR_SYSTEM_ERROR,
-                          _("failed to strdup hostname: %s"), strerror (errno));
+            virReportOOMError(dconn);
             return -1;
         }
     }
@@ -4742,9 +4743,9 @@ xenDaemonDomainBlockPeek (virDomainPtr d
     /* The path is correct, now try to open it and get its size. */
     fd = open (path, O_RDONLY);
     if (fd == -1) {
-        virXendError (domain->conn, VIR_ERR_SYSTEM_ERROR,
-                      _("failed to open for reading: %s: %s"),
-                      path, strerror (errno));
+        virReportSystemError(domain->conn, errno,
+                             _("failed to open for reading: %s"),
+                             path);
         goto cleanup;
     }
 
@@ -4754,9 +4755,9 @@ xenDaemonDomainBlockPeek (virDomainPtr d
      */
     if (lseek (fd, offset, SEEK_SET) == (off_t) -1 ||
         saferead (fd, buffer, size) == (ssize_t) -1) {
-        virXendError (domain->conn, VIR_ERR_SYSTEM_ERROR,
-                      _("failed to lseek or read from file: %s: %s"),
-                      path, strerror (errno));
+        virReportSystemError(domain->conn, errno,
+                             _("failed to lseek or read from file: %s"),
+                             path);
         goto cleanup;
     }
 
diff --git a/src/xm_internal.c b/src/xm_internal.c
--- a/src/xm_internal.c
+++ b/src/xm_internal.c
@@ -47,6 +47,7 @@
 #include "memory.h"
 #include "logging.h"
 
+#define VIR_FROM_THIS VIR_FROM_XENXM
 
 #ifdef WITH_RHEL5_API
 #define XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU 0
@@ -284,7 +285,7 @@ static int xenXMConfigCopyStringInternal
     }
 
     if (!(*value = strdup(val->str))) {
-        xenXMError(conn, VIR_ERR_NO_MEMORY, NULL);
+        virReportOOMError(conn);
         return -1;
     }
 
@@ -413,8 +414,9 @@ xenXMConfigCacheAddFile(virConnectPtr co
 
     /* Get modified time */
     if ((stat(filename, &st) < 0)) {
-        xenXMError (conn, VIR_ERR_INTERNAL_ERROR,
-                    _("cannot stat %s: %s"), filename, strerror(errno));
+        virReportSystemError(conn, errno,
+                             _("cannot stat: %s"),
+                             filename);
         return -1;
     }
 
@@ -449,7 +451,7 @@ xenXMConfigCacheAddFile(virConnectPtr co
     } else { /* Completely new entry */
         newborn = 1;
         if (VIR_ALLOC(entry) < 0) {
-            xenXMError (conn, VIR_ERR_NO_MEMORY, "%s", strerror(errno));
+            virReportOOMError(conn);
             return -1;
         }
         memcpy(entry->filename, filename, PATH_MAX);
@@ -503,7 +505,8 @@ int xenXMConfigCacheRefresh (virConnectP
     int ret = -1;
 
     if (now == ((time_t)-1)) {
-        xenXMError (conn, VIR_ERR_SYSTEM_ERROR, "%s", strerror(errno));
+        virReportSystemError(conn, errno,
+                             "%s", _("cannot get time of day"));
         return (-1);
     }
 
@@ -515,7 +518,9 @@ int xenXMConfigCacheRefresh (virConnectP
 
     /* Process the files in the config dir */
     if (!(dh = opendir(configDir))) {
-        xenXMError (conn, VIR_ERR_SYSTEM_ERROR, "%s", strerror(errno));
+        virReportSystemError(conn, errno,
+                             _("cannot read directory %s"),
+                             configDir);
         return (-1);
     }
 
@@ -1297,7 +1302,7 @@ xenXMDomainConfigParse(virConnectPtr con
     return def;
 
 no_memory:
-    xenXMError(conn, VIR_ERR_NO_MEMORY, NULL);
+    virReportOOMError(conn);
     /* fallthrough */
   cleanup:
     virDomainGraphicsDefFree(graphics);
@@ -1531,14 +1536,14 @@ int xenXMDomainPinVcpu(virDomainPtr doma
             }
 
     if (virBufferError(&mapbuf)) {
-        xenXMError(domain->conn, VIR_ERR_NO_MEMORY, "%s", _("allocate buffer"));
+        virReportOOMError(domain->conn);
         return -1;
     }
 
     mapstr = virBufferContentAndReset(&mapbuf);
 
     if (VIR_ALLOC_N(cpuset, maxcpu) < 0) {
-        xenXMError(domain->conn, VIR_ERR_NO_MEMORY, "%s", _("allocate buffer"));
+        virReportOOMError(domain->conn);
         goto cleanup;
     }
     if (virDomainCpuSetParse(domain->conn,
@@ -1781,12 +1786,12 @@ static int xenXMDomainConfigFormatDisk(v
         virBufferAddLit(&buf, ",w");
 
     if (virBufferError(&buf)) {
-        xenXMError(conn, VIR_ERR_NO_MEMORY, NULL);
+        virReportOOMError(conn);
         return -1;
     }
 
     if (VIR_ALLOC(val) < 0) {
-        xenXMError(conn, VIR_ERR_NO_MEMORY, NULL);
+        virReportOOMError(conn);
         goto cleanup;
     }
 
@@ -1853,7 +1858,7 @@ static int xenXMDomainConfigFormatNet(vi
                           net->model);
 
     if (VIR_ALLOC(val) < 0) {
-        xenXMError(conn, VIR_ERR_NO_MEMORY, NULL);
+        virReportOOMError(conn);
         goto cleanup;
     }
 
@@ -2254,7 +2259,7 @@ virConfPtr xenXMDomainConfigFormat(virCo
     return conf;
 
 no_memory:
-    xenXMError(conn, VIR_ERR_NO_MEMORY, NULL);
+    virReportOOMError(conn);
 
 cleanup:
     virConfFreeValue(diskVal);
@@ -2348,7 +2353,7 @@ virDomainPtr xenXMDomainDefineXML(virCon
         goto error;
 
     if (VIR_ALLOC(entry) < 0) {
-        xenXMError(conn, VIR_ERR_NO_MEMORY, "%s", _("config"));
+        virReportOOMError(conn);
         goto error;
     }
 
@@ -2544,7 +2549,7 @@ xenXMDomainAttachDevice(virDomainPtr dom
     case VIR_DOMAIN_DEVICE_DISK:
     {
         if (VIR_REALLOC_N(def->disks, def->ndisks+1) < 0) {
-            xenXMError(domain->conn, VIR_ERR_NO_MEMORY, NULL);
+            virReportOOMError(domain->conn);
             goto cleanup;
         }
         def->disks[def->ndisks++] = dev->data.disk;
@@ -2557,7 +2562,7 @@ xenXMDomainAttachDevice(virDomainPtr dom
     case VIR_DOMAIN_DEVICE_NET:
     {
         if (VIR_REALLOC_N(def->nets, def->nnets+1) < 0) {
-            xenXMError(domain->conn, VIR_ERR_NO_MEMORY, NULL);
+            virReportOOMError(domain->conn);
             goto cleanup;
         }
         def->nets[def->nnets++] = dev->data.net;
@@ -2715,15 +2720,15 @@ int xenXMDomainGetAutostart(virDomainPtr
     int ret = -1;
 
     if (!linkname || !config) {
-        xenXMError(dom->conn, VIR_ERR_NO_MEMORY, NULL);
+        virReportOOMError(dom->conn);
         goto cleanup;
     }
 
     *autostart = virFileLinkPointsTo(linkname, config);
     if (*autostart < 0) {
-        xenXMError(dom->conn, VIR_ERR_INTERNAL_ERROR,
-                   _("failed to check autostart link %s: %s"),
-                   linkname, strerror(errno));
+        virReportSystemError(dom->conn, errno,
+                             _("cannot check link %s points to config %s"),
+                             linkname, config);
         goto cleanup;
     }
 
@@ -2743,24 +2748,24 @@ int xenXMDomainSetAutostart(virDomainPtr
     int ret = -1;
 
     if (!linkname || !config) {
-        xenXMError(dom->conn, VIR_ERR_NO_MEMORY, NULL);
+        virReportOOMError(dom->conn);
         goto cleanup;
     }
 
     if (autostart) {
         if (symlink(config, linkname) < 0 &&
             errno != EEXIST) {
-            xenXMError(dom->conn, VIR_ERR_INTERNAL_ERROR,
-                       _("failed to create link %s: %s"),
-                       linkname, strerror(errno));
+            virReportSystemError(dom->conn, errno,
+                                 _("failed to create link %s to %s"),
+                                 config, linkname);
             goto cleanup;
         }
     } else {
         if (unlink(linkname)  < 0 &&
             errno != ENOENT) {
-            xenXMError(dom->conn, VIR_ERR_INTERNAL_ERROR,
-                       _("failed to remove link %s: %s"),
-                       linkname, strerror(errno));
+            virReportSystemError(dom->conn, errno,
+                                 _("failed to remove link %s"),
+                                 linkname);
             goto cleanup;
         }
     }


-- 
|: 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 :|




More information about the libvir-list mailing list