return(ret);
}
+/**
+ * virGetDomainByID:
+ * @conn: the hypervisor connection
+ * @id: the ID number for the domain
+ *
+ * Lookup if the domain ID is already registered for that connection,
+ * if yes return a new pointer to it, if no return NULL
+ *
+ * Returns a pointer to the domain, or NULL if not found
+ */
+virDomainPtr
+virGetDomainByID(virConnectPtr conn, int id) {
+ virDomainPtr ret = NULL, cur;
+ virHashEntryPtr iter, next;
+ virHashTablePtr table;
+ int key;
+
+ if ((!VIR_IS_CONNECT(conn)) || (id < 0)) {
+ virHashError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ return(NULL);
+ }
+ xmlMutexLock(conn->domains_mux);
+
+ table = conn->domains;
+ if ((table == NULL) || (table->nbElems == 0))
+ goto done;
+ for (key = 0;key < table->size;key++) {
+ if (table->table[key].valid == 0)
+ continue;
+ iter = &(table->table[key]);
+ while (iter != NULL) {
+ next = iter->next;
+ cur = (virDomainPtr) iter->payload;
+ if ((cur != NULL) && (cur->handle == id)) {
+ ret = cur;
+ goto done;
+ }
+ iter = next;
+ }
+ }
+done:
+ xmlMutexUnlock(conn->domains_mux);
+ return(ret);
+}
virConnectListDomains(virConnectPtr conn, int *ids, int maxids)
{
int ret = -1;
- unsigned int i;
+ int i;
long id;
char **idlist = NULL;
return (-1);
}
+ /* Go though the driver registered entry points */
+ for (i = 0;i < conn->nb_drivers;i++) {
+ if ((conn->drivers[i] != NULL) &&
+ (conn->drivers[i]->listDomains != NULL)) {
+ ret = conn->drivers[i]->listDomains(conn, ids, maxids);
+ if (ret >= 0)
+ return(ret);
+ }
+ }
+
/*
- * try first though the Xen Daemon
+ * try then though the Xen Daemon
*/
idlist = xenDaemonListDomains(conn);
if (idlist != NULL) {
virConnectNumOfDomains(virConnectPtr conn)
{
int ret = -1;
+ int i;
char **idlist = NULL;
if (!VIR_IS_CONNECT(conn)) {
return (-1);
}
- /* TODO: there must be a way to do that with an hypervisor call too ! */
+ /* Go though the driver registered entry points */
+ for (i = 0;i < conn->nb_drivers;i++) {
+ if ((conn->drivers[i] != NULL) &&
+ (conn->drivers[i]->numOfDomains != NULL)) {
+ ret = conn->drivers[i]->numOfDomains(conn);
+ if (ret >= 0)
+ return(ret);
+ }
+ }
+
/*
- * try first with Xend interface
+ * try then with Xend interface
*/
idlist = xenDaemonListDomains(conn);
if (idlist != NULL) {
NULL, /* type */
xenHypervisorGetVersion, /* version */
NULL, /* nodeGetInfo */
- NULL, /* listDomains */
- NULL, /* numOfDomains */
+ xenHypervisorListDomains, /* listDomains */
+ xenHypervisorNumOfDomains, /* numOfDomains */
NULL, /* domainCreateLinux */
NULL, /* domainLookupByID */
NULL, /* domainLookupByUUID */
}
conn->handle = ret;
- return (ret);
+ return(0);
}
/**
return(0);
}
+/**
+ * xenHypervisorNumOfDomains:
+ * @conn: pointer to the connection block
+ *
+ * Provides the number of active domains.
+ *
+ * Returns the number of domain found or -1 in case of error
+ */
+int
+xenHypervisorNumOfDomains(virConnectPtr conn)
+{
+ dom0_op_t op;
+ dom0_getdomaininfo_t *dominfos;
+ int ret, nbids;
+ static int last_maxids = 2;
+ int maxids = last_maxids;
+
+ if ((conn == NULL) || (conn->handle < 0))
+ return (-1);
+
+retry:
+ dominfos = malloc(maxids * sizeof(dom0_getdomaininfo_t));
+ if (dominfos == NULL) {
+ virXenError(VIR_ERR_NO_MEMORY, "failed to allocate %d domain info",
+ maxids);
+ return(-1);
+ }
+
+ memset(dominfos, 0, sizeof(dom0_getdomaininfo_t) * maxids);
+
+ if (mlock(dominfos, sizeof(dom0_getdomaininfo_t) * maxids) < 0) {
+ virXenError(VIR_ERR_XEN_CALL, " locking",
+ sizeof(dom0_getdomaininfo_t) * maxids);
+ free(dominfos);
+ return (-1);
+ }
+
+ op.cmd = DOM0_GETDOMAININFOLIST;
+ op.u.getdomaininfolist.first_domain = (domid_t) 0;
+ op.u.getdomaininfolist.max_domains = maxids;
+ op.u.getdomaininfolist.buffer = dominfos;
+ op.u.getdomaininfolist.num_domains = maxids;
+
+ ret = xenHypervisorDoOp(conn->handle, &op);
+
+ if (munlock(dominfos, sizeof(dom0_getdomaininfo_t) * maxids) < 0) {
+ virXenError(VIR_ERR_XEN_CALL, " release",
+ sizeof(dom0_getdomaininfo_t) * maxids);
+ ret = -1;
+ }
+
+ free(dominfos);
+
+ if (ret < 0)
+ return (-1);
+
+ nbids = op.u.getdomaininfolist.num_domains;
+ if (nbids == maxids) {
+ last_maxids *= 2;
+ maxids *= 2;
+ goto retry;
+ }
+ if ((nbids < 0) || (nbids > maxids))
+ return(-1);
+ return(nbids);
+}
+
+/**
+ * xenHypervisorListDomains:
+ * @conn: pointer to the connection block
+ * @ids: array to collect the list of IDs of active domains
+ * @maxids: size of @ids
+ *
+ * Collect the list of active domains, and store their ID in @maxids
+ *
+ * Returns the number of domain found or -1 in case of error
+ */
+int
+xenHypervisorListDomains(virConnectPtr conn, int *ids, int maxids)
+{
+ dom0_op_t op;
+ dom0_getdomaininfo_t *dominfos;
+ int ret, nbids, i;
+
+ if ((conn == NULL) || (conn->handle < 0) ||
+ (ids == NULL) || (maxids < 1))
+ return (-1);
+
+ dominfos = malloc(maxids * sizeof(dom0_getdomaininfo_t));
+ if (dominfos == NULL) {
+ virXenError(VIR_ERR_NO_MEMORY, "failed to allocate %d domain info",
+ maxids);
+ return(-1);
+ }
+
+ memset(dominfos, 0, sizeof(dom0_getdomaininfo_t) * maxids);
+ memset(ids, 0, maxids * sizeof(int));
+
+ if (mlock(dominfos, sizeof(dom0_getdomaininfo_t) * maxids) < 0) {
+ virXenError(VIR_ERR_XEN_CALL, " locking",
+ sizeof(dom0_getdomaininfo_t) * maxids);
+ free(dominfos);
+ return (-1);
+ }
+
+ op.cmd = DOM0_GETDOMAININFOLIST;
+ op.u.getdomaininfolist.first_domain = (domid_t) 0;
+ op.u.getdomaininfolist.max_domains = maxids;
+ op.u.getdomaininfolist.buffer = dominfos;
+ op.u.getdomaininfolist.num_domains = maxids;
+
+ ret = xenHypervisorDoOp(conn->handle, &op);
+
+ if (munlock(dominfos, sizeof(dom0_getdomaininfo_t) * maxids) < 0) {
+ virXenError(VIR_ERR_XEN_CALL, " release",
+ sizeof(dom0_getdomaininfo_t) * maxids);
+ ret = -1;
+ }
+
+ if (ret < 0) {
+ free(dominfos);
+ return (-1);
+ }
+
+ nbids = op.u.getdomaininfolist.num_domains;
+ if ((nbids < 0) || (nbids > maxids)) {
+ free(dominfos);
+ return(-1);
+ }
+
+ for (i = 0;i < nbids;i++) {
+ ids[i] = dominfos[i].domain;
+ }
+
+ free(dominfos);
+ return (nbids);
+}
+
/**
* xenHypervisorGetDomainInfo:
* @domain: pointer to the domain block
memset(info, 0, sizeof(virDomainInfo));
memset(&dominfo, 0, sizeof(dom0_getdomaininfo_t));
- if (mlock(info, sizeof(dom0_getdomaininfo_t)) < 0) {
+ if (mlock(&dominfo, sizeof(dom0_getdomaininfo_t)) < 0) {
virXenError(VIR_ERR_XEN_CALL, " locking",
sizeof(dom0_getdomaininfo_t));
return (-1);
ret = xenHypervisorDoOp(domain->conn->handle, &op);
- if (munlock(info, sizeof(dom0_getdomaininfo_t)) < 0) {
+ if (munlock(&dominfo, sizeof(dom0_getdomaininfo_t)) < 0) {
virXenError(VIR_ERR_XEN_CALL, " release",
sizeof(dom0_getdomaininfo_t));
ret = -1;