[libvirt] [PATCH 3/3] Implmentation of new APIs to checking state/persistence of objects

Daniel P. Berrange berrange at redhat.com
Wed Oct 21 18:15:25 UTC 2009


This implements the virConnectIsSecure, virConnectIsEncrypted,
virDomainIsPersistent, virDomainIsActive, virNetworkIsActive,
virNetworkIsPersistent, virStoragePoolIsActive,
virStoragePoolIsPersistent, virInterfaceIsActive APIs in
(nearly) all drivers. Exceptions are:

 phyp: missing domainIsActive/Persistent
 esx: missing domainIsPersistent
 opennebula: missing domainIsActive/Persistent

* src/remote/remote_protocol.x: Define remote wire ABI for newly
  added APIs.
* daemon/remote_dispatch*.h: Re-generated from remote_protocol.x
* src/esx/esx_driver.c, src/lxc/lxc_driver.c, src/network/bridge_driver.c,
  src/opennebula/one_driver.c, src/openvz/openvz_conf.c,
  src/openvz/openvz_driver.c, src/phyp/phyp_driver.c,
  src/remote/remote_driver.c, src/storage/storage_driver.c,
  src/test/test_driver.c, src/uml/uml_driver.c, src/vbox/vbox_tmpl.c,
  src/xen/xen_driver.c, src/xen/xen_driver.h, src/xen/xen_inotify.c,
  src/xen/xen_inotify.h: Implement all the new APIs where possible
---
 daemon/remote.c                     |  202 ++++++++++++++++++++++++++
 daemon/remote_dispatch_args.h       |    7 +
 daemon/remote_dispatch_prototypes.h |   64 +++++++++
 daemon/remote_dispatch_ret.h        |    8 +
 daemon/remote_dispatch_table.h      |   40 ++++++
 src/esx/esx_driver.c                |  106 +++++++++++++-
 src/lxc/lxc_driver.c                |   68 +++++++++-
 src/network/bridge_driver.c         |   50 ++++++-
 src/opennebula/one_driver.c         |   21 +++-
 src/openvz/openvz_conf.c            |    2 +
 src/openvz/openvz_driver.c          |   66 ++++++++-
 src/phyp/phyp_driver.c              |   25 +++-
 src/qemu/qemu_driver.c              |   65 ++++++++-
 src/remote/remote_driver.c          |  266 +++++++++++++++++++++++++++++++++--
 src/remote/remote_protocol.c        |  137 ++++++++++++++++++-
 src/remote/remote_protocol.h        |  112 +++++++++++++++
 src/remote/remote_protocol.x        |   87 +++++++++++-
 src/storage/storage_driver.c        |   46 ++++++
 src/test/test_driver.c              |  184 +++++++++++++++++++++++--
 src/uml/uml_driver.c                |   67 ++++++++-
 src/vbox/vbox_tmpl.c                |  108 ++++++++++++++-
 src/xen/xen_driver.c                |   98 ++++++++++++-
 src/xen/xen_driver.h                |    2 +
 src/xen/xen_inotify.c               |    8 +-
 src/xen/xen_inotify.h               |    1 +
 25 files changed, 1772 insertions(+), 68 deletions(-)

diff --git a/daemon/remote.c b/daemon/remote.c
index 4296fc3..1f239cd 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -5005,6 +5005,208 @@ remoteDispatchSecretLookupByUsage (struct qemud_server *server ATTRIBUTE_UNUSED,
 }
 
 
+static int remoteDispatchDomainIsActive(struct qemud_server *server ATTRIBUTE_UNUSED,
+                                        struct qemud_client *client ATTRIBUTE_UNUSED,
+                                        virConnectPtr conn,
+                                        remote_message_header *hdr ATTRIBUTE_UNUSED,
+                                        remote_error *err,
+                                        remote_domain_is_active_args *args,
+                                        remote_domain_is_active_ret *ret)
+{
+    virDomainPtr domain;
+
+    domain = get_nonnull_domain(conn, args->dom);
+    if (domain == NULL) {
+        remoteDispatchConnError(err, conn);
+        return -1;
+    }
+
+    ret->active = virDomainIsActive(domain);
+
+    if (ret->active < 0) {
+        remoteDispatchConnError(err, conn);
+        return -1;
+    }
+
+    return 0;
+}
+
+static int remoteDispatchDomainIsPersistent(struct qemud_server *server ATTRIBUTE_UNUSED,
+                                            struct qemud_client *client ATTRIBUTE_UNUSED,
+                                            virConnectPtr conn,
+                                            remote_message_header *hdr ATTRIBUTE_UNUSED,
+                                            remote_error *err,
+                                            remote_domain_is_persistent_args *args,
+                                            remote_domain_is_persistent_ret *ret)
+{
+    virDomainPtr domain;
+
+    domain = get_nonnull_domain(conn, args->dom);
+    if (domain == NULL) {
+        remoteDispatchConnError(err, conn);
+        return -1;
+    }
+
+    ret->persistent = virDomainIsPersistent(domain);
+
+    if (ret->persistent < 0) {
+        remoteDispatchConnError(err, conn);
+        return -1;
+    }
+
+    return 0;
+}
+
+static int remoteDispatchInterfaceIsActive(struct qemud_server *server ATTRIBUTE_UNUSED,
+                                           struct qemud_client *client ATTRIBUTE_UNUSED,
+                                           virConnectPtr conn,
+                                           remote_message_header *hdr ATTRIBUTE_UNUSED,
+                                           remote_error *err,
+                                           remote_interface_is_active_args *args,
+                                           remote_interface_is_active_ret *ret)
+{
+    virInterfacePtr iface;
+
+    iface = get_nonnull_interface(conn, args->iface);
+    if (iface == NULL) {
+        remoteDispatchConnError(err, conn);
+        return -1;
+    }
+
+    ret->active = virInterfaceIsActive(iface);
+
+    if (ret->active < 0) {
+        remoteDispatchConnError(err, conn);
+        return -1;
+    }
+
+    return 0;
+}
+
+static int remoteDispatchNetworkIsActive(struct qemud_server *server ATTRIBUTE_UNUSED,
+                                         struct qemud_client *client ATTRIBUTE_UNUSED,
+                                         virConnectPtr conn,
+                                         remote_message_header *hdr ATTRIBUTE_UNUSED,
+                                         remote_error *err,
+                                         remote_network_is_active_args *args,
+                                         remote_network_is_active_ret *ret)
+{
+    virNetworkPtr network;
+
+    network = get_nonnull_network(conn, args->net);
+    if (network == NULL) {
+        remoteDispatchConnError(err, conn);
+        return -1;
+    }
+
+    ret->active = virNetworkIsActive(network);
+
+    if (ret->active < 0) {
+        remoteDispatchConnError(err, conn);
+        return -1;
+    }
+
+    return 0;
+}
+
+static int remoteDispatchNetworkIsPersistent(struct qemud_server *server ATTRIBUTE_UNUSED,
+                                             struct qemud_client *client ATTRIBUTE_UNUSED,
+                                             virConnectPtr conn,
+                                             remote_message_header *hdr ATTRIBUTE_UNUSED,
+                                             remote_error *err,
+                                             remote_network_is_persistent_args *args,
+                                             remote_network_is_persistent_ret *ret)
+{
+    virNetworkPtr network;
+
+    network = get_nonnull_network(conn, args->net);
+    if (network == NULL) {
+        remoteDispatchConnError(err, conn);
+        return -1;
+    }
+
+    ret->persistent = virNetworkIsPersistent(network);
+
+    if (ret->persistent < 0) {
+        remoteDispatchConnError(err, conn);
+        return -1;
+    }
+
+    return 0;
+}
+
+static int remoteDispatchStoragePoolIsActive(struct qemud_server *server ATTRIBUTE_UNUSED,
+                                             struct qemud_client *client ATTRIBUTE_UNUSED,
+                                             virConnectPtr conn,
+                                             remote_message_header *hdr ATTRIBUTE_UNUSED,
+                                             remote_error *err,
+                                             remote_storage_pool_is_active_args *args,
+                                             remote_storage_pool_is_active_ret *ret)
+{
+    virStoragePoolPtr pool;
+
+    pool = get_nonnull_storage_pool(conn, args->pool);
+    if (pool == NULL) {
+        remoteDispatchConnError(err, conn);
+        return -1;
+    }
+
+    ret->active = virStoragePoolIsActive(pool);
+
+    if (ret->active < 0) {
+        remoteDispatchConnError(err, conn);
+        return -1;
+    }
+
+    return 0;
+}
+
+static int remoteDispatchStoragePoolIsPersistent(struct qemud_server *server ATTRIBUTE_UNUSED,
+                                                 struct qemud_client *client ATTRIBUTE_UNUSED,
+                                                 virConnectPtr conn,
+                                                 remote_message_header *hdr ATTRIBUTE_UNUSED,
+                                                 remote_error *err,
+                                                 remote_storage_pool_is_persistent_args *args,
+                                                 remote_storage_pool_is_persistent_ret *ret)
+{
+    virStoragePoolPtr pool;
+
+    pool = get_nonnull_storage_pool(conn, args->pool);
+    if (pool == NULL) {
+        remoteDispatchConnError(err, conn);
+        return -1;
+    }
+
+    ret->persistent = virStoragePoolIsPersistent(pool);
+
+    if (ret->persistent < 0) {
+        remoteDispatchConnError(err, conn);
+        return -1;
+    }
+
+    return 0;
+}
+
+
+static int remoteDispatchIsSecure(struct qemud_server *server ATTRIBUTE_UNUSED,
+                                  struct qemud_client *client ATTRIBUTE_UNUSED,
+                                  virConnectPtr conn,
+                                  remote_message_header *hdr ATTRIBUTE_UNUSED,
+                                  remote_error *err,
+                                  void *args ATTRIBUTE_UNUSED,
+                                  remote_is_secure_ret *ret)
+{
+    ret->secure = virConnectIsSecure(conn);
+
+    if (ret->secure < 0) {
+        remoteDispatchConnError(err, conn);
+        return -1;
+    }
+
+    return 0;
+}
+
+
 /*----- Helpers. -----*/
 
 /* get_nonnull_domain and get_nonnull_network turn an on-wire
diff --git a/daemon/remote_dispatch_args.h b/daemon/remote_dispatch_args.h
index aceead1..87dcdae 100644
--- a/daemon/remote_dispatch_args.h
+++ b/daemon/remote_dispatch_args.h
@@ -126,3 +126,10 @@
     remote_secret_undefine_args val_remote_secret_undefine_args;
     remote_secret_lookup_by_usage_args val_remote_secret_lookup_by_usage_args;
     remote_domain_migrate_prepare_tunnel_args val_remote_domain_migrate_prepare_tunnel_args;
+    remote_domain_is_active_args val_remote_domain_is_active_args;
+    remote_domain_is_persistent_args val_remote_domain_is_persistent_args;
+    remote_network_is_active_args val_remote_network_is_active_args;
+    remote_network_is_persistent_args val_remote_network_is_persistent_args;
+    remote_storage_pool_is_active_args val_remote_storage_pool_is_active_args;
+    remote_storage_pool_is_persistent_args val_remote_storage_pool_is_persistent_args;
+    remote_interface_is_active_args val_remote_interface_is_active_args;
diff --git a/daemon/remote_dispatch_prototypes.h b/daemon/remote_dispatch_prototypes.h
index 9afd2c7..7c2da07 100644
--- a/daemon/remote_dispatch_prototypes.h
+++ b/daemon/remote_dispatch_prototypes.h
@@ -226,6 +226,22 @@ static int remoteDispatchDomainInterfaceStats(
     remote_error *err,
     remote_domain_interface_stats_args *args,
     remote_domain_interface_stats_ret *ret);
+static int remoteDispatchDomainIsActive(
+    struct qemud_server *server,
+    struct qemud_client *client,
+    virConnectPtr conn,
+    remote_message_header *hdr,
+    remote_error *err,
+    remote_domain_is_active_args *args,
+    remote_domain_is_active_ret *ret);
+static int remoteDispatchDomainIsPersistent(
+    struct qemud_server *server,
+    struct qemud_client *client,
+    virConnectPtr conn,
+    remote_message_header *hdr,
+    remote_error *err,
+    remote_domain_is_persistent_args *args,
+    remote_domain_is_persistent_ret *ret);
 static int remoteDispatchDomainLookupById(
     struct qemud_server *server,
     struct qemud_client *client,
@@ -514,6 +530,14 @@ static int remoteDispatchInterfaceGetXmlDesc(
     remote_error *err,
     remote_interface_get_xml_desc_args *args,
     remote_interface_get_xml_desc_ret *ret);
+static int remoteDispatchInterfaceIsActive(
+    struct qemud_server *server,
+    struct qemud_client *client,
+    virConnectPtr conn,
+    remote_message_header *hdr,
+    remote_error *err,
+    remote_interface_is_active_args *args,
+    remote_interface_is_active_ret *ret);
 static int remoteDispatchInterfaceLookupByMacString(
     struct qemud_server *server,
     struct qemud_client *client,
@@ -538,6 +562,14 @@ static int remoteDispatchInterfaceUndefine(
     remote_error *err,
     remote_interface_undefine_args *args,
     void *ret);
+static int remoteDispatchIsSecure(
+    struct qemud_server *server,
+    struct qemud_client *client,
+    virConnectPtr conn,
+    remote_message_header *hdr,
+    remote_error *err,
+    void *args,
+    remote_is_secure_ret *ret);
 static int remoteDispatchListDefinedDomains(
     struct qemud_server *server,
     struct qemud_client *client,
@@ -666,6 +698,22 @@ static int remoteDispatchNetworkGetBridgeName(
     remote_error *err,
     remote_network_get_bridge_name_args *args,
     remote_network_get_bridge_name_ret *ret);
+static int remoteDispatchNetworkIsActive(
+    struct qemud_server *server,
+    struct qemud_client *client,
+    virConnectPtr conn,
+    remote_message_header *hdr,
+    remote_error *err,
+    remote_network_is_active_args *args,
+    remote_network_is_active_ret *ret);
+static int remoteDispatchNetworkIsPersistent(
+    struct qemud_server *server,
+    struct qemud_client *client,
+    virConnectPtr conn,
+    remote_message_header *hdr,
+    remote_error *err,
+    remote_network_is_persistent_args *args,
+    remote_network_is_persistent_ret *ret);
 static int remoteDispatchNetworkLookupByName(
     struct qemud_server *server,
     struct qemud_client *client,
@@ -1034,6 +1082,22 @@ static int remoteDispatchStoragePoolGetInfo(
     remote_error *err,
     remote_storage_pool_get_info_args *args,
     remote_storage_pool_get_info_ret *ret);
+static int remoteDispatchStoragePoolIsActive(
+    struct qemud_server *server,
+    struct qemud_client *client,
+    virConnectPtr conn,
+    remote_message_header *hdr,
+    remote_error *err,
+    remote_storage_pool_is_active_args *args,
+    remote_storage_pool_is_active_ret *ret);
+static int remoteDispatchStoragePoolIsPersistent(
+    struct qemud_server *server,
+    struct qemud_client *client,
+    virConnectPtr conn,
+    remote_message_header *hdr,
+    remote_error *err,
+    remote_storage_pool_is_persistent_args *args,
+    remote_storage_pool_is_persistent_ret *ret);
 static int remoteDispatchStoragePoolListVolumes(
     struct qemud_server *server,
     struct qemud_client *client,
diff --git a/daemon/remote_dispatch_ret.h b/daemon/remote_dispatch_ret.h
index 6ced13a..c37744a 100644
--- a/daemon/remote_dispatch_ret.h
+++ b/daemon/remote_dispatch_ret.h
@@ -106,3 +106,11 @@
     remote_secret_get_xml_desc_ret val_remote_secret_get_xml_desc_ret;
     remote_secret_get_value_ret val_remote_secret_get_value_ret;
     remote_secret_lookup_by_usage_ret val_remote_secret_lookup_by_usage_ret;
+    remote_is_secure_ret val_remote_is_secure_ret;
+    remote_domain_is_active_ret val_remote_domain_is_active_ret;
+    remote_domain_is_persistent_ret val_remote_domain_is_persistent_ret;
+    remote_network_is_active_ret val_remote_network_is_active_ret;
+    remote_network_is_persistent_ret val_remote_network_is_persistent_ret;
+    remote_storage_pool_is_active_ret val_remote_storage_pool_is_active_ret;
+    remote_storage_pool_is_persistent_ret val_remote_storage_pool_is_persistent_ret;
+    remote_interface_is_active_ret val_remote_interface_is_active_ret;
diff --git a/daemon/remote_dispatch_table.h b/daemon/remote_dispatch_table.h
index bb13f4c..cb640b6 100644
--- a/daemon/remote_dispatch_table.h
+++ b/daemon/remote_dispatch_table.h
@@ -747,3 +747,43 @@
     .args_filter = (xdrproc_t) xdr_remote_domain_migrate_prepare_tunnel_args,
     .ret_filter = (xdrproc_t) xdr_void,
 },
+{   /* IsSecure => 149 */
+    .fn = (dispatch_fn) remoteDispatchIsSecure,
+    .args_filter = (xdrproc_t) xdr_void,
+    .ret_filter = (xdrproc_t) xdr_remote_is_secure_ret,
+},
+{   /* DomainIsActive => 150 */
+    .fn = (dispatch_fn) remoteDispatchDomainIsActive,
+    .args_filter = (xdrproc_t) xdr_remote_domain_is_active_args,
+    .ret_filter = (xdrproc_t) xdr_remote_domain_is_active_ret,
+},
+{   /* DomainIsPersistent => 151 */
+    .fn = (dispatch_fn) remoteDispatchDomainIsPersistent,
+    .args_filter = (xdrproc_t) xdr_remote_domain_is_persistent_args,
+    .ret_filter = (xdrproc_t) xdr_remote_domain_is_persistent_ret,
+},
+{   /* NetworkIsActive => 152 */
+    .fn = (dispatch_fn) remoteDispatchNetworkIsActive,
+    .args_filter = (xdrproc_t) xdr_remote_network_is_active_args,
+    .ret_filter = (xdrproc_t) xdr_remote_network_is_active_ret,
+},
+{   /* NetworkIsPersistent => 153 */
+    .fn = (dispatch_fn) remoteDispatchNetworkIsPersistent,
+    .args_filter = (xdrproc_t) xdr_remote_network_is_persistent_args,
+    .ret_filter = (xdrproc_t) xdr_remote_network_is_persistent_ret,
+},
+{   /* StoragePoolIsActive => 154 */
+    .fn = (dispatch_fn) remoteDispatchStoragePoolIsActive,
+    .args_filter = (xdrproc_t) xdr_remote_storage_pool_is_active_args,
+    .ret_filter = (xdrproc_t) xdr_remote_storage_pool_is_active_ret,
+},
+{   /* StoragePoolIsPersistent => 155 */
+    .fn = (dispatch_fn) remoteDispatchStoragePoolIsPersistent,
+    .args_filter = (xdrproc_t) xdr_remote_storage_pool_is_persistent_args,
+    .ret_filter = (xdrproc_t) xdr_remote_storage_pool_is_persistent_ret,
+},
+{   /* InterfaceIsActive => 156 */
+    .fn = (dispatch_fn) remoteDispatchInterfaceIsActive,
+    .args_filter = (xdrproc_t) xdr_remote_interface_is_active_args,
+    .ret_filter = (xdrproc_t) xdr_remote_interface_is_active_ret,
+},
diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c
index 3a57613..c3d1eac 100644
--- a/src/esx/esx_driver.c
+++ b/src/esx/esx_driver.c
@@ -503,6 +503,30 @@ esxClose(virConnectPtr conn)
 }
 
 
