+Tue Aug 21 09:56:00 BST 2007 Richard W.M. Jones <rjones@redhat.com>
+
+ * qemud/remote.c, qemud/remote_protocol.x, src/driver.h,
+ src/internal.h, src/libvirt.c, src/libvirt_sym.version,
+ src/qemu_driver.c, src/remote_internal.c, src/test.c:
+ Add a private interface so that libvirt.c coordination
+ functions can detect the availability of features in
+ underlying drivers, using the VIR_DRV_SUPPORTS_FEATURE
+ macro.
+
Tue Aug 21 09:45:00 BST 2007 Richard W.M. Jones <rjones@redhat.com>
* src/xend_internal.c: Return the interface device name as
which hypervisors.
</p><p>
This information changes frequently. This page was last checked or
-updated on <i>2007-06-29</i>.
+updated on <i>2007-08-20</i>.
</p><h3>Domain functions</h3><p> x = not supported; empty cell means no information </p><table class="top_table"><tr><th> Function </th>
<th> Since </th>
<th> Xen </th>
<td> All </td>
<td> All </td>
<td> x </td>
- <td> x </td>
+ <td> ≥ 0.3.2 </td>
<td> ≥ 0.3.0 </td>
</tr><tr><td> virDomainResume </td>
<td> All </td>
<td> All </td>
<td> All </td>
<td> x </td>
- <td> x </td>
+ <td> ≥ 0.3.2 </td>
<td> ≥ 0.3.0 </td>
</tr><tr><td> virDomainSetAutostart </td>
<td> 0.2.1 </td>
return rv;
}
+static int
+remoteDispatchSupportsFeature (struct qemud_client *client, remote_message_header *req,
+ remote_supports_feature_args *args, remote_supports_feature_ret *ret)
+{
+ CHECK_CONN(client);
+
+ ret->supported = __virDrvSupportsFeature (client->conn, args->feature);
+ if (ret->supported == -1) return -1;
+
+ return 0;
+}
+
static int
remoteDispatchGetType (struct qemud_client *client, remote_message_header *req,
void *args ATTRIBUTE_UNUSED, remote_get_type_ret *ret)
remote_domain_get_autostart_args lv_remote_domain_get_autostart_args;
remote_domain_get_autostart_ret lv_remote_domain_get_autostart_ret;
remote_domain_set_vcpus_args lv_remote_domain_set_vcpus_args;
-remote_get_hostname_ret lv_remote_get_hostname_ret;
remote_domain_get_scheduler_type_args lv_remote_domain_get_scheduler_type_args;
remote_domain_get_scheduler_type_ret lv_remote_domain_get_scheduler_type_ret;
+remote_get_hostname_ret lv_remote_get_hostname_ret;
remote_network_undefine_args lv_remote_network_undefine_args;
remote_domain_create_args lv_remote_domain_create_args;
remote_domain_suspend_args lv_remote_domain_suspend_args;
remote_domain_get_info_ret lv_remote_domain_get_info_ret;
remote_network_create_args lv_remote_network_create_args;
remote_num_of_defined_networks_ret lv_remote_num_of_defined_networks_ret;
+remote_supports_feature_args lv_remote_supports_feature_args;
+remote_supports_feature_ret lv_remote_supports_feature_ret;
remote_domain_lookup_by_name_args lv_remote_domain_lookup_by_name_args;
remote_domain_lookup_by_name_ret lv_remote_domain_lookup_by_name_ret;
remote_network_lookup_by_uuid_args lv_remote_network_lookup_by_uuid_args;
args = (char *) &lv_remote_open_args;
memset (&lv_remote_open_args, 0, sizeof lv_remote_open_args);
break;
+case REMOTE_PROC_SUPPORTS_FEATURE:
+ fn = (dispatch_fn) remoteDispatchSupportsFeature;
+ args_filter = (xdrproc_t) xdr_remote_supports_feature_args;
+ args = (char *) &lv_remote_supports_feature_args;
+ memset (&lv_remote_supports_feature_args, 0, sizeof lv_remote_supports_feature_args);
+ ret_filter = (xdrproc_t) xdr_remote_supports_feature_ret;
+ ret = (char *) &lv_remote_supports_feature_ret;
+ memset (&lv_remote_supports_feature_ret, 0, sizeof lv_remote_supports_feature_ret);
+ break;
static int remoteDispatchNumOfDomains (struct qemud_client *client, remote_message_header *req, void *args, remote_num_of_domains_ret *ret);
static int remoteDispatchNumOfNetworks (struct qemud_client *client, remote_message_header *req, void *args, remote_num_of_networks_ret *ret);
static int remoteDispatchOpen (struct qemud_client *client, remote_message_header *req, remote_open_args *args, void *ret);
+static int remoteDispatchSupportsFeature (struct qemud_client *client, remote_message_header *req, remote_supports_feature_args *args, remote_supports_feature_ret *ret);
return TRUE;
}
+bool_t
+xdr_remote_supports_feature_args (XDR *xdrs, remote_supports_feature_args *objp)
+{
+
+ if (!xdr_int (xdrs, &objp->feature))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_remote_supports_feature_ret (XDR *xdrs, remote_supports_feature_ret *objp)
+{
+
+ if (!xdr_int (xdrs, &objp->supported))
+ return FALSE;
+ return TRUE;
+}
+
bool_t
xdr_remote_get_type_ret (XDR *xdrs, remote_get_type_ret *objp)
{
};
typedef struct remote_open_args remote_open_args;
+struct remote_supports_feature_args {
+ int feature;
+};
+typedef struct remote_supports_feature_args remote_supports_feature_args;
+
+struct remote_supports_feature_ret {
+ int supported;
+};
+typedef struct remote_supports_feature_ret remote_supports_feature_ret;
+
struct remote_get_type_ret {
remote_nonnull_string type;
};
REMOTE_PROC_DOMAIN_GET_SCHEDULER_PARAMETERS = 57,
REMOTE_PROC_DOMAIN_SET_SCHEDULER_PARAMETERS = 58,
REMOTE_PROC_GET_HOSTNAME = 59,
+ REMOTE_PROC_SUPPORTS_FEATURE = 60,
};
typedef enum remote_procedure remote_procedure;
extern bool_t xdr_remote_sched_param_value (XDR *, remote_sched_param_value*);
extern bool_t xdr_remote_sched_param (XDR *, remote_sched_param*);
extern bool_t xdr_remote_open_args (XDR *, remote_open_args*);
+extern bool_t xdr_remote_supports_feature_args (XDR *, remote_supports_feature_args*);
+extern bool_t xdr_remote_supports_feature_ret (XDR *, remote_supports_feature_ret*);
extern bool_t xdr_remote_get_type_ret (XDR *, remote_get_type_ret*);
extern bool_t xdr_remote_get_version_ret (XDR *, remote_get_version_ret*);
extern bool_t xdr_remote_get_hostname_ret (XDR *, remote_get_hostname_ret*);
extern bool_t xdr_remote_sched_param_value ();
extern bool_t xdr_remote_sched_param ();
extern bool_t xdr_remote_open_args ();
+extern bool_t xdr_remote_supports_feature_args ();
+extern bool_t xdr_remote_supports_feature_ret ();
extern bool_t xdr_remote_get_type_ret ();
extern bool_t xdr_remote_get_version_ret ();
extern bool_t xdr_remote_get_hostname_ret ();
int flags;
};
+struct remote_supports_feature_args {
+ int feature;
+};
+
+struct remote_supports_feature_ret {
+ int supported;
+};
+
struct remote_get_type_ret {
remote_nonnull_string type;
};
REMOTE_PROC_DOMAIN_GET_SCHEDULER_TYPE = 56,
REMOTE_PROC_DOMAIN_GET_SCHEDULER_PARAMETERS = 57,
REMOTE_PROC_DOMAIN_SET_SCHEDULER_PARAMETERS = 58,
- REMOTE_PROC_GET_HOSTNAME = 59
+ REMOTE_PROC_GET_HOSTNAME = 59,
+ REMOTE_PROC_SUPPORTS_FEATURE = 60
};
/* Custom RPC structure. */
VIR_DRV_OPEN_ERROR = -2,
} virDrvOpenStatus;
+/* Feature detection. This is a libvirt-private interface for determining
+ * what features are supported by the driver.
+ *
+ * The remote driver passes features through to the real driver at the
+ * remote end unmodified, except if you query a VIR_DRV_FEATURE_REMOTE*
+ * feature.
+ */
+ /* Driver supports V1-style virDomainMigrate, ie. domainMigratePrepare/
+ * domainMigratePerform/domainMigrateFinish.
+ */
+#define VIR_DRV_FEATURE_MIGRATION_V1 1
+
+ /* Driver is not local. */
+#define VIR_DRV_FEATURE_REMOTE 2
+
+/* Internal feature-detection macro. Don't call drv->supports_feature
+ * directly, because it may be NULL, use this macro instead.
+ *
+ * Note that you must check for errors.
+ *
+ * Returns:
+ * >= 1 Feature is supported.
+ * 0 Feature is not supported.
+ * -1 Error.
+ */
+#define VIR_DRV_SUPPORTS_FEATURE(drv,conn,feature) \
+ ((drv)->supports_feature ? (drv)->supports_feature((conn),(feature)) : 0)
+
typedef virDrvOpenStatus
(*virDrvOpen) (virConnectPtr conn,
const char *name,
int flags);
typedef int
(*virDrvClose) (virConnectPtr conn);
+typedef int
+ (*virDrvSupportsFeature) (virConnectPtr conn, int feature);
typedef const char *
(*virDrvGetType) (virConnectPtr conn);
typedef int
unsigned long ver; /* the version of the backend */
virDrvOpen open;
virDrvClose close;
+ virDrvSupportsFeature supports_feature;
virDrvGetType type;
virDrvGetVersion version;
virDrvGetHostname getHostname;
#define virStateReload() __virStateReload()
#define virStateActive() __virStateActive()
+int __virDrvSupportsFeature (virConnectPtr conn, int feature);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
return (0);
}
+/* Not for public use. This function is part of the internal
+ * implementation of driver features in the remote case.
+ */
+int
+__virDrvSupportsFeature (virConnectPtr conn, int feature)
+{
+ DEBUG("conn=%p, feature=%d", conn, feature);
+
+ if (!VIR_IS_CONNECT(conn))
+ return (-1);
+
+ return VIR_DRV_SUPPORTS_FEATURE (conn->driver, conn, feature);
+}
+
/**
* virConnectGetType:
* @conn: pointer to the hypervisor connection
__virStateReload;
__virStateActive;
+ __virDrvSupportsFeature;
+
local: *;
};
LIBVIR_VERSION_NUMBER,
qemudOpen, /* open */
qemudClose, /* close */
+ NULL, /* supports_feature */
qemudGetType, /* type */
qemudGetVersion, /* version */
NULL, /* hostname */
return ret;
}
+static int
+remoteSupportsFeature (virConnectPtr conn, int feature)
+{
+ remote_supports_feature_args args;
+ remote_supports_feature_ret ret;
+ GET_PRIVATE (conn, -1);
+
+ /* VIR_DRV_FEATURE_REMOTE* features are handled directly. */
+ if (feature == VIR_DRV_FEATURE_REMOTE) return 1;
+
+ args.feature = feature;
+
+ memset (&ret, 0, sizeof ret);
+ if (call (conn, priv, 0, REMOTE_PROC_SUPPORTS_FEATURE,
+ (xdrproc_t) xdr_remote_supports_feature_args, (char *) &args,
+ (xdrproc_t) xdr_remote_supports_feature_ret, (char *) &ret) == -1)
+ return -1;
+
+ return ret.supported;
+}
+
/* Unfortunately this function is defined to return a static string.
* Since the remote end always answers with the same type (for a
* single connection anyway) we cache the type in the connection's
.ver = REMOTE_PROTOCOL_VERSION,
.open = remoteOpen,
.close = remoteClose,
+ .supports_feature = remoteSupportsFeature,
.type = remoteType,
.version = remoteVersion,
.getHostname = remoteGetHostname,
LIBVIR_VERSION_NUMBER,
testOpen, /* open */
testClose, /* close */
+ NULL, /* supports_feature */
NULL, /* type */
testGetVersion, /* version */
testGetHostname, /* hostname */