diff options
Diffstat (limited to 'src/xend_internal.c')
-rw-r--r-- | src/xend_internal.c | 433 |
1 files changed, 131 insertions, 302 deletions
diff --git a/src/xend_internal.c b/src/xend_internal.c index 5ef6d6e92..e3ddbc0ac 100644 --- a/src/xend_internal.c +++ b/src/xend_internal.c @@ -666,35 +666,6 @@ sexpr_u64(struct sexpr *sexpr, const char *name) return 0; } -/** - * sexpr_u64: - * @sexpr: an S-Expression - * @name: the name for the value - * - * convenience function to lookup a value describing the default process when - * a domain stops - * - * Returns the value found or 0 if not found (but may not be an error) - */ -static virDomainRestart -sexpr_poweroff(struct sexpr *sexpr, const char *name) -{ - const char *value = sexpr_node(sexpr, name); - - if (value) { - if (strcmp(value, "poweroff") == 0) { - return VIR_DOMAIN_DESTROY; - } else if (strcmp(value, "restart") == 0) { - return VIR_DOMAIN_RESTART; - } else if (strcmp(value, "preserve") == 0) { - return VIR_DOMAIN_PRESERVE; - } else if (strcmp(value, "rename-restart") == 0) { - return VIR_DOMAIN_RENAME_RESTART; - } - } - return XEND_DEFAULT; -} - static int sexpr_strlen(struct sexpr *sexpr, const char *path) { @@ -716,36 +687,6 @@ sexpr_strcpy(char **ptr, struct sexpr *node, const char *path) return ret; } -/** - * sexpr_mode: - * @sexpr: an S-Expression - * @name: the name for the value - * - * convenience function to lookup a value describing a virtual block device - * mode from the S-Expression - * - * Returns the value found or 0 if not found (but may not be an error) - */ -static virDeviceMode -sexpr_mode(struct sexpr *node, const char *path) -{ - const char *mode = sexpr_node(node, path); - virDeviceMode ret; - - if (!mode) { - ret = VIR_DEVICE_DEFAULT; - } else if (strcmp(mode, "r") == 0) { - ret = VIR_DEVICE_RO; - } else if (strcmp(mode, "w") == 0) { - ret = VIR_DEVICE_RW; - } else if (strcmp(mode, "w!") == 0) { - ret = VIR_DEVICE_RW_FORCE; - } else { - ret = VIR_DEVICE_DEFAULT; - } - - return ret; -} /** * sexpr_node_system: @@ -772,31 +713,6 @@ sexpr_node_system(struct sexpr *node, const char *path) } /** - * sexpr_node_system: - * @mac: return value for the MAC address - * @sexpr: an S-Expression - * @name: the name for the value - * - * convenience function to lookup a MAC address (assumed ethernet and hence - * six bytes in length) from the S-Expression - * The value is returned in @mac - */ -static void -sexpr_mac(uint8_t * mac, struct sexpr *node, const char *path) -{ - const char *r = sexpr_node(node, path); - int mmac[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; - if (r) { - int i; - - sscanf(r, "%02x:%02x:%02x:%02x:%02x:%02x", - mmac + 0, mmac + 1, mmac + 2, mmac + 3, mmac + 4, mmac + 5); - for (i = 0; i < 6; i++) - mac[i] = mmac[i] & 0xFF; - } -} - -/** * sexpr_uuid: * @ptr: where to store the UUID, incremented * @sexpr: an S-Expression @@ -1171,211 +1087,6 @@ xend_set_memory(virConnectPtr xend, const char *name, uint64_t value) /** - * sexpr_to_xend_domain_size: - * @sexpr: the S-Expression - * @n_vbds: the number of virtual block devices used (OUT) - * @n_vifs: the number of network interface devices used (OUT) - * - * Helper function to compute the size in byte needed for the strings - * of a domain. - * - * Returns the number of bytes and the output parameters - */ -static size_t -sexpr_to_xend_domain_size(struct sexpr *root, int *n_vbds, int *n_vifs) -{ - size_t size = 0; - struct sexpr *_for_i, *node; - - size += sexpr_strlen(root, "domain/name"); - size += sexpr_strlen(root, "domain/image/linux/kernel"); - size += sexpr_strlen(root, "domain/image/linux/ramdisk"); - size += sexpr_strlen(root, "domain/image/linux/root"); - size += sexpr_strlen(root, "domain/image/linux/args"); - if (sexpr_node(root, "domain/uuid")) - size += 16; - - for (_for_i = root, node = root->car; _for_i->kind == SEXPR_CONS; - _for_i = _for_i->cdr, node = _for_i->car) { - if (sexpr_lookup(node, "device/vbd")) { - size += sexpr_strlen(node, "device/vbd/dev"); - size += sexpr_strlen(node, "device/vbd/uname"); - (*n_vbds)++; - } - } - - for (_for_i = root, node = root->car; _for_i->kind == SEXPR_CONS; - _for_i = _for_i->cdr, node = _for_i->car) { - if (sexpr_lookup(node, "device/vif")) { - size += sexpr_strlen(node, "device/vif/bridge"); - size += sexpr_strlen(node, "device/vif/ip"); - size += sexpr_strlen(node, "device/vif/script"); - size += sexpr_strlen(node, "device/vif/vifname"); - (*n_vifs)++; - } - } - - size += (*n_vbds) * sizeof(struct xend_device_vbd *); - size += (*n_vbds) * sizeof(struct xend_device_vbd); - - size += (*n_vifs) * sizeof(struct xend_device_vif *); - size += (*n_vifs) * sizeof(struct xend_device_vif); - - size += sizeof(struct xend_domain_live); - - size += sizeof(struct xend_domain); - - return size; -} - -/** - * sexpr_to_xend_domain: - * @root: an S-Expression describing a domain - * - * Internal routine creating a domain node based on the S-Expression - * provided by the Xen Daemon - * - * Returns a new structure or NULL in case of error. - */ -static struct xend_domain * -sexpr_to_xend_domain(struct sexpr *root) -{ - struct xend_domain *dom = NULL; - char *ptr; - int i; - int n_vbds = 0; - int n_vifs = 0; - struct sexpr *_for_i, *node; - - ptr = malloc(sexpr_to_xend_domain_size(root, &n_vbds, &n_vifs)); - if (ptr == NULL) - goto error; - - dom = (struct xend_domain *) ptr; - ptr += sizeof(struct xend_domain); - - dom->vbds = (struct xend_device_vbd *) ptr; - dom->n_vbds = n_vbds; - ptr += n_vbds * sizeof(struct xend_device_vbd); - - dom->vifs = (struct xend_device_vif *) ptr; - dom->n_vifs = n_vifs; - ptr += n_vifs * sizeof(struct xend_device_vif); - - dom->live = (struct xend_domain_live *) ptr; - ptr += sizeof(struct xend_domain_live); - - dom->name = sexpr_strcpy(&ptr, root, "domain/name"); - dom->uuid = sexpr_uuid(&ptr, root, "domain/uuid"); - dom->image.kernel = - sexpr_strcpy(&ptr, root, "domain/image/linux/kernel"); - dom->image.ramdisk = - sexpr_strcpy(&ptr, root, "domain/image/linux/ramdisk"); - dom->image.root = sexpr_strcpy(&ptr, root, "domain/image/linux/root"); - dom->image.extra = sexpr_strcpy(&ptr, root, "domain/image/linux/args"); - dom->memory = sexpr_u64(root, "domain/memory") << 20; - dom->max_memory = sexpr_u64(root, "domain/maxmem") << 20; - dom->ssidref = sexpr_int(root, "domain/ssidref"); - dom->on_poweroff = sexpr_poweroff(root, "domain/on_poweroff"); - dom->on_reboot = sexpr_poweroff(root, "domain/on_reboot"); - dom->on_crash = sexpr_poweroff(root, "domain/on_crash"); - dom->vcpus = sexpr_int(root, "domain/vcpus"); - - { - const char *flags = sexpr_node(root, "domain/state"); - - if (flags) { - dom->live->running = strchr(flags, 'r'); - dom->live->crashed = strchr(flags, 'c'); - dom->live->blocked = strchr(flags, 'b'); - dom->live->dying = strchr(flags, 'd'); - dom->live->paused = strchr(flags, 'p'); - dom->live->poweroff = false; - dom->live->reboot = false; - dom->live->suspend = false; - if (strchr(flags, 's') && - (flags = sexpr_node(root, "domain/shutdown_reason"))) { - if (strcmp(flags, "poweroff") == 0) { - dom->live->poweroff = true; - } else if (strcmp(flags, "reboot") == 0) { - dom->live->reboot = true; - } else if (strcmp(flags, "suspend") == 0) { - dom->live->suspend = true; - } - } - } - } - - dom->live->id = sexpr_int(root, "domain/domid"); - dom->live->cpu_time = sexpr_float(root, "domain/cpu_time"); - dom->live->up_time = sexpr_float(root, "domain/up_time"); - dom->live->start_time = sexpr_float(root, "domain/start_time"); - dom->live->online_vcpus = sexpr_int(root, "domain/online_vcpus"); - dom->live->vcpu_avail = sexpr_int(root, "domain/vcpu_avail"); - - i = 0; - for (_for_i = root, node = root->car; _for_i->kind == SEXPR_CONS; - _for_i = _for_i->cdr, node = _for_i->car) { - if (sexpr_lookup(node, "device/vbd")) { - dom->vbds[i].dev = sexpr_strcpy(&ptr, node, "device/vbd/dev"); - dom->vbds[i].uname = - sexpr_strcpy(&ptr, node, "device/vbd/uname"); - dom->vbds[i].backend = sexpr_int(node, "device/vbd/backend"); - dom->vbds[i].mode = sexpr_mode(node, "device/vbd/mode"); - i++; - } - } - - i = 0; - for (_for_i = root, node = root->car; _for_i->kind == SEXPR_CONS; - _for_i = _for_i->cdr, node = _for_i->car) { - if (sexpr_lookup(node, "device/vif")) { - dom->vifs[i].backend = sexpr_int(node, "device/vif/backend"); - dom->vifs[i].bridge = - sexpr_strcpy(&ptr, node, "device/vif/bridge"); - dom->vifs[i].ip = sexpr_strcpy(&ptr, node, "device/vif/ip"); - sexpr_mac(dom->vifs[i].mac, node, "device/vif/mac"); - dom->vifs[i].script = - sexpr_strcpy(&ptr, node, "device/vif/script"); - dom->vifs[i].vifname = - sexpr_strcpy(&ptr, node, "device/vif/vifname"); - i++; - } - } - - error: - return dom; -} - -/** - * xenDaemonDomainLookupByName: - * @xend: A xend instance - * @name: The name of the domain - * - * This method looks up information about a domain and returns - * it in the form of a struct xend_domain. This should be - * free()'d when no longer needed. - * - * Returns domain info on success; NULL (with errno) on error - */ -struct xend_domain * -xenDaemonDomainLookupByName(virConnectPtr xend, const char *domname) -{ - struct sexpr *root; - struct xend_domain *dom = NULL; - - root = sexpr_get(xend, "/xend/domain/%s?detail=1", domname); - if (root == NULL) - goto error; - - dom = sexpr_to_xend_domain(root); - - error: - sexpr_free(root); - return dom; -} - -/** * xenDaemonDomainLookupByName_ids: * @xend: A xend instance * @domname: The name of the domain @@ -1587,6 +1298,17 @@ xend_log(virConnectPtr xend, char *buffer, size_t n_buffer) return http2unix(xend_get(xend, "/xend/node/log", buffer, n_buffer)); } +/***************************************************************** + ****** + ****** + ****** + ****** + Needed helper code + ****** + ****** + ****** + ****** + *****************************************************************/ /** * xend_parse_sexp_desc: * @root: the root of the parsed S-Expression @@ -1742,17 +1464,6 @@ xend_parse_sexp_desc(struct sexpr *root) return (NULL); } -/***************************************************************** - ****** - ****** - ****** - ****** - Needed helper code - ****** - ****** - ****** - ****** - *****************************************************************/ /** * sexpr_to_xend_domain_info: * @root: an S-Expression describing a domain @@ -1797,6 +1508,56 @@ sexpr_to_xend_domain_info(struct sexpr *root, virDomainInfoPtr info) return (0); } +/** + * sexpr_to_domain: + * @conn: an existing virtual connection block + * @root: an S-Expression describing a domain + * + * Internal routine returning the associated virDomainPtr for this domain + * + * Returns the domain pointer or NULL in case of error. + */ +static virDomainPtr +sexpr_to_domain(virConnectPtr conn, struct sexpr *root) +{ + virDomainPtr ret; + char *dst_uuid = NULL; + const char *name; + + if ((conn == NULL) || (root == NULL)) + return(NULL); + + ret = (virDomainPtr) malloc(sizeof(virDomain)); + if (ret == NULL) { + virXendError(conn, VIR_ERR_NO_MEMORY, "Allocating domain"); + return(NULL); + } + memset(ret, 0, sizeof(virDomain)); + ret->magic = VIR_DOMAIN_MAGIC; + ret->conn = conn; + ret->handle = sexpr_int(root, "domain/domid"); + if (ret->handle < 0) + goto error; + dst_uuid = (char *) &(ret->uuid[0]); + if (sexpr_uuid(&dst_uuid, root, "domain/uuid") == NULL) + goto error; + name = sexpr_node(root, "domain/name"); + if (name == NULL) + goto error; + ret->name = strdup(name); + if (ret->name == NULL) + goto error; + + return (ret); +error: + virXendError(conn, VIR_ERR_INTERNAL_ERROR, + "failed to parse Xend domain informations"); + if (ret->name != NULL) + free(ret->name ); + free(ret); + return(NULL); +} + /***************************************************************** ****** @@ -1994,6 +1755,37 @@ xenDaemonDomainRestore(virConnectPtr conn, const char *filename) } /** + * xenDaemonDomainGetMaxMemory: + * @domain: pointer to the domain block + * + * Ask the Xen Daemon for the maximum memory allowed for a domain + * + * Returns the memory size in kilobytes or 0 in case of error. + */ +unsigned long +xenDaemonDomainGetMaxMemory(virDomainPtr domain) +{ + unsigned long ret = 0; + struct sexpr *root; + + if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) { + virXendError((domain ? domain->conn : NULL), VIR_ERR_INVALID_ARG, + __FUNCTION__); + return(-1); + } + + /* can we ask for a subset ? worth it ? */ + root = sexpr_get(domain->conn, "/xend/domain/%s?detail=1", domain->name); + if (root == NULL) + return(0); + + ret = (unsigned long) sexpr_u64(root, "domain/memory") << 10; + sexpr_free(root); + + return(ret); +} + +/** * xenDaemonDomainSetMaxMemory: * @domain: pointer to the Domain block * @memory: The maximum memory in kilobytes @@ -2067,8 +1859,13 @@ xenDaemonDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info) struct sexpr *root; int ret; - if ((domain == NULL) || (info == NULL)) - return (-1); + if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) || + (info == NULL)) { + virXendError((domain ? domain->conn : NULL), VIR_ERR_INVALID_ARG, + __FUNCTION__); + return(-1); + } + root = sexpr_get(domain->conn, "/xend/domain/%s?detail=1", domain->name); if (root == NULL) @@ -2079,3 +1876,35 @@ xenDaemonDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info) return (ret); } +/** + * xenDaemonDomainLookupByName: + * @conn: A xend instance + * @name: The name of the domain + * + * This method looks up information about a domain and returns + * it in the form of a struct xend_domain. This should be + * free()'d when no longer needed. + * + * Returns domain info on success; NULL (with errno) on error + */ +virDomainPtr +xenDaemonDomainLookupByName(virConnectPtr conn, const char *domname) +{ + struct sexpr *root; + virDomainPtr ret = NULL; + + if ((conn == NULL) || (domname == NULL)) { + virXendError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__); + return(NULL); + } + root = sexpr_get(conn, "/xend/domain/%s?detail=1", domname); + if (root == NULL) + goto error; + + ret = sexpr_to_domain(conn, root); + +error: + sexpr_free(root); + return(ret); +} + |