+static int
+esxIsSecure(virConnectPtr conn)
+{
+    esxPrivate *priv = (esxPrivate *)conn->privateData;
+
+    if (STRCASEEQ(priv->transport, "https")) {
+        return 1;
+    } else {
+        return 0;
+    }
+}
+
+
+static int
+esxIsEncrypted(virConnectPtr conn)
+{
+    esxPrivate *priv = (esxPrivate *)conn->privateData;
+
+    if (STRCASEEQ(priv->transport, "https")) {
+        return 1;
+    } else {
+        return 0;
+    }
+}
 
 static esxVI_Boolean
 esxSupportsVMotion(virConnectPtr conn)
@@ -1227,6 +1251,80 @@ esxDomainLookupByName(virConnectPtr conn, const char *name)
 }
 
 
+static int
+esxDomainIsActive(virDomainPtr dom)
+{
+    esxPrivate *priv = (esxPrivate *)dom->conn->privateData;
+    esxVI_String *propertyNameList = NULL;
+    esxVI_ObjectContent *virtualMachineList = NULL;
+    esxVI_ObjectContent *virtualMachine = NULL;
+    esxVI_VirtualMachinePowerState powerState;
+    int id_candidate = -1;
+    char *name_candidate = NULL;
+    unsigned char uuid_candidate[VIR_UUID_BUFLEN];
+    char uuid_string[VIR_UUID_STRING_BUFLEN];
+    int ret = -1;
+
+    if (esxVI_EnsureSession(dom->conn, priv->host) < 0) {
+        goto cleanup;
+    }
+
+    if (esxVI_String_AppendValueListToList(dom->conn, &propertyNameList,
+                                           "configStatus\0"
+                                           "name\0"
+                                           "runtime.powerState\0"
+                                           "config.uuid\0") < 0 ||
+        esxVI_GetObjectContent(dom->conn, priv->host, priv->host->vmFolder,
+                               "VirtualMachine", propertyNameList,
+                               esxVI_Boolean_True, &virtualMachineList) < 0) {
+        goto cleanup;
+    }
+
+    for (virtualMachine = virtualMachineList; virtualMachine != NULL;
+         virtualMachine = virtualMachine->_next) {
+        VIR_FREE(name_candidate);
+
+        if (esxVI_GetVirtualMachineIdentity(dom->conn, virtualMachine,
+                                            &id_candidate, &name_candidate,
+                                            uuid_candidate) < 0) {
+            goto cleanup;
+        }
+
+        if (memcmp(dom->uuid, uuid_candidate,
+                   VIR_UUID_BUFLEN * sizeof(unsigned char)) != 0) {
+            continue;
+        }
+
+        if (esxVI_GetVirtualMachinePowerState(dom->conn, virtualMachine,
+                                              &powerState) < 0) {
+            goto cleanup;
+        }
+
+        /* Only running/suspended virtual machines have an ID != -1 */
+        if (powerState != esxVI_VirtualMachinePowerState_PoweredOff) {
+            ret = 1;
+        } else {
+            ret = 0;
+        }
+
+        break;
+    }
+
+    if (ret == -1) {
+        virUUIDFormat(dom->uuid, uuid_string);
+
+        ESX_ERROR(dom->conn, VIR_ERR_NO_DOMAIN, "No domain with UUID '%s'",
+                  uuid_string);
+    }
+
+  cleanup:
+    esxVI_String_Free(&propertyNameList);
+    esxVI_ObjectContent_Free(&virtualMachineList);
+    VIR_FREE(name_candidate);
+
+    return ret;
+}
+
 
 static int
 esxDomainSuspend(virDomainPtr domain)
@@ -3275,10 +3373,10 @@ static virDriver esxDriver = {
     NULL,                            /* nodeDeviceReAttach */
     NULL,                            /* nodeDeviceReset */
     NULL,                            /* domainMigratePrepareTunnel */
-    NULL, /* isEncrypted */
-    NULL, /* isSecure */
-    NULL, /* domainIsActive */
-    NULL, /* domainIsEncrypted */
+    esxIsEncrypted,                  /* isEncrypted */
+    esxIsSecure,                     /* isSecure */
+    esxDomainIsActive,               /* domainIsActive */
+    NULL,                            /* domainIsPersistent */
 };
 
 
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index 92502fe..313342e 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -128,6 +128,21 @@ static int lxcClose(virConnectPtr conn)
     return 0;
 }
 
