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

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

 



The strerror() method is not guarenteed to be re-entrant, which is
rather a pain because the strerror_r() method is rather unpleasant
to use. In addition our code is quite inconsistent about using 
VIR_ERR_SYSTEM_ERROR vs VIR_ERR_INTERNAL_ERROR for problems which
have an 'errno' avilable. Likewise we're not very consistent about
OOM reporting error codes

This patch thus introduces two convenient functions for reporting a
system error and OOM error.

 virReportSystemError(conn, theerrno, fmt,...)
 virReportOOMError(conn)

The OOM error funtion doesn't take any args because 50% of the time
we don't currently give any message, and where we do its just the
name of the variable, which is pretty useless for a user.
The useful stuff would be filename/line number/method name, which
are automatically included in all error calls now.

As a short example..

Before:

        virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
                             _("cannot remove config %s: %s"),
                             configFile, strerror(errno));

After:

        virReportSystemError(conn, errno,
                             _("cannot remove config %s"),
                             configFile);


NB, we actually still use strerror() on MinGW because it lacks
strerror_r(), and by code examination I've verified its strerror()
is threadsafe, just returning static strings.


 .x-sc_avoid_write             |    1 
 autobuild.sh                  |    1 
 configure.in                  |    3 
 po/POTFILES.in                |    1 
 src/domain_conf.c             |   41 ++++++-----
 src/libvirt_private.syms      |    2 
 src/lxc_container.c           |  142 ++++++++++++++++++++++------------------
 src/lxc_controller.c          |   97 ++++++++++++++-------------
 src/lxc_driver.c              |   73 +++++++++------------
 src/network_conf.c            |   46 ++++++-------
 src/network_driver.c          |  125 ++++++++++++++++++-----------------
 src/nodeinfo.c                |   16 ++--
 src/qemu_driver.c             |   79 ++++++++++------------
 src/remote_internal.c         |   73 +++++++++------------
 src/storage_backend.c         |   81 +++++++++++------------
 src/storage_backend_disk.c    |   23 +++---
 src/storage_backend_fs.c      |  129 ++++++++++++++++++-------------------
 src/storage_backend_iscsi.c   |   34 +++++----
 src/storage_backend_logical.c |   57 ++++++++--------
 src/storage_conf.c            |   26 ++++---
 src/storage_driver.c          |   34 ++++-----
 src/test.c                    |  146 +++++++++++++++++++++---------------------
 src/uml_driver.c              |  111 +++++++++++++++----------------
 src/util.c                    |   94 ++++++++++++---------------
 src/virterror.c               |   73 ++++++++++++++++++++-
 src/virterror_internal.h      |   28 +++++++-
 src/xen_inotify.c             |    9 +-
 src/xen_internal.c            |   13 ++-
 src/xen_unified.c             |    5 +
 src/xend_internal.c           |   21 +++---
 src/xm_internal.c             |   59 +++++++++-------
 31 files changed, 881 insertions(+), 762 deletions(-)

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",
@@ -1904,8 +1906,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 {
@@ -3394,33 +3395,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;
     }
 
@@ -3519,9 +3520,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;
     }
 
@@ -3573,9 +3574,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
@@ -319,6 +319,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, errno,
+                                     _("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;
         }
     }
@@ -963,9 +961,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;
     }
 
@@ -983,10 +981,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;
     }
 
@@ -2239,9 +2236,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;
@@ -2402,8 +2399,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 {
@@ -2471,8 +2468,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;
                     }
 
@@ -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);
                 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
@@ -584,9 +586,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:
@@ -605,9 +607,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;
                 }
 
@@ -639,9 +641,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) {
@@ -663,9 +664,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;
         }
 
@@ -723,9 +724,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;
         }
 
@@ -752,16 +752,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(wakeup) < 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->wakeupRead = wakeup[0];
@@ -1002,9 +1000,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;
@@ -1191,9 +1189,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;
     }
 
@@ -5183,10 +5180,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)
@@ -5195,10 +5190,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)
@@ -5723,8 +5716,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;
 
         }
@@ -5773,10 +5766,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, errno,
+                                  _("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;
 
@@ -332,7 +333,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
@@ -363,7 +364,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
@@ -978,7 +979,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;
@@ -1000,3 +1001,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
@@ -54,6 +54,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.
@@ -2404,8 +2406,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;
         }
     }
@@ -2414,9 +2417,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
 
 /*
@@ -4093,14 +4095,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;
         }
     }
@@ -4734,9 +4735,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;
     }
 
@@ -4746,9 +4747,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
 
 /* The true Xen limit varies but so far is always way
    less than 1024, which is the Linux kernel limit according
@@ -276,7 +277,7 @@ static int xenXMConfigCopyStringInternal
     }
 
     if (!(*value = strdup(val->str))) {
-        xenXMError(conn, VIR_ERR_NO_MEMORY, NULL);
+        virReportOOMError(conn);
         return -1;
     }
 
@@ -405,8 +406,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;
     }
 
@@ -441,7 +443,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);
@@ -495,7 +497,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);
     }
 
@@ -507,7 +510,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);
     }
 
@@ -1289,7 +1294,7 @@ xenXMDomainConfigParse(virConnectPtr con
     return def;
 
 no_memory:
-    xenXMError(conn, VIR_ERR_NO_MEMORY, NULL);
+    virReportOOMError(conn);
     /* fallthrough */
   cleanup:
     virDomainGraphicsDefFree(graphics);
@@ -1523,14 +1528,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,
@@ -1773,12 +1778,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;
     }
 
@@ -1844,7 +1849,7 @@ static int xenXMDomainConfigFormatNet(vi
                           net->model);
 
     if (VIR_ALLOC(val) < 0) {
-        xenXMError(conn, VIR_ERR_NO_MEMORY, NULL);
+        virReportOOMError(conn);
         goto cleanup;
     }
 
@@ -2245,7 +2250,7 @@ virConfPtr xenXMDomainConfigFormat(virCo
     return conf;
 
 no_memory:
-    xenXMError(conn, VIR_ERR_NO_MEMORY, NULL);
+    virReportOOMError(conn);
 
 cleanup:
     virConfFreeValue(diskVal);
@@ -2339,7 +2344,7 @@ virDomainPtr xenXMDomainDefineXML(virCon
         goto error;
 
     if (VIR_ALLOC(entry) < 0) {
-        xenXMError(conn, VIR_ERR_NO_MEMORY, "%s", _("config"));
+        virReportOOMError(conn);
         goto error;
     }
 
@@ -2535,7 +2540,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;
@@ -2548,7 +2553,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;
@@ -2706,15 +2711,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;
     }
 
@@ -2734,24 +2739,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 :|

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

[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]