Daniel Veillard 4a8ca1
diff --git a/src/libvirt.c b/src/libvirt.c
Daniel Veillard 4a8ca1
--- a/src/libvirt.c
Daniel Veillard 4a8ca1
+++ b/src/libvirt.c
Daniel Veillard 4a8ca1
@@ -2296,6 +2296,16 @@ virDomainMigrate (virDomainPtr domain,
Daniel Veillard 4a8ca1
     conn = domain->conn;        /* Source connection. */
Daniel Veillard 4a8ca1
     if (!VIR_IS_CONNECT (dconn)) {
Daniel Veillard 4a8ca1
         virLibConnError (conn, VIR_ERR_INVALID_CONN, __FUNCTION__);
Daniel Veillard 4a8ca1
+        return NULL;
Daniel Veillard 4a8ca1
+    }
Daniel Veillard 4a8ca1
+
Daniel Veillard 4a8ca1
+    if (domain->conn->flags & VIR_CONNECT_RO) {
Daniel Veillard 4a8ca1
+        virLibDomainError(domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
Daniel Veillard 4a8ca1
+        return NULL;
Daniel Veillard 4a8ca1
+    }
Daniel Veillard 4a8ca1
+    if (dconn->flags & VIR_CONNECT_RO) {
Daniel Veillard 4a8ca1
+        /* NB, delibrately report error against source object, not dest here */
Daniel Veillard 4a8ca1
+        virLibDomainError(domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
Daniel Veillard 4a8ca1
         return NULL;
Daniel Veillard 4a8ca1
     }
Daniel Veillard 4a8ca1
 
Daniel Veillard 4a8ca1
@@ -2426,6 +2436,11 @@ virDomainMigratePrepare (virConnectPtr d
Daniel Veillard 4a8ca1
         return -1;
Daniel Veillard 4a8ca1
     }
Daniel Veillard 4a8ca1
 
Daniel Veillard 4a8ca1
+    if (dconn->flags & VIR_CONNECT_RO) {
Daniel Veillard 4a8ca1
+        virLibConnError(dconn, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
Daniel Veillard 4a8ca1
+        return -1;
Daniel Veillard 4a8ca1
+    }
Daniel Veillard 4a8ca1
+
Daniel Veillard 4a8ca1
     if (dconn->driver->domainMigratePrepare)
Daniel Veillard 4a8ca1
         return dconn->driver->domainMigratePrepare (dconn, cookie, cookielen,
Daniel Veillard 4a8ca1
                                                     uri_in, uri_out,
Daniel Veillard 4a8ca1
@@ -2457,6 +2472,11 @@ virDomainMigratePerform (virDomainPtr do
Daniel Veillard 4a8ca1
     }
Daniel Veillard 4a8ca1
     conn = domain->conn;
Daniel Veillard 4a8ca1
 
Daniel Veillard 4a8ca1
+    if (domain->conn->flags & VIR_CONNECT_RO) {
Daniel Veillard 4a8ca1
+        virLibDomainError(domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
Daniel Veillard 4a8ca1
+        return -1;
Daniel Veillard 4a8ca1
+    }
Daniel Veillard 4a8ca1
+
Daniel Veillard 4a8ca1
     if (conn->driver->domainMigratePerform)
Daniel Veillard 4a8ca1
         return conn->driver->domainMigratePerform (domain, cookie, cookielen,
Daniel Veillard 4a8ca1
                                                    uri,
Daniel Veillard 4a8ca1
@@ -2482,6 +2502,11 @@ virDomainMigrateFinish (virConnectPtr dc
Daniel Veillard 4a8ca1
 
Daniel Veillard 4a8ca1
     if (!VIR_IS_CONNECT (dconn)) {
Daniel Veillard 4a8ca1
         virLibConnError (NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
Daniel Veillard 4a8ca1
+        return NULL;
Daniel Veillard 4a8ca1
+    }
Daniel Veillard 4a8ca1
+
Daniel Veillard 4a8ca1
+    if (dconn->flags & VIR_CONNECT_RO) {
Daniel Veillard 4a8ca1
+        virLibConnError(dconn, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
Daniel Veillard 4a8ca1
         return NULL;
Daniel Veillard 4a8ca1
     }
Daniel Veillard 4a8ca1
 
Daniel Veillard 4a8ca1
@@ -2517,6 +2542,11 @@ virDomainMigratePrepare2 (virConnectPtr 
Daniel Veillard 4a8ca1
         return -1;
Daniel Veillard 4a8ca1
     }
Daniel Veillard 4a8ca1
 
Daniel Veillard 4a8ca1
+    if (dconn->flags & VIR_CONNECT_RO) {
Daniel Veillard 4a8ca1
+        virLibConnError(dconn, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
Daniel Veillard 4a8ca1
+        return -1;
Daniel Veillard 4a8ca1
+    }
Daniel Veillard 4a8ca1
+
Daniel Veillard 4a8ca1
     if (dconn->driver->domainMigratePrepare2)
Daniel Veillard 4a8ca1
         return dconn->driver->domainMigratePrepare2 (dconn, cookie, cookielen,
Daniel Veillard 4a8ca1
                                                      uri_in, uri_out,
Daniel Veillard 4a8ca1
@@ -2547,6 +2577,11 @@ virDomainMigrateFinish2 (virConnectPtr d
Daniel Veillard 4a8ca1
         return NULL;
Daniel Veillard 4a8ca1
     }
Daniel Veillard 4a8ca1
 
Daniel Veillard 4a8ca1
+    if (dconn->flags & VIR_CONNECT_RO) {
Daniel Veillard 4a8ca1
+        virLibConnError(dconn, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
Daniel Veillard 4a8ca1
+        return NULL;
Daniel Veillard 4a8ca1
+    }
Daniel Veillard 4a8ca1
+
Daniel Veillard 4a8ca1
     if (dconn->driver->domainMigrateFinish2)
Daniel Veillard 4a8ca1
         return dconn->driver->domainMigrateFinish2 (dconn, dname,
Daniel Veillard 4a8ca1
                                                     cookie, cookielen,
Daniel Veillard 4a8ca1
@@ -2905,6 +2940,11 @@ virDomainBlockPeek (virDomainPtr dom,
Daniel Veillard 4a8ca1
     }
Daniel Veillard 4a8ca1
     conn = dom->conn;
Daniel Veillard 4a8ca1
 
Daniel Veillard 4a8ca1
+    if (dom->conn->flags & VIR_CONNECT_RO) {
Daniel Veillard 4a8ca1
+        virLibDomainError(dom, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
Daniel Veillard 4a8ca1
+        return (-1);
Daniel Veillard 4a8ca1
+    }
Daniel Veillard 4a8ca1
+
Daniel Veillard 4a8ca1
     if (!path) {
Daniel Veillard 4a8ca1
         virLibDomainError (dom, VIR_ERR_INVALID_ARG,
Daniel Veillard 4a8ca1
                            _("path is NULL"));
Daniel Veillard 4a8ca1
@@ -2980,6 +3020,11 @@ virDomainMemoryPeek (virDomainPtr dom,
Daniel Veillard 4a8ca1
     }
Daniel Veillard 4a8ca1
     conn = dom->conn;
Daniel Veillard 4a8ca1
 
Daniel Veillard 4a8ca1
+    if (dom->conn->flags & VIR_CONNECT_RO) {
Daniel Veillard 4a8ca1
+        virLibDomainError(dom, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
Daniel Veillard 4a8ca1
+        return (-1);
Daniel Veillard 4a8ca1
+    }
Daniel Veillard 4a8ca1
+
Daniel Veillard 4a8ca1
     /* Flags must be VIR_MEMORY_VIRTUAL at the moment.
Daniel Veillard 4a8ca1
      *
Daniel Veillard 4a8ca1
      * Note on access to physical memory: A VIR_MEMORY_PHYSICAL flag is
Daniel Veillard 4a8ca1
@@ -3246,6 +3291,11 @@ virDomainSetAutostart(virDomainPtr domai
Daniel Veillard 4a8ca1
     }
Daniel Veillard 4a8ca1
 
Daniel Veillard 4a8ca1
     conn = domain->conn;
Daniel Veillard 4a8ca1
+
Daniel Veillard 4a8ca1
+    if (domain->conn->flags & VIR_CONNECT_RO) {
Daniel Veillard 4a8ca1
+        virLibDomainError(domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
Daniel Veillard 4a8ca1
+        return (-1);
Daniel Veillard 4a8ca1
+    }
Daniel Veillard 4a8ca1
 
Daniel Veillard 4a8ca1
     if (conn->driver->domainSetAutostart)
Daniel Veillard 4a8ca1
         return conn->driver->domainSetAutostart (domain, autostart);
Daniel Veillard 4a8ca1
@@ -4197,6 +4247,11 @@ virNetworkSetAutostart(virNetworkPtr net
Daniel Veillard 4a8ca1
         return (-1);
Daniel Veillard 4a8ca1
     }
Daniel Veillard 4a8ca1
 
Daniel Veillard 4a8ca1
+    if (network->conn->flags & VIR_CONNECT_RO) {
Daniel Veillard 4a8ca1
+        virLibNetworkError(network, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
Daniel Veillard 4a8ca1
+        return (-1);
Daniel Veillard 4a8ca1
+    }
Daniel Veillard 4a8ca1
+
Daniel Veillard 4a8ca1
     conn = network->conn;
Daniel Veillard 4a8ca1
 
Daniel Veillard 4a8ca1
     if (conn->networkDriver && conn->networkDriver->networkSetAutostart)
Daniel Veillard 4a8ca1
@@ -4395,6 +4450,11 @@ virConnectFindStoragePoolSources(virConn
Daniel Veillard 4a8ca1
         return NULL;
Daniel Veillard 4a8ca1
     }
Daniel Veillard 4a8ca1
 
Daniel Veillard 4a8ca1
+    if (conn->flags & VIR_CONNECT_RO) {
Daniel Veillard 4a8ca1
+        virLibConnError(conn, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
Daniel Veillard 4a8ca1
+        return NULL;
Daniel Veillard 4a8ca1
+    }
Daniel Veillard 4a8ca1
+
Daniel Veillard 4a8ca1
     if (conn->storageDriver && conn->storageDriver->findPoolSources)
Daniel Veillard 4a8ca1
         return conn->storageDriver->findPoolSources(conn, type, srcSpec, flags);
Daniel Veillard 4a8ca1
 
Daniel Veillard 4a8ca1
@@ -5068,6 +5128,11 @@ virStoragePoolSetAutostart(virStoragePoo
Daniel Veillard 4a8ca1
         return (-1);
Daniel Veillard 4a8ca1
     }
Daniel Veillard 4a8ca1
 
Daniel Veillard 4a8ca1
+    if (pool->conn->flags & VIR_CONNECT_RO) {
Daniel Veillard 4a8ca1
+        virLibStoragePoolError(pool, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
Daniel Veillard 4a8ca1
+        return (-1);
Daniel Veillard 4a8ca1
+    }
Daniel Veillard 4a8ca1
+
Daniel Veillard 4a8ca1
     conn = pool->conn;
Daniel Veillard 4a8ca1
 
Daniel Veillard 4a8ca1
     if (conn->storageDriver && conn->storageDriver->poolSetAutostart)