+
+static int lxcIsSecure(virConnectPtr conn ATTRIBUTE_UNUSED)
+{
+    /* Trivially secure, since always inside the daemon */
+    return 1;
+}
+
+
+static int lxcIsEncrypted(virConnectPtr conn ATTRIBUTE_UNUSED)
+{
+    /* Not encrypted, but remote driver takes care of that */
+    return 0;
+}
+
+
 static char *lxcGetCapabilities(virConnectPtr conn) {
     lxc_driver_t *driver = conn->privateData;
     char *xml;
@@ -218,6 +233,51 @@ cleanup:
     return dom;
 }
 
+
+static int lxcDomainIsActive(virDomainPtr dom)
+{
+    lxc_driver_t *driver = dom->conn->privateData;
+    virDomainObjPtr obj;
+    int ret = -1;
+
+    lxcDriverLock(driver);
+    obj = virDomainFindByUUID(&driver->domains, dom->uuid);
+    lxcDriverUnlock(driver);
+    if (!obj) {
+        lxcError(dom->conn, NULL, VIR_ERR_NO_DOMAIN, NULL);
+        goto cleanup;
+    }
+    ret = virDomainObjIsActive(obj);
+
+cleanup:
+    if (obj)
+        virDomainObjUnlock(obj);
+    return ret;
+}
+
+
+static int lxcDomainIsPersistent(virDomainPtr dom)
+{
+    lxc_driver_t *driver = dom->conn->privateData;
+    virDomainObjPtr obj;
+    int ret = -1;
+
+    lxcDriverLock(driver);
+    obj = virDomainFindByUUID(&driver->domains, dom->uuid);
+    lxcDriverUnlock(driver);
+    if (!obj) {
+        lxcError(dom->conn, NULL, VIR_ERR_NO_DOMAIN, NULL);
+        goto cleanup;
+    }
+    ret = obj->persistent;
+
+cleanup:
+    if (obj)
+        virDomainObjUnlock(obj);
+    return ret;
+}
+
+
 static int lxcListDomains(virConnectPtr conn, int *ids, int nids) {
     lxc_driver_t *driver = conn->privateData;
     int got = 0, i;
@@ -2348,10 +2408,10 @@ static virDriver lxcDriver = {
     NULL, /* nodeDeviceReAttach */
     NULL, /* nodeDeviceReset */
     NULL, /* domainMigratePrepareTunnel */
-    NULL, /* isEncrypted */
-    NULL, /* isSecure */
-    NULL, /* domainIsActive */
-    NULL, /* domainIsEncrypted */
+    lxcIsEncrypted,
+    lxcIsSecure,
+    lxcDomainIsActive,
+    lxcDomainIsPersistent,
 };
 
 static virStateDriver lxcStateDriver = {
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 311838c..60c1acc 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -1159,6 +1159,50 @@ static int networkListDefinedNetworks(virConnectPtr conn, char **const names, in
     return -1;
 }
 
+
+static int networkIsActive(virNetworkPtr net)
+{
+    struct network_driver *driver = net->conn->privateData;
+    virNetworkObjPtr obj;
+    int ret = -1;
+
+    networkDriverLock(driver);
+    obj = virNetworkFindByUUID(&driver->networks, net->uuid);
+    networkDriverUnlock(driver);
+    if (!obj) {
+        networkReportError(net->conn, NULL, NULL, VIR_ERR_NO_NETWORK, NULL);
+        goto cleanup;
+    }
+    ret = virNetworkObjIsActive(obj);
+
+cleanup:
+    if (obj)
+        virNetworkObjUnlock(obj);
+    return ret;
+}
+
+static int networkIsPersistent(virNetworkPtr net)
+{
+    struct network_driver *driver = net->conn->privateData;
+    virNetworkObjPtr obj;
+    int ret = -1;
+
+    networkDriverLock(driver);
+    obj = virNetworkFindByUUID(&driver->networks, net->uuid);
+    networkDriverUnlock(driver);
+    if (!obj) {
+        networkReportError(net->conn, NULL, NULL, VIR_ERR_NO_NETWORK, NULL);
+        goto cleanup;
+    }
+    ret = obj->persistent;
+
+cleanup:
+    if (obj)
+        virNetworkObjUnlock(obj);
+    return ret;
+}
+
+
 static virNetworkPtr networkCreate(virConnectPtr conn, const char *xml) {
     struct network_driver *driver = conn->networkPrivateData;
     virNetworkDefPtr def;
@@ -1246,7 +1290,7 @@ static int networkUndefine(virNetworkPtr net) {
 
     network = virNetworkFindByUUID(&driver->networks, net->uuid);
     if (!network) {
-        networkReportError(net->conn, NULL, net, VIR_ERR_INVALID_DOMAIN,
+        networkReportError(net->conn, NULL, net, VIR_ERR_INVALID_NETWORK,
                            "%s", _("no network with matching uuid"));
         goto cleanup;
     }
@@ -1497,8 +1541,8 @@ static virNetworkDriver networkDriver = {
     networkGetBridgeName, /* networkGetBridgeName */
     networkGetAutostart, /* networkGetAutostart */
     networkSetAutostart, /* networkSetAutostart */
-    NULL, /* networkIsActive */
-    NULL, /* networkIsEncrypted */
+    networkIsActive,
+    networkIsPersistent,
 };
 
 static virStateDriver networkStateDriver = {
diff --git a/src/opennebula/one_driver.c b/src/opennebula/one_driver.c
index 9707bf8..ba61432 100644
--- a/src/opennebula/one_driver.c
+++ b/src/opennebula/one_driver.c
@@ -90,6 +90,21 @@ static int oneClose(virConnectPtr conn)
     return 0;
 }
 
+
+static int oneIsEncrypted(virConnectPtr conn ATTRIBUTE_UNUSED)
+{
+    /* Not encrypted because it uses HTTP, not HTTPs */
+    return 0;
+}
+
+
+static int oneIsSecure(virConnectPtr conn ATTRIBUTE_UNUSED)
+{
+    /* Not secure because it uses HTTP, not HTTPs */
+    return 0;
+}
+
+
 static virDomainPtr oneDomainLookupByID(virConnectPtr conn,
                                         int id)
 {
@@ -788,10 +803,10 @@ static virDriver oneDriver = {
     NULL, /* nodeDeviceReAttach; */
     NULL, /* nodeDeviceReset; */
     NULL, /* domainMigratePrepareTunnel */
-    NULL, /* isEncrypted */
-    NULL, /* isSecure */
+    oneIsEncrypted,
+    oneIsSecure,
     NULL, /* domainIsActive */
-    NULL, /* domainIsEncrypted */
+    NULL, /* domainIsPersistent */
 };
 
 static virStateDriver oneStateDriver = {
diff --git a/src/openvz/openvz_conf.c b/src/openvz/openvz_conf.c
index 403f537..83687a2 100644
--- a/src/openvz/openvz_conf.c
+++ b/src/openvz/openvz_conf.c
@@ -473,6 +473,8 @@ int openvzLoadDomains(struct openvz_driver *driver) {
 
         dom->pid = veid;
         dom->def->id = dom->state == VIR_DOMAIN_SHUTOFF ? -1 : veid;
+        /* XXX OpenVZ doesn't appear to have concept of a transient domain */
+        dom->persistent = 1;
 
         if (virAsprintf(&dom->def->name, "%i", veid) < 0)
             goto no_memory;
diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c
index 4d7f56c..c9fb8a2 100644
--- a/src/openvz/openvz_driver.c
+++ b/src/openvz/openvz_driver.c
@@ -415,6 +415,50 @@ cleanup:
 }
 
 
+static int openvzDomainIsActive(virDomainPtr dom)
+{
+    struct openvz_driver *driver = dom->conn->privateData;
+    virDomainObjPtr obj;
+    int ret = -1;
+
+    openvzDriverLock(driver);
+    obj = virDomainFindByUUID(&driver->domains, dom->uuid);
+    openvzDriverUnlock(driver);
+    if (!obj) {
+        openvzError(dom->conn, VIR_ERR_NO_DOMAIN, NULL);
+        goto cleanup;
+    }
+    ret = virDomainObjIsActive(obj);
+
+cleanup:
+    if (obj)
+        virDomainObjUnlock(obj);
+    return ret;
+}
+
+
+static int openvzDomainIsPersistent(virDomainPtr dom)
+{
+    struct openvz_driver *driver = dom->conn->privateData;
+    virDomainObjPtr obj;
+    int ret = -1;
+
+    openvzDriverLock(driver);
+    obj = virDomainFindByUUID(&driver->domains, dom->uuid);
+    openvzDriverUnlock(driver);
+    if (!obj) {
+        openvzError(dom->conn, VIR_ERR_NO_DOMAIN, NULL);
+        goto cleanup;
+    }
+    ret = obj->persistent;
+
+cleanup:
+    if (obj)
+        virDomainObjUnlock(obj);
+    return ret;
+}
+
+
 static char *openvzDomainDumpXML(virDomainPtr dom, int flags) {
     struct openvz_driver *driver = dom->conn->privateData;
     virDomainObjPtr vm;
@@ -777,6 +821,7 @@ openvzDomainDefineXML(virConnectPtr conn, const char *xml)
     if (!(vm = virDomainAssignDef(conn, &driver->domains, vmdef)))
         goto cleanup;
     vmdef = NULL;
+    vm->persistent = 1;
 
     if (openvzSetInitialConfig(conn, vm->def) < 0) {
         openvzError(conn, VIR_ERR_INTERNAL_ERROR,
@@ -844,6 +889,9 @@ openvzDomainCreateXML(virConnectPtr conn, const char *xml,
     if (!(vm = virDomainAssignDef(conn, &driver->domains, vmdef)))
         goto cleanup;
     vmdef = NULL;
+    /* All OpenVZ domains seem to be persistent - this is a bit of a violation
+     * of this libvirt API which is intended for transient domain creation */
+    vm->persistent = 1;
 
     if (openvzSetInitialConfig(conn, vm->def) < 0) {
         openvzError(conn, VIR_ERR_INTERNAL_ERROR,
@@ -1199,6 +1247,16 @@ static const char *openvzGetType(virConnectPtr conn ATTRIBUTE_UNUSED) {
     return "OpenVZ";
 }
 
+static int openvzIsEncrypted(virConnectPtr conn ATTRIBUTE_UNUSED) {
+    /* Encryption is not relevant / applicable to way we talk to openvz */
+    return 0;
+}
+
+static int openvzIsSecure(virConnectPtr conn ATTRIBUTE_UNUSED) {
+    /* We run CLI tools directly so this is secure */
+    return 1;
+}
+
 static char *openvzGetCapabilities(virConnectPtr conn) {
     struct openvz_driver *driver = conn->privateData;
     char *ret;
@@ -1433,10 +1491,10 @@ static virDriver openvzDriver = {
     NULL, /* nodeDeviceReAttach */
     NULL, /* nodeDeviceReset */
     NULL, /* domainMigratePrepareTunnel */
-    NULL, /* isEncrypted */
-    NULL, /* isSecure */
-    NULL, /* domainIsActive */
-    NULL, /* domainIsEncrypted */
+    openvzIsEncrypted,
+    openvzIsSecure,
+    openvzDomainIsActive,
+    openvzDomainIsPersistent,
 };
 
 int openvzRegister(void) {
diff --git a/src/phyp/phyp_driver.c b/src/phyp/phyp_driver.c
index cd0e9a7..52bdcce 100644
--- a/src/phyp/phyp_driver.c
+++ b/src/phyp/phyp_driver.c
@@ -159,6 +159,23 @@ phypClose(virConnectPtr conn)
     return 0;
 }
 
+
+static int
+phypIsEncrypted(virConnectPtr conn ATTRIBUTE_UNUSED)
+{
+    /* Phyp uses an SSH tunnel, so is always encrypted */
+    return 1;
+}
+
+
+static int
+phypIsSecure(virConnectPtr conn ATTRIBUTE_UNUSED)
+{
+    /* Phyp uses an SSH tunnel, so is always secure */
+    return 1;
+}
+
+
 LIBSSH2_SESSION *
 openSSHSession(virConnectPtr conn, virConnectAuthPtr auth,
                int *internal_socket)
@@ -1378,10 +1395,10 @@ virDriver phypDriver = {
     NULL,                       /* nodeDeviceReAttach */
     NULL,                       /* nodeDeviceReset */
     NULL,                       /* domainMigratePrepareTunnel */
-    NULL, /* isEncrypted */
-    NULL, /* isSecure */
-    NULL, /* domainIsActive */
-    NULL, /* domainIsEncrypted */
+    phypIsEncrypted,
+    phypIsSecure,
+    NULL,                       /* domainIsActive */
+    NULL,                       /* domainIsPersistent */
 };
 
 int
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 0264797..c98fa58 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -2395,6 +2395,19 @@ static const char *qemudGetType(virConnectPtr conn ATTRIBUTE_UNUSED) {
 }
 
 
+static int qemuIsSecure(virConnectPtr conn ATTRIBUTE_UNUSED)
+{
+    /* Trivially secure, since always inside the daemon */
+    return 1;
+}
+
+static int qemuIsEncrypted(virConnectPtr conn ATTRIBUTE_UNUSED)
+{
+    /* Not encrypted, but remote driver takes care of that */
+    return 0;
+}
+
+
 static int kvmGetMaxVCPUs(void) {
     int maxvcpus = 1;
 
@@ -2604,6 +2617,50 @@ cleanup:
     return dom;
 }
 
+
+static int qemuDomainIsActive(virDomainPtr dom)
+{
+    struct qemud_driver *driver = dom->conn->privateData;
+    virDomainObjPtr obj;
+    int ret = -1;
+
+    qemuDriverLock(driver);
+    obj = virDomainFindByUUID(&driver->domains, dom->uuid);
+    qemuDriverUnlock(driver);
+    if (!obj) {
+        qemudReportError(dom->conn, NULL, NULL, VIR_ERR_NO_DOMAIN, NULL);
+        goto cleanup;
+    }
+    ret = virDomainObjIsActive(obj);
+
+cleanup:
+    if (obj)
+        virDomainObjUnlock(obj);
+    return ret;
+}
+
+static int qemuDomainIsPersistent(virDomainPtr dom)
+{
+    struct qemud_driver *driver = dom->conn->privateData;
+    virDomainObjPtr obj;
+    int ret = -1;
+
+    qemuDriverLock(driver);
+    obj = virDomainFindByUUID(&driver->domains, dom->uuid);
+    qemuDriverUnlock(driver);
+    if (!obj) {
+        qemudReportError(dom->conn, NULL, NULL, VIR_ERR_NO_DOMAIN, NULL);
+        goto cleanup;
+    }
+    ret = obj->persistent;
+
+cleanup:
+    if (obj)
+        virDomainObjUnlock(obj);
+    return ret;
+}
+
+
 static int qemudGetVersion(virConnectPtr conn, unsigned long *version) {
     struct qemud_driver *driver = conn->privateData;
     int ret = -1;
@@ -7166,10 +7223,10 @@ static virDriver qemuDriver = {
     qemudNodeDeviceReAttach, /* nodeDeviceReAttach */
     qemudNodeDeviceReset, /* nodeDeviceReset */
     qemudDomainMigratePrepareTunnel, /* domainMigratePrepareTunnel */
-    NULL, /* isEncrypted */
-    NULL, /* isSecure */
-    NULL, /* domainIsActive */
-    NULL, /* domainIsEncrypted */
+    qemuIsEncrypted,
+    qemuIsSecure,
+    qemuDomainIsActive,
+    qemuDomainIsPersistent,
 };
 
 
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index 9a265ac..5eeba00 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -157,6 +157,7 @@ struct private_data {
     int watch;                  /* File handle watch */
     pid_t pid;                  /* PID of tunnel process */
     int uses_tls;               /* TLS enabled on socket? */
+    int is_secure;              /* Secure if TLS or SASL or UNIX sockets */
     gnutls_session_t session;   /* GnuTLS session (if uses_tls != 0). */
     char *type;                 /* Cached return from remoteType. */
     int counter;                /* Generates serial numbers for RPC. */
@@ -574,6 +575,7 @@ doRemoteOpen (virConnectPtr conn,
     case trans_tls:
         if (initialise_gnutls (conn) == -1) goto failed;
         priv->uses_tls = 1;
+        priv->is_secure = 1;
 
         /*FALLTHROUGH*/
     case trans_tcp: {
@@ -691,6 +693,7 @@ doRemoteOpen (virConnectPtr conn,
             addr.sun_path[0] = '\0';
 
       autostart_retry:
+        priv->is_secure = 1;
         priv->sock = socket (AF_UNIX, SOCK_STREAM, 0);
         if (priv->sock == -1) {
             virReportSystemError(conn, errno, "%s",
@@ -771,6 +774,8 @@ doRemoteOpen (virConnectPtr conn,
         for (j = 0; j < (nr_args-1); j++)
             if (cmd_argv[j] == NULL)
                 goto out_of_memory;
+
+        priv->is_secure = 1;
     }
 
         /*FALLTHROUGH*/
@@ -797,6 +802,10 @@ doRemoteOpen (virConnectPtr conn,
         close (sv[1]);
         priv->sock = sv[0];
         priv->pid = pid;
+
+        /* Do not set 'is_secure' flag since we can't guarentee
+         * an external program is secure, and this flag must be
+         * pessimistic */
     }
 #else /* WIN32 */
 
@@ -1562,6 +1571,72 @@ done:
     return rv;
 }
 
+static int remoteIsSecure(virConnectPtr conn)
+{
+    int rv = -1;
+    struct private_data *priv = conn->privateData;
+    remote_is_secure_ret ret;
+    remoteDriverLock(priv);
+
+    memset (&ret, 0, sizeof ret);
+    if (call (conn, priv, 0, REMOTE_PROC_IS_SECURE,
+              (xdrproc_t) xdr_void, (char *) NULL,
+              (xdrproc_t) xdr_remote_is_secure_ret, (char *) &ret) == -1)
+        goto done;
+
+    /* We claim to be secure, if the remote driver
+     * transport itself is secure, and the remote
+     * HV connection is secure
+     *
+     * ie, we don't want to claim to be secure if the
+     * remote driver is used to connect to a XenD
+     * driver using unencrypted HTTP:/// access
+     */
+    rv = priv->is_secure && ret.secure ? 1 : 0;
+
+done:
+    remoteDriverUnlock(priv);
+    return rv;
+}
+
+static int remoteIsEncrypted(virConnectPtr conn)
+{
+    int rv = -1;
+    int encrypted = 0;
+    struct private_data *priv = conn->privateData;
+    remote_is_secure_ret ret;
+    remoteDriverLock(priv);
+
+    memset (&ret, 0, sizeof ret);
+    if (call (conn, priv, 0, REMOTE_PROC_IS_SECURE,
+              (xdrproc_t) xdr_void, (char *) NULL,
+              (xdrproc_t) xdr_remote_is_secure_ret, (char *) &ret) == -1)
+        goto done;
+
+    if (priv->uses_tls)
+        encrypted = 1;
+#if HAVE_SASL
+    else if (priv->saslconn)
+        encrypted = 1;
+#endif
+
+
+    /* We claim to be encrypted, if the remote driver
+     * transport itself is encrypted, and the remote
+     * HV connection is secure.
+     *
+     * Yes, we really don't check the remote 'encrypted'
+     * option, since it will almost always be false,
+     * even if secure (eg UNIX sockets).
+     */
+    rv = encrypted && ret.secure ? 1 : 0;
+
+done:
+    remoteDriverUnlock(priv);
+    return rv;
+}
+
+
 static int
 remoteGetMaxVcpus (virConnectPtr conn, const char *type)
 {
@@ -1773,6 +1848,54 @@ done:
     return rv;
 }
 
+static int
+remoteDomainIsActive(virDomainPtr domain)
+{
+    int rv = -1;
+    remote_domain_is_active_args args;
+    remote_domain_is_active_ret ret;
+    struct private_data *priv = domain->conn->privateData;
+
+    remoteDriverLock(priv);
+
+    make_nonnull_domain (&args.dom, domain);
+
+    if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_IS_ACTIVE,
+              (xdrproc_t) xdr_remote_domain_is_active_args, (char *) &args,
+              (xdrproc_t) xdr_remote_domain_is_active_ret, (char *) &ret) == -1)
+        goto done;
+
+    rv = ret.active;
+
+done:
+    remoteDriverUnlock(priv);
+    return rv;
+}
+
+static int
+remoteDomainIsPersistent(virDomainPtr domain)
+{
+    int rv = -1;
+    remote_domain_is_persistent_args args;
+    remote_domain_is_persistent_ret ret;
+    struct private_data *priv = domain->conn->privateData;
+
+    remoteDriverLock(priv);
+
+    make_nonnull_domain (&args.dom, domain);
+
+    if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_IS_PERSISTENT,
+              (xdrproc_t) xdr_remote_domain_is_persistent_args, (char *) &args,
+              (xdrproc_t) xdr_remote_domain_is_persistent_ret, (char *) &ret) == -1)
+        goto done;
+
+    rv = ret.persistent;
+
+done:
+    remoteDriverUnlock(priv);
+    return rv;
+}
+
 static virDomainPtr
 remoteDomainCreateXML (virConnectPtr conn,
                          const char *xmlDesc,
@@ -3572,6 +3695,54 @@ done:
     return net;
 }
 
+static int
+remoteNetworkIsActive(virNetworkPtr network)
+{
+    int rv = -1;
+    remote_network_is_active_args args;
+    remote_network_is_active_ret ret;
+    struct private_data *priv = network->conn->privateData;
+
+    remoteDriverLock(priv);
+
+    make_nonnull_network (&args.net, network);
+
+    if (call (network->conn, priv, 0, REMOTE_PROC_NETWORK_IS_ACTIVE,
+              (xdrproc_t) xdr_remote_network_is_active_args, (char *) &args,
+              (xdrproc_t) xdr_remote_network_is_active_ret, (char *) &ret) == -1)
+        goto done;
+
+    rv = ret.active;
+
+done:
+    remoteDriverUnlock(priv);
+    return rv;
+}
+
+static int
+remoteNetworkIsPersistent(virNetworkPtr network)
+{
+    int rv = -1;
+    remote_network_is_persistent_args args;
+    remote_network_is_persistent_ret ret;
+    struct private_data *priv = network->conn->privateData;
+
+    remoteDriverLock(priv);
+
+    make_nonnull_network (&args.net, network);
+
+    if (call (network->conn, priv, 0, REMOTE_PROC_NETWORK_IS_PERSISTENT,
+              (xdrproc_t) xdr_remote_network_is_persistent_args, (char *) &args,
+              (xdrproc_t) xdr_remote_network_is_persistent_ret, (char *) &ret) == -1)
+        goto done;
+
+    rv = ret.persistent;
+
+done:
+    remoteDriverUnlock(priv);
+    return rv;
+}
+
 static virNetworkPtr
 remoteNetworkCreateXML (virConnectPtr conn, const char *xmlDesc)
 {
@@ -4060,6 +4231,32 @@ done:
     return iface;
 }
 
+
+static int
+remoteInterfaceIsActive(virInterfacePtr iface)
+{
+    int rv = -1;
+    remote_interface_is_active_args args;
+    remote_interface_is_active_ret ret;
+    struct private_data *priv = iface->conn->privateData;
+
+    remoteDriverLock(priv);
+
+    make_nonnull_interface (&args.iface, iface);
+
+    if (call (iface->conn, priv, 0, REMOTE_PROC_INTERFACE_IS_ACTIVE,
+              (xdrproc_t) xdr_remote_interface_is_active_args, (char *) &args,
+              (xdrproc_t) xdr_remote_interface_is_active_ret, (char *) &ret) == -1)
+        goto done;
+
+    rv = ret.active;
+
+done:
+    remoteDriverUnlock(priv);
+    return rv;
+}
+
+
 static char *
 remoteInterfaceGetXMLDesc (virInterfacePtr iface,
                            unsigned int flags)
@@ -4522,6 +4719,55 @@ done:
 }
 
 
+static int
+remoteStoragePoolIsActive(virStoragePoolPtr pool)
+{
+    int rv = -1;
+    remote_storage_pool_is_active_args args;
+    remote_storage_pool_is_active_ret ret;
+    struct private_data *priv = pool->conn->privateData;
+
+    remoteDriverLock(priv);
+
+    make_nonnull_storage_pool (&args.pool, pool);
+
+    if (call (pool->conn, priv, 0, REMOTE_PROC_STORAGE_POOL_IS_ACTIVE,
+              (xdrproc_t) xdr_remote_storage_pool_is_active_args, (char *) &args,
+              (xdrproc_t) xdr_remote_storage_pool_is_active_ret, (char *) &ret) == -1)
+        goto done;
+
+    rv = ret.active;
+
+done:
+    remoteDriverUnlock(priv);
+    return rv;
+}
+
+static int
+remoteStoragePoolIsPersistent(virStoragePoolPtr pool)
+{
+    int rv = -1;
+    remote_storage_pool_is_persistent_args args;
+    remote_storage_pool_is_persistent_ret ret;
+    struct private_data *priv = pool->conn->privateData;
+
+    remoteDriverLock(priv);
+
+    make_nonnull_storage_pool (&args.pool, pool);
+
+    if (call (pool->conn, priv, 0, REMOTE_PROC_STORAGE_POOL_IS_PERSISTENT,
+              (xdrproc_t) xdr_remote_storage_pool_is_persistent_args, (char *) &args,
+              (xdrproc_t) xdr_remote_storage_pool_is_persistent_ret, (char *) &ret) == -1)
+        goto done;
+
+    rv = ret.persistent;
+
+done:
+    remoteDriverUnlock(priv);
+    return rv;
+}
+
+
 static virStoragePoolPtr
 remoteStoragePoolCreateXML (virConnectPtr conn, const char *xmlDesc, unsigned int flags)
 {
@@ -6205,6 +6451,7 @@ remoteAuthSASL (virConnectPtr conn, struct private_data *priv, int in_open,
                              _("negotiation SSF %d was not strong enough"), ssf);
             goto cleanup;
         }
+        priv->is_secure = 1;
     }
 
     DEBUG0("SASL authentication complete");
@@ -8449,10 +8696,10 @@ static virDriver remote_driver = {
     remoteNodeDeviceReAttach, /* nodeDeviceReAttach */
     remoteNodeDeviceReset, /* nodeDeviceReset */
     remoteDomainMigratePrepareTunnel, /* domainMigratePrepareTunnel */
-    NULL, /* isEncrypted */
-    NULL, /* isSecure */
-    NULL, /* domainIsActive */
-    NULL, /* domainIsEncrypted */
+    remoteIsEncrypted, /* isEncrypted */
+    remoteIsSecure, /* isSecure */
+    remoteDomainIsActive, /* domainIsActive */
+    remoteDomainIsPersistent, /* domainIsPersistent */
 };
 
 static virNetworkDriver network_driver = {
@@ -8474,8 +8721,8 @@ static virNetworkDriver network_driver = {
     .networkGetBridgeName = remoteNetworkGetBridgeName,
     .networkGetAutostart = remoteNetworkGetAutostart,
     .networkSetAutostart = remoteNetworkSetAutostart,
-    .networkIsActive = NULL,
-    .networkIsPersistent = NULL,
+    .networkIsActive = remoteNetworkIsActive,
+    .networkIsPersistent = remoteNetworkIsPersistent,
 };
 
 static virInterfaceDriver interface_driver = {
@@ -8493,7 +8740,7 @@ static virInterfaceDriver interface_driver = {
     .interfaceUndefine = remoteInterfaceUndefine,
     .interfaceCreate = remoteInterfaceCreate,
     .interfaceDestroy = remoteInterfaceDestroy,
-    .interfaceIsActive = NULL, /* interfaceIsActive */
+    .interfaceIsActive = remoteInterfaceIsActive,
 };
 
 static virStorageDriver storage_driver = {
@@ -8532,9 +8779,8 @@ static virStorageDriver storage_driver = {
     .volGetInfo = remoteStorageVolGetInfo,
     .volGetXMLDesc = remoteStorageVolDumpXML,
     .volGetPath = remoteStorageVolGetPath,
-
-    .poolIsActive = NULL, /* poolIsActive */
-    .poolIsPersistent = NULL, /* poolIsEncrypted */
+    .poolIsActive = remoteStoragePoolIsActive,
+    .poolIsPersistent = remoteStoragePoolIsPersistent,
 };
 
 static virSecretDriver secret_driver = {
diff --git a/src/remote/remote_protocol.c b/src/remote/remote_protocol.c
index 1449ed4..b6a85a8 100644
--- a/src/remote/remote_protocol.c
+++ b/src/remote/remote_protocol.c
@@ -4,7 +4,7 @@
  * It was generated using rpcgen.
  */
 
-#include "remote_protocol.h"
+#include "./remote/remote_protocol.h"
 #include "internal.h"
 #include <arpa/inet.h>
 
@@ -2713,6 +2713,141 @@ xdr_remote_domain_migrate_prepare_tunnel_args (XDR *xdrs, remote_domain_migrate_
 }
 
 bool_t
+xdr_remote_is_secure_ret (XDR *xdrs, remote_is_secure_ret *objp)
+{
+
+         if (!xdr_int (xdrs, &objp->secure))
+                 return FALSE;
+        return TRUE;
+}
+
+bool_t
+xdr_remote_domain_is_active_args (XDR *xdrs, remote_domain_is_active_args *objp)
+{
+
+         if (!xdr_remote_nonnull_domain (xdrs, &objp->dom))
+                 return FALSE;
+        return TRUE;
+}
+
+bool_t
+xdr_remote_domain_is_active_ret (XDR *xdrs, remote_domain_is_active_ret *objp)
+{
+
+         if (!xdr_int (xdrs, &objp->active))
+                 return FALSE;
+        return TRUE;
+}
+
+bool_t
+xdr_remote_domain_is_persistent_args (XDR *xdrs, remote_domain_is_persistent_args *objp)
+{
+
+         if (!xdr_remote_nonnull_domain (xdrs, &objp->dom))
+                 return FALSE;
+        return TRUE;
+}
+
+bool_t
+xdr_remote_domain_is_persistent_ret (XDR *xdrs, remote_domain_is_persistent_ret *objp)
+{
+
+         if (!xdr_int (xdrs, &objp->persistent))
+                 return FALSE;
+        return TRUE;
+}
+
+bool_t
+xdr_remote_network_is_active_args (XDR *xdrs, remote_network_is_active_args *objp)
+{
+
+         if (!xdr_remote_nonnull_network (xdrs, &objp->net))
+                 return FALSE;
+        return TRUE;
+}
+
+bool_t
+xdr_remote_network_is_active_ret (XDR *xdrs, remote_network_is_active_ret *objp)
+{
+
+         if (!xdr_int (xdrs, &objp->active))
+                 return FALSE;
+        return TRUE;
+}
+
+bool_t
+xdr_remote_network_is_persistent_args (XDR *xdrs, remote_network_is_persistent_args *objp)
+{
+
+         if (!xdr_remote_nonnull_network (xdrs, &objp->net))
+                 return FALSE;
+        return TRUE;
+}
+
+bool_t
+xdr_remote_network_is_persistent_ret (XDR *xdrs, remote_network_is_persistent_ret *objp)
+{
+
+         if (!xdr_int (xdrs, &objp->persistent))
+                 return FALSE;
+        return TRUE;
+}
+
+bool_t
+xdr_remote_storage_pool_is_active_args (XDR *xdrs, remote_storage_pool_is_active_args *objp)
+{
+
+         if (!xdr_remote_nonnull_storage_pool (xdrs, &objp->pool))
+                 return FALSE;
+        return TRUE;
+}
+
+bool_t
+xdr_remote_storage_pool_is_active_ret (XDR *xdrs, remote_storage_pool_is_active_ret *objp)
+{
+
+         if (!xdr_int (xdrs, &objp->active))
+                 return FALSE;
+        return TRUE;
+}
+
+bool_t
+xdr_remote_storage_pool_is_persistent_args (XDR *xdrs, remote_storage_pool_is_persistent_args *objp)
+{
+
+         if (!xdr_remote_nonnull_storage_pool (xdrs, &objp->pool))
+                 return FALSE;
+        return TRUE;
+}
+
+bool_t
+xdr_remote_storage_pool_is_persistent_ret (XDR *xdrs, remote_storage_pool_is_persistent_ret *objp)
+{
+
+         if (!xdr_int (xdrs, &objp->persistent))
+                 return FALSE;
+        return TRUE;
+}
+
+bool_t
+xdr_remote_interface_is_active_args (XDR *xdrs, remote_interface_is_active_args *objp)
+{
+
+         if (!xdr_remote_nonnull_interface (xdrs, &objp->iface))
+                 return FALSE;
+        return TRUE;
+}
+
+bool_t
+xdr_remote_interface_is_active_ret (XDR *xdrs, remote_interface_is_active_ret *objp)
+{
+
+         if (!xdr_int (xdrs, &objp->active))
+                 return FALSE;
+        return TRUE;
+}
+
+bool_t
 xdr_remote_procedure (XDR *xdrs, remote_procedure *objp)
 {
 
diff --git a/src/remote/remote_protocol.h b/src/remote/remote_protocol.h
index d87e8bc..885695c 100644
--- a/src/remote/remote_protocol.h
+++ b/src/remote/remote_protocol.h
@@ -1537,6 +1537,80 @@ struct remote_domain_migrate_prepare_tunnel_args {
 };
 typedef struct remote_domain_migrate_prepare_tunnel_args remote_domain_migrate_prepare_tunnel_args;
 
+struct remote_is_secure_ret {
+        int secure;
+};
+typedef struct remote_is_secure_ret remote_is_secure_ret;
+
+struct remote_domain_is_active_args {
+        remote_nonnull_domain dom;
+};
+typedef struct remote_domain_is_active_args remote_domain_is_active_args;
+
+struct remote_domain_is_active_ret {
+        int active;
+};
+typedef struct remote_domain_is_active_ret remote_domain_is_active_ret;
+
+struct remote_domain_is_persistent_args {
+        remote_nonnull_domain dom;
+};
+typedef struct remote_domain_is_persistent_args remote_domain_is_persistent_args;
+
+struct remote_domain_is_persistent_ret {
+        int persistent;
+};
+typedef struct remote_domain_is_persistent_ret remote_domain_is_persistent_ret;
+
+struct remote_network_is_active_args {
+        remote_nonnull_network net;
+};
+typedef struct remote_network_is_active_args remote_network_is_active_args;
+
+struct remote_network_is_active_ret {
+        int active;
+};
+typedef struct remote_network_is_active_ret remote_network_is_active_ret;
+
+struct remote_network_is_persistent_args {
+        remote_nonnull_network net;
+};
+typedef struct remote_network_is_persistent_args remote_network_is_persistent_args;
+
+struct remote_network_is_persistent_ret {
+        int persistent;
+};
+typedef struct remote_network_is_persistent_ret remote_network_is_persistent_ret;
+
+struct remote_storage_pool_is_active_args {
+        remote_nonnull_storage_pool pool;
+};
+typedef struct remote_storage_pool_is_active_args remote_storage_pool_is_active_args;
+
+struct remote_storage_pool_is_active_ret {
+        int active;
+};
+typedef struct remote_storage_pool_is_active_ret remote_storage_pool_is_active_ret;
+
+struct remote_storage_pool_is_persistent_args {
+        remote_nonnull_storage_pool pool;
+};
+typedef struct remote_storage_pool_is_persistent_args remote_storage_pool_is_persistent_args;
+
+struct remote_storage_pool_is_persistent_ret {
+        int persistent;
+};
+typedef struct remote_storage_pool_is_persistent_ret remote_storage_pool_is_persistent_ret;
+
+struct remote_interface_is_active_args {
+        remote_nonnull_interface iface;
+};
+typedef struct remote_interface_is_active_args remote_interface_is_active_args;
+
+struct remote_interface_is_active_ret {
+        int active;
+};
+typedef struct remote_interface_is_active_ret remote_interface_is_active_ret;
 #define REMOTE_PROGRAM 0x20008086
 #define REMOTE_PROTOCOL_VERSION 1
 
@@ -1689,6 +1763,14 @@ enum remote_procedure {
         REMOTE_PROC_SECRET_UNDEFINE = 146,
         REMOTE_PROC_SECRET_LOOKUP_BY_USAGE = 147,
         REMOTE_PROC_DOMAIN_MIGRATE_PREPARE_TUNNEL = 148,
+        REMOTE_PROC_IS_SECURE = 149,
+        REMOTE_PROC_DOMAIN_IS_ACTIVE = 150,
+        REMOTE_PROC_DOMAIN_IS_PERSISTENT = 151,
+        REMOTE_PROC_NETWORK_IS_ACTIVE = 152,
+        REMOTE_PROC_NETWORK_IS_PERSISTENT = 153,
+        REMOTE_PROC_STORAGE_POOL_IS_ACTIVE = 154,
+        REMOTE_PROC_STORAGE_POOL_IS_PERSISTENT = 155,
+        REMOTE_PROC_INTERFACE_IS_ACTIVE = 156,
 };
 typedef enum remote_procedure remote_procedure;
 
@@ -1970,6 +2052,21 @@ extern  bool_t xdr_remote_secret_undefine_args (XDR *, remote_secret_undefine_ar
 extern  bool_t xdr_remote_secret_lookup_by_usage_args (XDR *, remote_secret_lookup_by_usage_args*);
 extern  bool_t xdr_remote_secret_lookup_by_usage_ret (XDR *, remote_secret_lookup_by_usage_ret*);
 extern  bool_t xdr_remote_domain_migrate_prepare_tunnel_args (XDR *, remote_domain_migrate_prepare_tunnel_args*);
+extern  bool_t xdr_remote_is_secure_ret (XDR *, remote_is_secure_ret*);
+extern  bool_t xdr_remote_domain_is_active_args (XDR *, remote_domain_is_active_args*);
+extern  bool_t xdr_remote_domain_is_active_ret (XDR *, remote_domain_is_active_ret*);
+extern  bool_t xdr_remote_domain_is_persistent_args (XDR *, remote_domain_is_persistent_args*);
+extern  bool_t xdr_remote_domain_is_persistent_ret (XDR *, remote_domain_is_persistent_ret*);
+extern  bool_t xdr_remote_network_is_active_args (XDR *, remote_network_is_active_args*);
+extern  bool_t xdr_remote_network_is_active_ret (XDR *, remote_network_is_active_ret*);
+extern  bool_t xdr_remote_network_is_persistent_args (XDR *, remote_network_is_persistent_args*);
+extern  bool_t xdr_remote_network_is_persistent_ret (XDR *, remote_network_is_persistent_ret*);
+extern  bool_t xdr_remote_storage_pool_is_active_args (XDR *, remote_storage_pool_is_active_args*);
+extern  bool_t xdr_remote_storage_pool_is_active_ret (XDR *, remote_storage_pool_is_active_ret*);
+extern  bool_t xdr_remote_storage_pool_is_persistent_args (XDR *, remote_storage_pool_is_persistent_args*);
+extern  bool_t xdr_remote_storage_pool_is_persistent_ret (XDR *, remote_storage_pool_is_persistent_ret*);
+extern  bool_t xdr_remote_interface_is_active_args (XDR *, remote_interface_is_active_args*);
+extern  bool_t xdr_remote_interface_is_active_ret (XDR *, remote_interface_is_active_ret*);
 extern  bool_t xdr_remote_procedure (XDR *, remote_procedure*);
 extern  bool_t xdr_remote_message_type (XDR *, remote_message_type*);
 extern  bool_t xdr_remote_message_status (XDR *, remote_message_status*);
@@ -2225,6 +2322,21 @@ extern bool_t xdr_remote_secret_undefine_args ();
 extern bool_t xdr_remote_secret_lookup_by_usage_args ();
 extern bool_t xdr_remote_secret_lookup_by_usage_ret ();
 extern bool_t xdr_remote_domain_migrate_prepare_tunnel_args ();
+extern bool_t xdr_remote_is_secure_ret ();
+extern bool_t xdr_remote_domain_is_active_args ();
+extern bool_t xdr_remote_domain_is_active_ret ();
+extern bool_t xdr_remote_domain_is_persistent_args ();
+extern bool_t xdr_remote_domain_is_persistent_ret ();
+extern bool_t xdr_remote_network_is_active_args ();
+extern bool_t xdr_remote_network_is_active_ret ();
+extern bool_t xdr_remote_network_is_persistent_args ();
+extern bool_t xdr_remote_network_is_persistent_ret ();
+extern bool_t xdr_remote_storage_pool_is_active_args ();
+extern bool_t xdr_remote_storage_pool_is_active_ret ();
+extern bool_t xdr_remote_storage_pool_is_persistent_args ();
+extern bool_t xdr_remote_storage_pool_is_persistent_ret ();
+extern bool_t xdr_remote_interface_is_active_args ();
+extern bool_t xdr_remote_interface_is_active_ret ();
 extern bool_t xdr_remote_procedure ();
 extern bool_t xdr_remote_message_type ();
 extern bool_t xdr_remote_message_status ();
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index 2b3c03b..1886282 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -1362,6 +1362,73 @@ struct remote_domain_migrate_prepare_tunnel_args {
     remote_nonnull_string dom_xml;
 };
 
+
+struct remote_is_secure_ret {
+    int secure;
+};
+
+
+struct remote_domain_is_active_args {
+    remote_nonnull_domain dom;
+};
+
+struct remote_domain_is_active_ret {
+    int active;
+};
+
+
+struct remote_domain_is_persistent_args {
+    remote_nonnull_domain dom;
+};
+
+struct remote_domain_is_persistent_ret {
+    int persistent;
+};
+
+
+struct remote_network_is_active_args {
+    remote_nonnull_network net;
+};
+
+struct remote_network_is_active_ret {
+    int active;
+};
+
+struct remote_network_is_persistent_args {
+    remote_nonnull_network net;
+};
+
+struct remote_network_is_persistent_ret {
+    int persistent;
+};
+
+
+struct remote_storage_pool_is_active_args {
+    remote_nonnull_storage_pool pool;
+};
+
+struct remote_storage_pool_is_active_ret {
+    int active;
+};
+
+struct remote_storage_pool_is_persistent_args {
+    remote_nonnull_storage_pool pool;
+};
+
+struct remote_storage_pool_is_persistent_ret {
+    int persistent;
+};
+
+
+struct remote_interface_is_active_args {
+    remote_nonnull_interface iface;
+};
+
+struct remote_interface_is_active_ret {
+    int active;
+};
+
+
 /*----- Protocol. -----*/
 
 /* Define the program number, protocol version and procedure numbers here. */
@@ -1518,12 +1585,11 @@ enum remote_procedure {
     REMOTE_PROC_INTERFACE_DESTROY = 134,
     REMOTE_PROC_DOMAIN_XML_FROM_NATIVE = 135,
     REMOTE_PROC_DOMAIN_XML_TO_NATIVE = 136,
-
     REMOTE_PROC_NUM_OF_DEFINED_INTERFACES = 137,
     REMOTE_PROC_LIST_DEFINED_INTERFACES = 138,
-
     REMOTE_PROC_NUM_OF_SECRETS = 139,
     REMOTE_PROC_LIST_SECRETS = 140,
+
     REMOTE_PROC_SECRET_LOOKUP_BY_UUID = 141,
     REMOTE_PROC_SECRET_DEFINE_XML = 142,
     REMOTE_PROC_SECRET_GET_XML_DESC = 143,
@@ -1531,11 +1597,24 @@ enum remote_procedure {
     REMOTE_PROC_SECRET_GET_VALUE = 145,
     REMOTE_PROC_SECRET_UNDEFINE = 146,
     REMOTE_PROC_SECRET_LOOKUP_BY_USAGE = 147,
+    REMOTE_PROC_DOMAIN_MIGRATE_PREPARE_TUNNEL = 148,
+    REMOTE_PROC_IS_SECURE = 149,
+    REMOTE_PROC_DOMAIN_IS_ACTIVE = 150,
 
-    REMOTE_PROC_DOMAIN_MIGRATE_PREPARE_TUNNEL = 148
-};
+    REMOTE_PROC_DOMAIN_IS_PERSISTENT = 151,
+    REMOTE_PROC_NETWORK_IS_ACTIVE = 152,
+    REMOTE_PROC_NETWORK_IS_PERSISTENT = 153,
+    REMOTE_PROC_STORAGE_POOL_IS_ACTIVE = 154,
+    REMOTE_PROC_STORAGE_POOL_IS_PERSISTENT = 155,
+    REMOTE_PROC_INTERFACE_IS_ACTIVE = 156
 
 
+    /*
+     * Notice how the entries are grouped in sets of 10 ?
+     * Nice isn't it. Please keep it this way when adding more.
+     */
+};
+
 /*
  * RPC wire format
  *
diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c
index 4f8949b..00ee472 100644
--- a/src/storage/storage_driver.c
+++ b/src/storage/storage_driver.c
@@ -464,6 +464,49 @@ cleanup:
 }
 
 
+static int storagePoolIsActive(virStoragePoolPtr net)
+{
+    virStorageDriverStatePtr driver = net->conn->privateData;
+    virStoragePoolObjPtr obj;
+    int ret = -1;
+
+    storageDriverLock(driver);
+    obj = virStoragePoolObjFindByUUID(&driver->pools, net->uuid);
+    storageDriverUnlock(driver);
+    if (!obj) {
+        virStorageReportError(net->conn, VIR_ERR_NO_STORAGE_POOL, NULL);
+        goto cleanup;
+    }
+    ret = virStoragePoolObjIsActive(obj);
+
+cleanup:
+    if (obj)
+        virStoragePoolObjUnlock(obj);
+    return ret;
+}
+
+static int storagePoolIsPersistent(virStoragePoolPtr net)
+{
+    virStorageDriverStatePtr driver = net->conn->privateData;
+    virStoragePoolObjPtr obj;
+    int ret = -1;
+
+    storageDriverLock(driver);
+    obj = virStoragePoolObjFindByUUID(&driver->pools, net->uuid);
+    storageDriverUnlock(driver);
+    if (!obj) {
+        virStorageReportError(net->conn, VIR_ERR_NO_STORAGE_POOL, NULL);
+        goto cleanup;
+    }
+    ret = obj->configFile ? 1 : 0;
+
+cleanup:
+    if (obj)
+        virStoragePoolObjUnlock(obj);
+    return ret;
+}
+
+
 static virStoragePoolPtr
 storagePoolCreate(virConnectPtr conn,
                   const char *xml,
@@ -1740,6 +1783,9 @@ static virStorageDriver storageDriver = {
     .volGetInfo = storageVolumeGetInfo,
     .volGetXMLDesc = storageVolumeGetXMLDesc,
     .volGetPath = storageVolumeGetPath,
+
+    .poolIsActive = storagePoolIsActive,
+    .poolIsPersistent = storagePoolIsPersistent,
 };
 
 
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index 88dc6a5..afa9b02 100644
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -1006,6 +1006,17 @@ static char *testGetHostname (virConnectPtr conn)
     return result;
 }
 
+
+static int testIsSecure(virConnectPtr conn ATTRIBUTE_UNUSED)
+{
+    return 1;
+}
+
+static int testIsEncrypted(virConnectPtr conn ATTRIBUTE_UNUSED)
+{
+    return 0;
+}
+
 static int testGetMaxVCPUs(virConnectPtr conn ATTRIBUTE_UNUSED,
                            const char *type ATTRIBUTE_UNUSED)
 {
@@ -1047,6 +1058,48 @@ static int testNumOfDomains(virConnectPtr conn)
     return numActive;
 }
 
+static int testDomainIsActive(virDomainPtr dom)
+{
+    testConnPtr privconn = dom->conn->privateData;
+    virDomainObjPtr obj;
+    int ret = -1;
+
+    testDriverLock(privconn);
+    obj = virDomainFindByUUID(&privconn->domains, dom->uuid);
+    testDriverUnlock(privconn);
+    if (!obj) {
+        testError(dom->conn, VIR_ERR_NO_DOMAIN, NULL);
+        goto cleanup;
+    }
+    ret = virDomainObjIsActive(obj);
+
+cleanup:
+    if (obj)
+        virDomainObjUnlock(obj);
+    return ret;
+}
+
+static int testDomainIsPersistent(virDomainPtr dom)
+{
+    testConnPtr privconn = dom->conn->privateData;
+    virDomainObjPtr obj;
+    int ret = -1;
+
+    testDriverLock(privconn);
+    obj = virDomainFindByUUID(&privconn->domains, dom->uuid);
+    testDriverUnlock(privconn);
+    if (!obj) {
+        testError(dom->conn, VIR_ERR_NO_DOMAIN, NULL);
+        goto cleanup;
+    }
+    ret = obj->persistent;
+
+cleanup:
+    if (obj)
+        virDomainObjUnlock(obj);
+    return ret;
+}
+
 static virDomainPtr
 testDomainCreateXML(virConnectPtr conn, const char *xml,
                       unsigned int flags ATTRIBUTE_UNUSED)
@@ -2441,6 +2494,50 @@ no_memory:
     return -1;
 }
 
+
+static int testNetworkIsActive(virNetworkPtr net)
+{
+    testConnPtr privconn = net->conn->privateData;
+    virNetworkObjPtr obj;
+    int ret = -1;
+
+    testDriverLock(privconn);
+    obj = virNetworkFindByUUID(&privconn->networks, net->uuid);
+    testDriverUnlock(privconn);
+    if (!obj) {
+        testError(net->conn, VIR_ERR_NO_NETWORK, NULL);
+        goto cleanup;
+    }
+    ret = virNetworkObjIsActive(obj);
+
+cleanup:
+    if (obj)
+        virNetworkObjUnlock(obj);
+    return ret;
+}
+
+static int testNetworkIsPersistent(virNetworkPtr net)
+{
+    testConnPtr privconn = net->conn->privateData;
+    virNetworkObjPtr obj;
+    int ret = -1;
+
+    testDriverLock(privconn);
+    obj = virNetworkFindByUUID(&privconn->networks, net->uuid);
+    testDriverUnlock(privconn);
+    if (!obj) {
+        testError(net->conn, VIR_ERR_NO_NETWORK, NULL);
+        goto cleanup;
+    }
+    ret = obj->persistent;
+
+cleanup:
+    if (obj)
+        virNetworkObjUnlock(obj);
+    return ret;
+}
+
+
 static virNetworkPtr testNetworkCreate(virConnectPtr conn, const char *xml) {
     testConnPtr privconn = conn->privateData;
     virNetworkDefPtr def;
@@ -2857,6 +2954,28 @@ cleanup:
     return ret;
 }
 
+static int testInterfaceIsActive(virInterfacePtr iface)
+{
+    testConnPtr privconn = iface->conn->privateData;
+    virInterfaceObjPtr obj;
+    int ret = -1;
+
+    testDriverLock(privconn);
+    obj = virInterfaceFindByName(&privconn->ifaces, iface->name);
+    testDriverUnlock(privconn);
+    if (!obj) {
+        testError(iface->conn, VIR_ERR_NO_INTERFACE, NULL);
+        goto cleanup;
+    }
+    ret = virInterfaceObjIsActive(obj);
+
+cleanup:
+    if (obj)
+        virInterfaceObjUnlock(obj);
+    return ret;
+}
+
+
 static char *testInterfaceGetXMLDesc(virInterfacePtr iface,
                                      unsigned int flags ATTRIBUTE_UNUSED)
 {
@@ -3001,6 +3120,7 @@ cleanup:
  * Storage Driver routines
  */
 
+
 static int testStoragePoolObjSetDefaults(virConnectPtr conn,
                                          virStoragePoolObjPtr pool) {
 
@@ -3032,6 +3152,7 @@ static int testStorageClose(virConnectPtr conn) {
     return 0;
 }
 
+
 static virStoragePoolPtr
 testStoragePoolLookupByUUID(virConnectPtr conn,
                             const unsigned char *uuid) {
@@ -3177,6 +3298,50 @@ no_memory:
 }
 
 
+static int testStoragePoolIsActive(virStoragePoolPtr pool)
+{
+    testConnPtr privconn = pool->conn->privateData;
+    virStoragePoolObjPtr obj;
+    int ret = -1;
+
+    testDriverLock(privconn);
+    obj = virStoragePoolObjFindByUUID(&privconn->pools, pool->uuid);
+    testDriverUnlock(privconn);
+    if (!obj) {
+        testError(pool->conn, VIR_ERR_NO_STORAGE_POOL, NULL);
+        goto cleanup;
+    }
+    ret = virStoragePoolObjIsActive(obj);
+
+cleanup:
+    if (obj)
+        virStoragePoolObjUnlock(obj);
+    return ret;
+}
+
+static int testStoragePoolIsPersistent(virStoragePoolPtr pool)
+{
+    testConnPtr privconn = pool->conn->privateData;
+    virStoragePoolObjPtr obj;
+    int ret = -1;
+
+    testDriverLock(privconn);
+    obj = virStoragePoolObjFindByUUID(&privconn->pools, pool->uuid);
+    testDriverUnlock(privconn);
+    if (!obj) {
+        testError(pool->conn, VIR_ERR_NO_STORAGE_POOL, NULL);
+        goto cleanup;
+    }
+    ret = obj->configFile ? 1 : 0;
+
+cleanup:
+    if (obj)
+        virStoragePoolObjUnlock(obj);
+    return ret;
+}
+
+
+
 static int
 testStoragePoolStart(virStoragePoolPtr pool,
                      unsigned int flags ATTRIBUTE_UNUSED) {
@@ -4558,10 +4723,10 @@ static virDriver testDriver = {
     NULL, /* nodeDeviceReAttach */
     NULL, /* nodeDeviceReset */
     NULL, /* domainMigratePrepareTunnel */
-    NULL, /* isEncrypted */
-    NULL, /* isSecure */
-    NULL, /* domainIsActive */
-    NULL, /* domainIsEncrypted */
+    testIsEncrypted, /* isEncrypted */
+    testIsSecure, /* isEncrypted */
+    testDomainIsActive, /* domainIsActive */
+    testDomainIsPersistent, /* domainIsPersistent */
 };
 
 static virNetworkDriver testNetworkDriver = {
@@ -4583,8 +4748,8 @@ static virNetworkDriver testNetworkDriver = {
     testNetworkGetBridgeName, /* networkGetBridgeName */
     testNetworkGetAutostart, /* networkGetAutostart */
     testNetworkSetAutostart, /* networkSetAutostart */
-    NULL, /* networkIsActive */
-    NULL, /* networkIsEncrypted */
+    testNetworkIsActive, /* domainIsActive */
+    testNetworkIsPersistent, /* domainIsPersistent */
 };
 
 static virInterfaceDriver testInterfaceDriver = {
@@ -4602,7 +4767,7 @@ static virInterfaceDriver testInterfaceDriver = {
     testInterfaceUndefine,      /* interfaceUndefine */
     testInterfaceCreate,        /* interfaceCreate */
     testInterfaceDestroy,       /* interfaceDestroy */
-    NULL, /* interfaceIsActive */
+    testInterfaceIsActive, /* domainIsActive */
 };
 
 
@@ -4643,9 +4808,8 @@ static virStorageDriver testStorageDriver = {
     .volGetInfo = testStorageVolumeGetInfo,
     .volGetXMLDesc = testStorageVolumeGetXMLDesc,
     .volGetPath = testStorageVolumeGetPath,
-
-    .poolIsActive = NULL, /* poolIsActive */
-    .poolIsPersistent = NULL, /* poolIsEncrypted */
+    .poolIsActive = testStoragePoolIsActive,
+    .poolIsPersistent = testStoragePoolIsPersistent,
 };
 
 static virDeviceMonitor testDevMonitor = {
diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c
index 9b450d9..0a87341 100644
--- a/src/uml/uml_driver.c
+++ b/src/uml/uml_driver.c
@@ -981,6 +981,20 @@ static const char *umlGetType(virConnectPtr conn ATTRIBUTE_UNUSED) {
 }
 
 
+static int umlIsSecure(virConnectPtr conn ATTRIBUTE_UNUSED)
+{
+    /* Trivially secure, since always inside the daemon */
+    return 1;
+}
+
+
+static int umlIsEncrypted(virConnectPtr conn ATTRIBUTE_UNUSED)
+{
+    /* Not encrypted, but remote driver takes care of that */
+    return 0;
+}
+
+
 static char *umlGetCapabilities(virConnectPtr conn) {
     struct uml_driver *driver = (struct uml_driver *)conn->privateData;
     char *xml;
@@ -1104,6 +1118,51 @@ cleanup:
     return dom;
 }
 
+
+static int umlDomainIsActive(virDomainPtr dom)
+{
+    struct uml_driver *driver = dom->conn->privateData;
+    virDomainObjPtr obj;
+    int ret = -1;
+
+    umlDriverLock(driver);
+    obj = virDomainFindByUUID(&driver->domains, dom->uuid);
+    umlDriverUnlock(driver);
+    if (!obj) {
+        umlReportError(dom->conn, NULL, NULL, VIR_ERR_NO_DOMAIN, NULL);
+        goto cleanup;
+    }
+    ret = virDomainObjIsActive(obj);
+
+cleanup:
+    if (obj)
+        virDomainObjUnlock(obj);
+    return ret;
+}
+
+
+static int umlDomainIsPersistent(virDomainPtr dom)
+{
+    struct uml_driver *driver = dom->conn->privateData;
+    virDomainObjPtr obj;
+    int ret = -1;
+
+    umlDriverLock(driver);
+    obj = virDomainFindByUUID(&driver->domains, dom->uuid);
+    umlDriverUnlock(driver);
+    if (!obj) {
+        umlReportError(dom->conn, NULL, NULL, VIR_ERR_NO_DOMAIN, NULL);
+        goto cleanup;
+    }
+    ret = obj->persistent;
+
+cleanup:
+    if (obj)
+        virDomainObjUnlock(obj);
+    return ret;
+}
+
+
 static int umlGetVersion(virConnectPtr conn, unsigned long *version) {
     struct uml_driver *driver = conn->privateData;
     struct utsname ut;
@@ -1862,10 +1921,10 @@ static virDriver umlDriver = {
     NULL, /* nodeDeviceReAttach */
     NULL, /* nodeDeviceReset */
     NULL, /* domainMigratePrepareTunnel */
-    NULL, /* isEncrypted */
-    NULL, /* isSecure */
-    NULL, /* domainIsActive */
-    NULL, /* domainIsEncrypted */
+    umlIsEncrypted,
+    umlIsSecure,
+    umlDomainIsActive,
+    umlDomainIsPersistent,
 };
 
 
diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
index 5878154..28651a4 100644
--- a/src/vbox/vbox_tmpl.c
+++ b/src/vbox/vbox_tmpl.c
@@ -607,6 +607,19 @@ static char *vboxGetHostname(virConnectPtr conn) {
     return hostname;
 }
 
+
+static int vboxIsSecure(virConnectPtr conn ATTRIBUTE_UNUSED) {
+    /* Driver is using local, non-network based transport */
+    return 1;
+}
+
+
+static int vboxIsEncrypted(virConnectPtr conn ATTRIBUTE_UNUSED) {
+    /* No encryption is needed, or used on the local transport*/
+    return 0;
+}
+
+
 static int vboxGetMaxVcpus(virConnectPtr conn, const char *type ATTRIBUTE_UNUSED) {
     vboxGlobalData *data = conn->privateData;
     PRUint32 maxCPUCount = 0;
@@ -1030,6 +1043,93 @@ static virDomainPtr vboxDomainLookupByName(virConnectPtr conn, const char *name)
     return dom;
 }
 
+
+static int vboxDomainIsActive(virDomainPtr dom) {
+    nsresult rc;
+    vboxGlobalData *data = dom->conn->privateData;
+    IMachine **machines  = NULL;
+    PRUint32 machineCnt  = 0;
+    vboxIID *iid         = NULL;
+    char      *machineNameUtf8  = NULL;
+    PRUnichar *machineNameUtf16 = NULL;
+    unsigned char iidl[VIR_UUID_BUFLEN];
+    int i, matched = 0;
+    int ret = -1;
+
+    if(data->vboxObj) {
+        rc = data->vboxObj->vtbl->GetMachines(data->vboxObj, &machineCnt, &machines);
+        if (NS_FAILED(rc)) {
+            vboxError(dom->conn, VIR_ERR_INTERNAL_ERROR,"%s, rc=%08x",
+                      "Could not get list of machines",(unsigned)rc);
+            return -1;
+        }
+
+        for (i = 0; i < machineCnt; ++i) {
+            IMachine *machine = machines[i];
+            PRBool isAccessible = PR_FALSE;
+
+            if (!machine)
+                continue;
+
+            machine->vtbl->GetAccessible(machine, &isAccessible);
+            if (isAccessible) {
+
+                machine->vtbl->GetId(machine, &iid);
+                if (!iid)
+                    continue;
+                vboxIIDToUUID(iidl, iid);
+                vboxIIDUnalloc(iid);
+
+                if (memcmp(dom->uuid, iidl, VIR_UUID_BUFLEN) == 0) {
+
+                    PRUint32 state;
+
+                    matched = 1;
+
+                    machine->vtbl->GetName(machine, &machineNameUtf16);
+                    data->pFuncs->pfnUtf16ToUtf8(machineNameUtf16, &machineNameUtf8);
+
+                    machine->vtbl->GetState(machine, &state);
+
+                    if ((state == MachineState_Starting)   ||
+                        (state == MachineState_Running)    ||
+                        (state == MachineState_Stuck)      ||
+                        (state == MachineState_Stopping)   ||
+                        (state == MachineState_Saving)     ||
+                        (state == MachineState_Restoring)  ||
+                        (state == MachineState_Discarding) ||
+                        (state == MachineState_Paused) )
+                        ret = 1;
+                    else
+                        ret = 0;
+                }
+
+                if (matched == 1)
+                    break;
+            }
+        }
+
+        /* Do the cleanup and take care you dont leak any memory */
+        if (machineNameUtf8)
+            data->pFuncs->pfnUtf8Free(machineNameUtf8);
+        if (machineNameUtf16)
+            data->pFuncs->pfnComUnallocMem(machineNameUtf16);
+        for (i = 0; i < machineCnt; ++i) {
+            if (machines[i])
+                machines[i]->vtbl->nsisupports.Release((nsISupports *)machines[i]);
+        }
+    }
+
+    return ret;
+}
+
+
+static int vboxDomainIsPersistent(virDomainPtr dom ATTRIBUTE_UNUSED) {
+    /* XXX All domains appear to be persistent. Is this true ? */
+    return 1;
+}
+
+
 static int vboxDomainSuspend(virDomainPtr dom) {
     nsresult rc;
     vboxGlobalData *data = dom->conn->privateData;
@@ -6468,10 +6568,10 @@ virDriver NAME(Driver) = {
     NULL, /* nodeDeviceReAttach */
     NULL, /* nodeDeviceReset */
     NULL, /* domainMigratePrepareTunnel */
-    NULL, /* isEncrypted */
-    NULL, /* isSecure */
-    NULL, /* domainIsActive */
-    NULL, /* domainIsEncrypted */
+    vboxIsEncrypted,
+    vboxIsSecure,
+    vboxDomainIsActive,
+    vboxDomainIsPersistent,
 };
 
 virNetworkDriver NAME(NetworkDriver) = {
diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c
index da05253..fcf0506 100644
--- a/src/xen/xen_driver.c
+++ b/src/xen/xen_driver.c
@@ -45,6 +45,7 @@
 #include "memory.h"
 #include "node_device_conf.h"
 #include "pci.h"
+#include "uuid.h"
 
 #define VIR_FROM_THIS VIR_FROM_XEN
 
@@ -497,6 +498,26 @@ xenUnifiedGetHostname (virConnectPtr conn)
 }
 
 static int
+xenUnifiedIsEncrypted(virConnectPtr conn ATTRIBUTE_UNUSED)
+{
+    return 0;
+}
+
+static int
+xenUnifiedIsSecure(virConnectPtr conn)
+{
+    GET_PRIVATE(conn);
+    int ret = 1;
+
+    /* All drivers are secure, except for XenD over TCP */
+    if (priv->opened[XEN_UNIFIED_XEND_OFFSET] &&
+        priv->addrfamily != AF_UNIX)
+        ret = 0;
+
+    return ret;
+}
+
+static int
 xenUnifiedGetMaxVcpus (virConnectPtr conn, const char *type)
 {
     GET_PRIVATE(conn);
@@ -738,6 +759,75 @@ xenUnifiedDomainLookupByName (virConnectPtr conn,
     return NULL;
 }
 
+
+static int
+xenUnifiedDomainIsActive(virDomainPtr dom)
+{
+    virDomainPtr currdom;
+    int ret = -1;
+
+    /* ID field in dom may be outdated, so re-lookup */
+    currdom = xenUnifiedDomainLookupByUUID(dom->conn, dom->uuid);
+
+    if (currdom) {
+        ret = currdom->id == -1 ? 0 : 1;
+        virDomainFree(currdom);
+    }
+
+    return ret;
+}
+
+static int
+xenUnifiedDomainisPersistent(virDomainPtr dom)
+{
+    GET_PRIVATE(dom->conn);
+    virDomainPtr currdom = NULL;
+    int ret = -1;
+
+    if (priv->opened[XEN_UNIFIED_XM_OFFSET]) {
+        /* Old Xen, pre-inactive domain management.
+         * If the XM driver can see the guest, it is definitely persistent */
+        currdom = xenXMDomainLookupByUUID(dom->conn, dom->uuid);
+        if (currdom)
+            ret = 1;
+        else
+            ret = 0;
+    } else {
+        /* New Xen with inactive domain management */
+        if (priv->opened[XEN_UNIFIED_XEND_OFFSET]) {
+            currdom = xenDaemonLookupByUUID(dom->conn, dom->uuid);
+            if (currdom) {
+                if (currdom->id == -1) {
+                    /* If its inactive, then trivially, it must be persistent */
+                    ret = 1;
+                } else {
+                    char *path;
+                    char uuidstr[VIR_UUID_STRING_BUFLEN];
+
+                    /* If its running there's no official way to tell, so we
+                     * go behind xend's back & look at the config dir */
+
+                    virUUIDFormat(dom->uuid, uuidstr);
+                    if (virAsprintf(&path, "%s/%s", XEND_DOMAINS_DIR, uuidstr) < 0) {
+                        virReportOOMError(NULL);
+                        goto done;
+                    }
+                    if (access(path, R_OK) == 0)
+                        ret = 1;
+                    else if (errno == ENOENT)
+                        ret = 0;
+                }
+            }
+        }
+    }
+
+done:
+    if (currdom)
+        virDomainFree(currdom);
+
+    return ret;
+}
+
 static int
 xenUnifiedDomainSuspend (virDomainPtr dom)
 {
@@ -1726,10 +1816,10 @@ static virDriver xenUnifiedDriver = {
     xenUnifiedNodeDeviceReAttach, /* nodeDeviceReAttach */
     xenUnifiedNodeDeviceReset, /* nodeDeviceReset */
     NULL, /* domainMigratePrepareTunnel */
-    NULL, /* isEncrypted */
-    NULL, /* isSecure */
-    NULL, /* domainIsActive */
-    NULL, /* domainIsEncrypted */
+    xenUnifiedIsEncrypted,
+    xenUnifiedIsSecure,
+    xenUnifiedDomainIsActive,
+    xenUnifiedDomainisPersistent,
 };
 
 /**
diff --git a/src/xen/xen_driver.h b/src/xen/xen_driver.h
index 9cc877b..185eb2b 100644
--- a/src/xen/xen_driver.h
+++ b/src/xen/xen_driver.h
@@ -49,6 +49,8 @@ extern int xenRegister (void);
 #define XEN_CONFIG_FORMAT_XM    "xen-xm"
 #define XEN_CONFIG_FORMAT_SEXPR "xen-sxpr"
 
+#define XEND_DOMAINS_DIR "/var/lib/xend/domains"
+
 /* _xenUnifiedDriver:
  *
  * Entry points into the underlying Xen drivers.  This structure
diff --git a/src/xen/xen_inotify.c b/src/xen/xen_inotify.c
index 9e0407f..d47565d 100644
--- a/src/xen/xen_inotify.c
+++ b/src/xen/xen_inotify.c
@@ -47,8 +47,6 @@
         virReportErrorHelper(NULL, VIR_FROM_XEN_INOTIFY, code, __FILE__,      \
                                __FUNCTION__, __LINE__, fmt)
 
-#define LIBVIRTD_DOMAINS_DIR "/var/lib/xend/domains"
-
 struct xenUnifiedDriver xenInotifyDriver = {
     xenInotifyOpen, /* open */
     xenInotifyClose, /* close */
@@ -125,7 +123,7 @@ xenInotifyXendDomainsDirLookup(virConnectPtr conn, const char *filename,
     * a filename in the manner:
     * /var/lib/xend/domains/<uuid>/
     */
-    uuid_str = filename + strlen(LIBVIRTD_DOMAINS_DIR) + 1;
+    uuid_str = filename + strlen(XEND_DOMAINS_DIR) + 1;
 
     if (virUUIDParse(uuid_str, rawuuid) < 0) {
         virXenInotifyError(NULL, VIR_ERR_INTERNAL_ERROR,
@@ -198,7 +196,7 @@ static int
 xenInotifyXendDomainsDirRemoveEntry(virConnectPtr conn,
                                     const char *fname) {
     xenUnifiedPrivatePtr priv = conn->privateData;
-    const char *uuidstr = fname + strlen(LIBVIRTD_DOMAINS_DIR) + 1;
+    const char *uuidstr = fname + strlen(XEND_DOMAINS_DIR) + 1;
     unsigned char uuid[VIR_UUID_BUFLEN];
     int i;
 
@@ -393,7 +391,7 @@ xenInotifyOpen(virConnectPtr conn ATTRIBUTE_UNUSED,
         priv->useXenConfigCache = 1;
     } else {
         /* /var/lib/xend/domains/<uuid>/config.sxp */
-        priv->configDir = LIBVIRTD_DOMAINS_DIR;
+        priv->configDir = XEND_DOMAINS_DIR;
         priv->useXenConfigCache = 0;
 
         if (VIR_ALLOC(priv->configInfoList) < 0) {
diff --git a/src/xen/xen_inotify.h b/src/xen/xen_inotify.h
index 70bc63c..48490e7 100644
--- a/src/xen/xen_inotify.h
+++ b/src/xen/xen_inotify.h
@@ -31,4 +31,5 @@ virDrvOpenStatus	xenInotifyOpen	(virConnectPtr conn,
                                          virConnectAuthPtr auth,
                                          int flags);
 int		xenInotifyClose		(virConnectPtr conn);
+
 #endif
-- 
1.6.2.5




More information about the libvir-list mailing list