[libvirt PATCH v2] hyperv: Handle long CPU models better.
The existing driver code strips down CPU model strings returned by Hyper-V hosts so they fit into the 32 character limit of the virNodeInfo.model field. However, this did not work well for my AMD CPU for which Hyper-V returns the string "AMD FX(tm)-8350 Eight-Core Processor". Therefore, this patch improves that code block to be case insensitive (so that the "(tm)" part is removed) and additionally removes the trailing " Processor" suffix. While this change alone worked for me, I have also added a line to terminate the stripped down string at 32nd character to make sure that any other CPU string we did not come across yet won't trigger the error - the virNodeInfo has other useful info that is arguably more important than CPU model string, e.g. core count, or memory size Signed-off-by: Dawid Zamirski Reviewed-by: Neal Gompa --- Changes since v1: * Added missing Signed-off-by * Add Reviewed-by * Reworded commit message src/hyperv/hyperv_driver.c | 17 - 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c index 17f5be1f0d..6e03aa4f18 100644 --- a/src/hyperv/hyperv_driver.c +++ b/src/hyperv/hyperv_driver.c @@ -1948,14 +1948,14 @@ hypervNodeGetInfo(virConnectPtr conn, virNodeInfoPtr info) if (STRPREFIX(tmp, " ")) { memmove(tmp, tmp + 1, strlen(tmp + 1) + 1); continue; -} else if (STRPREFIX(tmp, "(R)") || STRPREFIX(tmp, "(C)")) { +} else if (STRCASEPREFIX(tmp, "(R)") || STRCASEPREFIX(tmp, "(C)")) { memmove(tmp, tmp + 3, strlen(tmp + 3) + 1); continue; -} else if (STRPREFIX(tmp, "(TM)")) { +} else if (STRCASEPREFIX(tmp, "(TM)")) { memmove(tmp, tmp + 4, strlen(tmp + 4) + 1); continue; -} else if (STRPREFIX(tmp, " @ ")) { -/* Remove " @ X.YZGHz" from the end. */ +} else if (STRPREFIX(tmp, " @ ") || STRPREFIX(tmp, " Processor")) { +/* Remove " @ X.YZGHz" or " Processor" from the end. */ *tmp = '\0'; break; } @@ -1963,13 +1963,12 @@ hypervNodeGetInfo(virConnectPtr conn, virNodeInfoPtr info) ++tmp; } +/* trim whatever is left to 32 characters - better this than nothing */ +processorList->data->Name[31] = '\0'; + /* Fill struct */ -if (virStrcpyStatic(info->model, processorList->data->Name) < 0) { -virReportError(VIR_ERR_INTERNAL_ERROR, - _("CPU model %s too long for destination"), - processorList->data->Name); +if (virStrcpyStatic(info->model, processorList->data->Name) < 0) return -1; -} info->memory = computerSystem->data->TotalPhysicalMemory / 1024; /* byte to kilobyte */ info->mhz = processorList->data->MaxClockSpeed; -- 2.31.1
[PATCH] hyperv: Handle long CPU models better.
Apparenlly exising code was dealing with stripping down Intel CPU models as reported by Hyper-V host but was still having issues with my AMD CPU for which Hyper-V returns "AMD FX(tm)-8350 Eight-Core Processor". Therefore, this patch deals with it by stripping out the " Processor" part, and if there's another CPU that we don't know of yet that causes trouble, trim the resulting string to 32 characters rather than failing as the node info has other information that are more useful than the model. --- src/hyperv/hyperv_driver.c | 17 - 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c index 17f5be1f0d..6e03aa4f18 100644 --- a/src/hyperv/hyperv_driver.c +++ b/src/hyperv/hyperv_driver.c @@ -1948,14 +1948,14 @@ hypervNodeGetInfo(virConnectPtr conn, virNodeInfoPtr info) if (STRPREFIX(tmp, " ")) { memmove(tmp, tmp + 1, strlen(tmp + 1) + 1); continue; -} else if (STRPREFIX(tmp, "(R)") || STRPREFIX(tmp, "(C)")) { +} else if (STRCASEPREFIX(tmp, "(R)") || STRCASEPREFIX(tmp, "(C)")) { memmove(tmp, tmp + 3, strlen(tmp + 3) + 1); continue; -} else if (STRPREFIX(tmp, "(TM)")) { +} else if (STRCASEPREFIX(tmp, "(TM)")) { memmove(tmp, tmp + 4, strlen(tmp + 4) + 1); continue; -} else if (STRPREFIX(tmp, " @ ")) { -/* Remove " @ X.YZGHz" from the end. */ +} else if (STRPREFIX(tmp, " @ ") || STRPREFIX(tmp, " Processor")) { +/* Remove " @ X.YZGHz" or " Processor" from the end. */ *tmp = '\0'; break; } @@ -1963,13 +1963,12 @@ hypervNodeGetInfo(virConnectPtr conn, virNodeInfoPtr info) ++tmp; } +/* trim whatever is left to 32 characters - better this than nothing */ +processorList->data->Name[31] = '\0'; + /* Fill struct */ -if (virStrcpyStatic(info->model, processorList->data->Name) < 0) { -virReportError(VIR_ERR_INTERNAL_ERROR, - _("CPU model %s too long for destination"), - processorList->data->Name); +if (virStrcpyStatic(info->model, processorList->data->Name) < 0) return -1; -} info->memory = computerSystem->data->TotalPhysicalMemory / 1024; /* byte to kilobyte */ info->mhz = processorList->data->MaxClockSpeed; -- 2.31.1
Re: [libvirt] [libvirt-php PATCH 0/2] Add binding for virDomainInterfaceAddresses
Hi Michal, Yes, please feel free to add: Signed-off-by: Dawid Zamirski to both messages. I'll make sure it is included in my future submissions from now on. Thanks, Dawid On Fri, 2019-07-12 at 17:12 +0200, Michal Privoznik wrote: > On 7/8/19 11:32 PM, Dawid Zamirski wrote: > > Hello, > > > > The following two patches add a new bingding for > > virDomainInterfaceAddresses. > > While working on it I have found that the PHP7 version of the > > VIRT_ARRAY_INIT macro was causing segfaults which I have fixed in > > the > > first patch wheread the actual implementation of the binding is in > > the > > second one. Details are included in the commit messages of each > > patch. > > > > Regards, > > Dawid > > > > Dawid Zamirski (2): > >Fix PHP7 VIRT_ARRAY_INIT macro implementation. > >Add binding for virDomainInterfaceAddresses. > > > > src/libvirt-domain.c | 55 > > > > src/libvirt-domain.h | 2 ++ > > src/libvirt-php.c| 9 > > src/util.h | 7 +++--- > > 4 files changed, 70 insertions(+), 3 deletions(-) > > > > Patches look good, but I cannot push them because they are missing > your > signoff. I can fix it, but I need your permisson to add the following > at > the end of both messages: > >Signed-off-by: Dawid Zamirski > > This confirms also that you've agreed to Developer Certificate of > Origin > 1.1: > >https://libvirt.org/hacking.html > > Michal > -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-php PATCH 1/2] Fix PHP7 VIRT_ARRAY_INIT macro implementation.
This is a PHP 7 compatibilty macro which was segfaulting due to the temporary variable being defined in the do..while scoped block (to swallow semicolon for macros), e.g: zval *arr; VIRT_ARRAY_INIT(arr); VIRT_ADD_ASSOC_STRING(arr, "foo", "bar"); // <= segfault here The VIRT_ARRAY_INIT above was expanding to: do { zval z_arr; // <= local scope definition arr = _arr; array_init(arr); } while (0) After this patch, the macro expands to: zval z_arr; // now defined in the scope of the macro caller do { arr = _arr; array_init(arr); } while (0) which solved the issue. --- src/util.h | 7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/util.h b/src/util.h index 3af77d4..c96fd0c 100644 --- a/src/util.h +++ b/src/util.h @@ -151,10 +151,11 @@ } \ } while(0) -# define VIRT_ARRAY_INIT(_name) do { \ +# define VIRT_ARRAY_INIT(_name) \ zval z##_name; \ -_name = ##_name; \ -array_init(_name); \ +do { \ + _name = ##_name; \ + array_init(_name); \ } while(0) # else /* PHP_MAJOR_VERSION < 7 */ -- 2.21.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-php PATCH 0/2] Add binding for virDomainInterfaceAddresses
Hello, The following two patches add a new bingding for virDomainInterfaceAddresses. While working on it I have found that the PHP7 version of the VIRT_ARRAY_INIT macro was causing segfaults which I have fixed in the first patch wheread the actual implementation of the binding is in the second one. Details are included in the commit messages of each patch. Regards, Dawid Dawid Zamirski (2): Fix PHP7 VIRT_ARRAY_INIT macro implementation. Add binding for virDomainInterfaceAddresses. src/libvirt-domain.c | 55 src/libvirt-domain.h | 2 ++ src/libvirt-php.c| 9 src/util.h | 7 +++--- 4 files changed, 70 insertions(+), 3 deletions(-) -- 2.21.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-php PATCH 2/2] Add binding for virDomainInterfaceAddresses.
A straight-forward 1:1 mapping to the C API. Returns array in the following format: array ( 0 => array ( 'name' => 'vnet0', 'hwaddr' => '52:54:00:3a:cd:94', 'naddrs' => 1, 'addrs' => array ( 'addr' => '192.168.254.224', 'prefix' => 24, 'type' => 0, ), ), ) --- src/libvirt-domain.c | 55 src/libvirt-domain.h | 2 ++ src/libvirt-php.c| 9 3 files changed, 66 insertions(+) diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c index 8b8bb45..877d311 100644 --- a/src/libvirt-domain.c +++ b/src/libvirt-domain.c @@ -1948,6 +1948,61 @@ PHP_FUNCTION(libvirt_domain_block_job_set_speed) RETURN_TRUE; } +/* + * Function name: libvirt_domain_interface_addresses + * Since version: 0.5.5 + * Description: Function is used to get network interface addresses for the domain + * Arguments: @domain [resource]: libvirt domain resource, e.g. from libvirt_domain_lookup_by_*() + * @source [int]: one of the VIR_DOMAIN_ADDRESSES_SRC_* flags. + * Returns: interface array of a domain holding information about addresses resembling the virDomainInterface structure, false on error + */ +PHP_FUNCTION(libvirt_domain_interface_addresses) +{ +php_libvirt_domain *domain = NULL; +zval *zdomain; +zend_long source = 0; + +virDomainInterfacePtr *ifaces = NULL; +int count = 0; +size_t i, j; + +GET_DOMAIN_FROM_ARGS("rl", , ); + +if ((count = virDomainInterfaceAddresses(domain->domain, , source, 0)) < 0) { +RETURN_FALSE +goto cleanup; +} + +array_init(return_value); + +for (i = 0; i < count; i++) { +zval *iface; +VIRT_ARRAY_INIT(iface); +VIRT_ADD_ASSOC_STRING(iface, "name", ifaces[i]->name); +VIRT_ADD_ASSOC_STRING(iface, "hwaddr", ifaces[i]->hwaddr); +add_assoc_long(iface, "naddrs", ifaces[i]->naddrs); + +for (j = 0; j < ifaces[i]->naddrs; j++) { +zval *ifaddr; +VIRT_ARRAY_INIT(ifaddr); +VIRT_ADD_ASSOC_STRING(ifaddr, "addr", ifaces[i]->addrs[j].addr); +add_assoc_long(ifaddr, "prefix", ifaces[i]->addrs[j].prefix); +add_assoc_long(ifaddr, "type", ifaces[i]->addrs[j].type); + +add_assoc_zval(iface, "addrs", ifaddr); +} + +add_index_zval(return_value, i, iface); +} + + cleanup: +if (ifaces && count > 0) { +for (i = 0; i < count; i++) +virDomainInterfaceFree(ifaces[i]); +} +VIR_FREE(ifaces); +} + /* * Function name: libvirt_domain_interface_stats * Since version: 0.4.1(-1) diff --git a/src/libvirt-domain.h b/src/libvirt-domain.h index dc0ab46..f15237f 100644 --- a/src/libvirt-domain.h +++ b/src/libvirt-domain.h @@ -89,6 +89,7 @@ PHP_FE(libvirt_domain_block_job_info, arginfo_libvirt_domain_block_job_info)\ PHP_FE(libvirt_domain_block_job_abort, arginfo_libvirt_domain_block_job_abort) \ PHP_FE(libvirt_domain_block_job_set_speed, arginfo_libvirt_domain_block_job_set_speed) \ +PHP_FE(libvirt_domain_interface_addresses, arginfo_libvirt_domain_interface_addresses) \ PHP_FE(libvirt_domain_interface_stats, arginfo_libvirt_conn_path) \ PHP_FE(libvirt_domain_get_connect, arginfo_libvirt_conn) \ PHP_FE(libvirt_domain_migrate, arginfo_libvirt_domain_migrate) \ @@ -179,6 +180,7 @@ PHP_FUNCTION(libvirt_domain_block_resize); PHP_FUNCTION(libvirt_domain_block_job_info); PHP_FUNCTION(libvirt_domain_block_job_abort); PHP_FUNCTION(libvirt_domain_block_job_set_speed); +PHP_FUNCTION(libvirt_domain_interface_addresses); PHP_FUNCTION(libvirt_domain_interface_stats); PHP_FUNCTION(libvirt_domain_get_connect); PHP_FUNCTION(libvirt_domain_migrate); diff --git a/src/libvirt-php.c b/src/libvirt-php.c index cf8fd7f..04b7c07 100644 --- a/src/libvirt-php.c +++ b/src/libvirt-php.c @@ -248,6 +248,11 @@ ZEND_ARG_INFO(0, bandwidth) ZEND_ARG_INFO(0, flags) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO_EX(arginfo_libvirt_domain_interface_addresses, 0, 0, 2) +ZEND_ARG_INFO(0, domain) +ZEND_ARG_INFO(0, source) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_INFO_EX(arginfo_libvirt_domain_block_job_info, 0, 0, 2) ZEND_ARG_INFO(0, dom) ZEND_ARG_INFO(0, disk) @@ -1476,6 +1481,10 @@ PHP_MINIT_FUNCTION(libvirt) REGISTER_LONG_CONSTANT("VIR_DOMAIN_MEM_LIVE", VIR_DOMAIN_MEM_LIVE, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("VIR_DOMAIN_MEM_MAXIMUM", VIR_DOMAIN_MEM_MAXIMUM, CONST_CS | CONST_PERSISTENT); +REGISTER_LONG_CONSTANT("VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_LEASE", VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_LEASE, CONST_CS | CONST_PERSISTENT); +REGISTER_LONG_CONSTANT("VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT", VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT, CONST_CS | CONST_PERSISTENT); +
[libvirt] [PATCH php v2] Fix crash in VIRT_HASH_CURRENT_KEY_INFO macro
The PHP7 variant of the macro wasn't safe if the hash key was not a string type. This was found when running php script with just libvirt_connect call under xdebug session which segfaulted. This patch makes the following changes: * make sure that tmp_name is initialized to NULL * set the key name only when zend_hash_get_current_key_ex did set it to something which happens only when type is HASH_KEY_IS_STRING * stash the key index in out php_libvirt_hash_key_info struct because it wasn't there before and separate variable had to be used. --- v1: https://www.redhat.com/archives/libvir-list/2017-December/msg00151.html Changes since v1: * use zend_ulong in php_libvirt_hash_key_info struct so that no type cast is needed src/libvirt-connection.c | 8 +++- src/libvirt-php.c| 6 ++ src/libvirt-php.h| 1 + src/util.h | 16 +--- 4 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/libvirt-connection.c b/src/libvirt-connection.c index 181b266..2d59d82 100644 --- a/src/libvirt-connection.c +++ b/src/libvirt-connection.c @@ -131,8 +131,6 @@ PHP_FUNCTION(libvirt_connect) HashPosition pointer; int array_count; -zend_ulong index; - unsigned long libVer; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sba", , _len, , ) == FAILURE) { @@ -176,13 +174,13 @@ PHP_FUNCTION(libvirt_connect) VIRT_FOREACH(arr_hash, pointer, data) { if (Z_TYPE_P(data) == IS_STRING) { php_libvirt_hash_key_info info; -VIRT_HASH_CURRENT_KEY_INFO(arr_hash, pointer, index, info); +VIRT_HASH_CURRENT_KEY_INFO(arr_hash, pointer, info); if (info.type == HASH_KEY_IS_STRING) { PHPWRITE(info.name, info.length); } else { -DPRINTF("%s: credentials index %d\n", PHPFUNC, (int)index); -creds[j].type = index; +DPRINTF("%s: credentials index %d\n", PHPFUNC, info.index); +creds[j].type = info.index; creds[j].result = (char *)emalloc(Z_STRLEN_P(data) + 1); memset(creds[j].result, 0, Z_STRLEN_P(data) + 1); creds[j].resultlen = Z_STRLEN_P(data); diff --git a/src/libvirt-php.c b/src/libvirt-php.c index ef057fe..efbef58 100644 --- a/src/libvirt-php.c +++ b/src/libvirt-php.c @@ -1921,7 +1921,6 @@ long get_next_free_numeric_value(virDomainPtr domain, char *xpath) HashPosition pointer; // int array_count; zval *data; -unsigned long index; long max_slot = -1; xml = virDomainGetXMLDesc(domain, VIR_DOMAIN_XML_INACTIVE); @@ -1934,7 +1933,7 @@ long get_next_free_numeric_value(virDomainPtr domain, char *xpath) VIRT_FOREACH(arr_hash, pointer, data) { if (Z_TYPE_P(data) == IS_STRING) { php_libvirt_hash_key_info info; -VIRT_HASH_CURRENT_KEY_INFO(arr_hash, pointer, index, info); +VIRT_HASH_CURRENT_KEY_INFO(arr_hash, pointer, info); if (info.type != HASH_KEY_IS_STRING) { long num = -1; @@ -2439,7 +2438,6 @@ void parse_array(zval *arr, tVMDisk *disk, tVMNetwork *network) zval *data; php_libvirt_hash_key_info key; HashPosition pointer; -unsigned long index; arr_hash = Z_ARRVAL_P(arr); //array_count = zend_hash_num_elements(arr_hash); @@ -2451,7 +2449,7 @@ void parse_array(zval *arr, tVMDisk *disk, tVMNetwork *network) VIRT_FOREACH(arr_hash, pointer, data) { if ((Z_TYPE_P(data) == IS_STRING) || (Z_TYPE_P(data) == IS_LONG)) { -VIRT_HASH_CURRENT_KEY_INFO(arr_hash, pointer, index, key); +VIRT_HASH_CURRENT_KEY_INFO(arr_hash, pointer, key); if (key.type == HASH_KEY_IS_STRING) { if (disk != NULL) { if ((Z_TYPE_P(data) == IS_STRING) && strcmp(key.name, "path") == 0) diff --git a/src/libvirt-php.h b/src/libvirt-php.h index 8d13a6b..aea43a2 100644 --- a/src/libvirt-php.h +++ b/src/libvirt-php.h @@ -137,6 +137,7 @@ typedef struct tVMNetwork { typedef struct _php_libvirt_hash_key_info { char *name; unsigned int length; +zend_ulong index; unsigned int type; } php_libvirt_hash_key_info; diff --git a/src/util.h b/src/util.h index ecb3a1f..fcd4075 100644 --- a/src/util.h +++ b/src/util.h @@ -135,12 +135,14 @@ # define VIRT_FOREACH_END(_dummy) -# define VIRT_HASH_CURRENT_KEY_INFO(_ht, _pos, _idx, _info) \ +# define VIRT_HASH_CURRENT_KEY_INFO(_ht, _pos, _info) \ do { \ -zend_string *tmp_key_info; \ -_info.type = zend_hash_get_current_key_ex(_ht, _key_info, &_idx, &_pos); \ -_info.name = ZSTR_VAL(tmp_key_info); \ -_info.length = ZSTR_LEN(tmp_key_info); \ +zend_string *tmp_name = NULL; \ +_info.type = zend_hash_get_current_key_ex(_ht, _name, &_info.index, &_pos); \ +if (tmp_name) { \ +_info.name = ZSTR_VAL(tmp_name);
Re: [libvirt] [libvirt-php PATCH] Fix crash in VIRT_HASH_CURRENT_KEY_INFO macro
On Wed, 2017-12-06 at 11:40 -0500, Dawid Zamirski wrote: > On Wed, 2017-12-06 at 16:21 +0100, Michal Privoznik wrote: > > On 12/06/2017 12:17 AM, Dawid Zamirski wrote: > > > > > > &_info.length, &_info.index, 0, &_pos); \ > > > > but not here. Does that work for you? > > > > It does but with a compiler warning :-) I did not realize PHP5 had > zend_ulong and I thought it was introduced only in PHP7. V2 coming in > a > minute. Well PHP5 indeed does not have zend_ulong but we do typedef it already in src/util.h > > Thanks, > Dawid > > > Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [libvirt-php PATCH] Fix crash in VIRT_HASH_CURRENT_KEY_INFO macro
On Wed, 2017-12-06 at 16:21 +0100, Michal Privoznik wrote: > On 12/06/2017 12:17 AM, Dawid Zamirski wrote: > > > > &_info.length, &_info.index, 0, &_pos); \ > > but not here. Does that work for you? > It does but with a compiler warning :-) I did not realize PHP5 had zend_ulong and I thought it was introduced only in PHP7. V2 coming in a minute. Thanks, Dawid > Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-php PATCH] Fix crash in VIRT_HASH_CURRENT_KEY_INFO macro
The PHP7 variant of the macro wasn't safe if the hash key was not a string type. This was found when running php script with just libvirt_connect call under xdebug session which segfaulted. This patch makes the following changes: * make sure that tmp_name is initialized to NULL * set the key name only when zend_hash_get_current_key_ex did set it to something which happens only when type is HASH_KEY_IS_STRING * stash the key index in out php_libvirt_hash_key_info struct because it wasn't there before and separate variable had to be used. --- src/libvirt-connection.c | 8 +++- src/libvirt-php.c| 6 ++ src/libvirt-php.h| 1 + src/util.h | 16 +--- 4 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/libvirt-connection.c b/src/libvirt-connection.c index 181b266..2d59d82 100644 --- a/src/libvirt-connection.c +++ b/src/libvirt-connection.c @@ -131,8 +131,6 @@ PHP_FUNCTION(libvirt_connect) HashPosition pointer; int array_count; -zend_ulong index; - unsigned long libVer; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sba", , _len, , ) == FAILURE) { @@ -176,13 +174,13 @@ PHP_FUNCTION(libvirt_connect) VIRT_FOREACH(arr_hash, pointer, data) { if (Z_TYPE_P(data) == IS_STRING) { php_libvirt_hash_key_info info; -VIRT_HASH_CURRENT_KEY_INFO(arr_hash, pointer, index, info); +VIRT_HASH_CURRENT_KEY_INFO(arr_hash, pointer, info); if (info.type == HASH_KEY_IS_STRING) { PHPWRITE(info.name, info.length); } else { -DPRINTF("%s: credentials index %d\n", PHPFUNC, (int)index); -creds[j].type = index; +DPRINTF("%s: credentials index %d\n", PHPFUNC, info.index); +creds[j].type = info.index; creds[j].result = (char *)emalloc(Z_STRLEN_P(data) + 1); memset(creds[j].result, 0, Z_STRLEN_P(data) + 1); creds[j].resultlen = Z_STRLEN_P(data); diff --git a/src/libvirt-php.c b/src/libvirt-php.c index ef057fe..efbef58 100644 --- a/src/libvirt-php.c +++ b/src/libvirt-php.c @@ -1921,7 +1921,6 @@ long get_next_free_numeric_value(virDomainPtr domain, char *xpath) HashPosition pointer; // int array_count; zval *data; -unsigned long index; long max_slot = -1; xml = virDomainGetXMLDesc(domain, VIR_DOMAIN_XML_INACTIVE); @@ -1934,7 +1933,7 @@ long get_next_free_numeric_value(virDomainPtr domain, char *xpath) VIRT_FOREACH(arr_hash, pointer, data) { if (Z_TYPE_P(data) == IS_STRING) { php_libvirt_hash_key_info info; -VIRT_HASH_CURRENT_KEY_INFO(arr_hash, pointer, index, info); +VIRT_HASH_CURRENT_KEY_INFO(arr_hash, pointer, info); if (info.type != HASH_KEY_IS_STRING) { long num = -1; @@ -2439,7 +2438,6 @@ void parse_array(zval *arr, tVMDisk *disk, tVMNetwork *network) zval *data; php_libvirt_hash_key_info key; HashPosition pointer; -unsigned long index; arr_hash = Z_ARRVAL_P(arr); //array_count = zend_hash_num_elements(arr_hash); @@ -2451,7 +2449,7 @@ void parse_array(zval *arr, tVMDisk *disk, tVMNetwork *network) VIRT_FOREACH(arr_hash, pointer, data) { if ((Z_TYPE_P(data) == IS_STRING) || (Z_TYPE_P(data) == IS_LONG)) { -VIRT_HASH_CURRENT_KEY_INFO(arr_hash, pointer, index, key); +VIRT_HASH_CURRENT_KEY_INFO(arr_hash, pointer, key); if (key.type == HASH_KEY_IS_STRING) { if (disk != NULL) { if ((Z_TYPE_P(data) == IS_STRING) && strcmp(key.name, "path") == 0) diff --git a/src/libvirt-php.h b/src/libvirt-php.h index 8d13a6b..f24a329 100644 --- a/src/libvirt-php.h +++ b/src/libvirt-php.h @@ -137,6 +137,7 @@ typedef struct tVMNetwork { typedef struct _php_libvirt_hash_key_info { char *name; unsigned int length; +unsigned int index; unsigned int type; } php_libvirt_hash_key_info; diff --git a/src/util.h b/src/util.h index ecb3a1f..72cfa91 100644 --- a/src/util.h +++ b/src/util.h @@ -135,12 +135,14 @@ # define VIRT_FOREACH_END(_dummy) -# define VIRT_HASH_CURRENT_KEY_INFO(_ht, _pos, _idx, _info) \ +# define VIRT_HASH_CURRENT_KEY_INFO(_ht, _pos, _info) \ do { \ -zend_string *tmp_key_info; \ -_info.type = zend_hash_get_current_key_ex(_ht, _key_info, &_idx, &_pos); \ -_info.name = ZSTR_VAL(tmp_key_info); \ -_info.length = ZSTR_LEN(tmp_key_info); \ +zend_string *tmp_name = NULL; \ +_info.type = zend_hash_get_current_key_ex(_ht, _name, (zend_ulong *) &_info.index, &_pos); \ +if (tmp_name) { \ +_info.name = ZSTR_VAL(tmp_name); \ +_info.length = ZSTR_LEN(tmp_name); \ +} \ } while(0) # define VIRT_ARRAY_INIT(_name) do { \ @@ -213,9 +215,9 @@ # define
[libvirt] [PATCH 3/2] news: Update for vbox 5.2 support
--- docs/news.xml | 5 + 1 file changed, 5 insertions(+) diff --git a/docs/news.xml b/docs/news.xml index 9361a9165..630784a0a 100644 --- a/docs/news.xml +++ b/docs/news.xml @@ -37,6 +37,11 @@ + + + vbox: Add VirtualBox 5.2 support + + vbox: Add support for configuring storage controllers -- 2.14.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 1/2] vbox: Add vbox 5.2 CAPI header file.
Extracted from 5.2 SDK and reindented with cppi 0001-vbox-Add-vbox-5.2-CAPI-header-file.tar.xz Description: application/xz-compressed-tar -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 2/2] vbox: Add support for 5.2.x
Simply add the 5.2 SDK header to the existing unified framework. No other special handling is needed as there's no API break between exising 5.1 and the just added 5.2. --- src/Makefile.am | 1 + src/vbox/vbox_V5_2.c | 13 + src/vbox/vbox_common.h| 2 ++ src/vbox/vbox_storage.c | 2 ++ src/vbox/vbox_tmpl.c | 2 ++ src/vbox/vbox_uniformed_api.h | 1 + 6 files changed, 21 insertions(+) create mode 100644 src/vbox/vbox_V5_2.c diff --git a/src/Makefile.am b/src/Makefile.am index 1d2423124..de43d0f50 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -881,6 +881,7 @@ VBOX_DRIVER_SOURCES = \ vbox/vbox_V4_3_4.c vbox/vbox_CAPI_v4_3_4.h \ vbox/vbox_V5_0.c vbox/vbox_CAPI_v5_0.h \ vbox/vbox_V5_1.c vbox/vbox_CAPI_v5_1.h \ + vbox/vbox_V5_2.c vbox/vbox_CAPI_v5_2.h \ vbox/vbox_common.c vbox/vbox_common.h \ vbox/vbox_uniformed_api.h \ vbox/vbox_get_driver.h \ diff --git a/src/vbox/vbox_V5_2.c b/src/vbox/vbox_V5_2.c new file mode 100644 index 0..86d40f3f7 --- /dev/null +++ b/src/vbox/vbox_V5_2.c @@ -0,0 +1,13 @@ +/** @file vbox_V5_2.c + * C file to include support for multiple versions of VirtualBox + * at runtime. + */ + +#include + +/** The API Version */ +#define VBOX_API_VERSION 5002000 +/** Version specific prefix. */ +#define NAME(name) vbox52##name + +#include "vbox_tmpl.c" diff --git a/src/vbox/vbox_common.h b/src/vbox/vbox_common.h index 05636fea2..5709ff8b4 100644 --- a/src/vbox/vbox_common.h +++ b/src/vbox/vbox_common.h @@ -446,6 +446,8 @@ typedef nsISupports IKeyboard; vbox50InstallUniformedAPI(); \ } else if (uVersion >= 551 && uVersion < 5001051) { \ vbox51InstallUniformedAPI(); \ +} else if (uVersion >= 5001051 && uVersion < 5002051) { \ +vbox52InstallUniformedAPI(); \ } else { \ result = -1; \ } \ diff --git a/src/vbox/vbox_storage.c b/src/vbox/vbox_storage.c index c2de1ce23..672caa6f9 100644 --- a/src/vbox/vbox_storage.c +++ b/src/vbox/vbox_storage.c @@ -902,6 +902,8 @@ virStorageDriverPtr vboxGetStorageDriver(uint32_t uVersion) vbox50InstallUniformedAPI(); } else if (uVersion >= 551 && uVersion < 5001051) { vbox51InstallUniformedAPI(); +} else if (uVersion >= 5001051 && uVersion < 5002051) { +vbox52InstallUniformedAPI(); } else { return NULL; } diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c index 98d4bbf0d..88792c992 100644 --- a/src/vbox/vbox_tmpl.c +++ b/src/vbox/vbox_tmpl.c @@ -65,6 +65,8 @@ # include "vbox_CAPI_v5_0.h" #elif VBOX_API_VERSION == 5001000 # include "vbox_CAPI_v5_1.h" +#elif VBOX_API_VERSION == 5002000 +# include "vbox_CAPI_v5_2.h" #else # error "Unsupport VBOX_API_VERSION" #endif diff --git a/src/vbox/vbox_uniformed_api.h b/src/vbox/vbox_uniformed_api.h index c51191e7d..65c24d094 100644 --- a/src/vbox/vbox_uniformed_api.h +++ b/src/vbox/vbox_uniformed_api.h @@ -564,5 +564,6 @@ void vbox43InstallUniformedAPI(vboxUniformedAPI *pVBoxAPI); void vbox43_4InstallUniformedAPI(vboxUniformedAPI *pVBoxAPI); void vbox50InstallUniformedAPI(vboxUniformedAPI *pVBoxAPI); void vbox51InstallUniformedAPI(vboxUniformedAPI *pVBoxAPI); +void vbox52InstallUniformedAPI(vboxUniformedAPI *pVBoxAPI); #endif /* VBOX_UNIFORMED_API_H */ -- 2.14.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 0/2] vbox: Add support for 5.2.x
With each minor VBOX release a new SDK header needs to be added and wired up to the driver. This is basically the same as last time [1]. The first patch will be sent as a compressed attachment because it's a large header file taken from the SDK that would not pass the mailing list size constraints. [1] https://www.redhat.com/archives/libvir-list/2016-November/msg00355.html Dawid Zamirski (2): vbox: Add vbox 5.2 CAPI header file. vbox: Add support for 5.2.x src/Makefile.am | 1 + src/vbox/vbox_CAPI_v5_2.h | 26870 src/vbox/vbox_V5_2.c |13 + src/vbox/vbox_common.h| 2 + src/vbox/vbox_storage.c | 2 + src/vbox/vbox_tmpl.c | 2 + src/vbox/vbox_uniformed_api.h | 1 + 7 files changed, 26891 insertions(+) create mode 100644 src/vbox/vbox_CAPI_v5_2.h create mode 100644 src/vbox/vbox_V5_2.c -- 2.14.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 1/2] docs: Update vbox driver documentation.
On Tue, 2017-11-07 at 17:05 -0500, John Ferlan wrote: > > On 11/07/2017 04:36 PM, Dawid Zamirski wrote: > > * libvirt no longer supports vbox <= 3.x > > * update XML definition sample to show how to attach disks to > > VBOX's SAS > > controller and how to change IDE controller model. > > * update XML to show how to create RDP display with autoport. > > --- > > docs/drvvbox.html.in | 28 +++- > > 1 file changed, 27 insertions(+), 1 deletion(-) > > > > diff --git a/docs/drvvbox.html.in b/docs/drvvbox.html.in > > index 63f166b24..a56f5db11 100644 > > --- a/docs/drvvbox.html.in > > +++ b/docs/drvvbox.html.in > > @@ -5,7 +5,7 @@ > > VirtualBox hypervisor driver > > > > The libvirt VirtualBox driver can manage any VirtualBox > > version > > -from version 2.2 onwards. > > +from version 4.0 onwards. > > Hmmm... we should have changed that as part of commit id '73c6f16ba' > or > 'ccdf108c'. > > Mind if I add a "(since libvirt 3.0.0)" > prior > to the end of line? > Sure no problem :-) > E.g.: > >The libvirt VirtualBox driver can manage any VirtualBox > version >from version 4.0 onwards >(since libvirt 3.0.0). > > > > > > > Project Links > > @@ -68,6 +68,14 @@ vbox+ssh://u...@example.com/session (remote > > access, SSH tunnelled) > >/features > > > >devices > > +!--Set IDE controller model to PIIX4 (default PIIX3)-- > > +controller type='ide' model='piix4'/ > > + > > +controller type='scsi' index='0'/ > > + > > +!--VirtualBox SAS Controller-- > > +controller type='scsi' index='1' model='lsisas1068'/ > > + > > disk type='file' device='cdrom' > >source file='/home/user/Downloads/slax-6.0.9.iso'/ > >target dev='hdc'/ > > @@ -79,6 +87,19 @@ vbox+ssh://u...@example.com/session (remote > > access, SSH tunnelled) > >target dev='hdd'/ > > /disk > > > > +!--Attach to the SCSI controller (index=0, default)-- > > +disk type='file' device='disk' > > + source file='/home/user/tmp/vbox2.vdi'/ > > + target dev='sda' bus='scsi'/ > > +/disk > > + > > +!--Attach to the SAS controller (index=1)-- > > +disk type='file' device='disk' > > + source file='/home/user/tmp/vbox3.vdi'/ > > + target dev='sda' bus='scsi'/ > > + address type='drive' controller='1' bus='0' target='0' > > unit='0'/ > > +/disk > > + > > disk type='file' device='floppy' > >source file='/home/user/tmp/WIN98C.IMG'/ > >target dev='fda'/ > > @@ -101,6 +122,11 @@ vbox+ssh://u...@example.com/session (remote > > access, SSH tunnelled) > >mac address='56:16:3e:5d:c7:9e'/ > >model type='82540eM'/ > > /interface > > + > > There's some extraneous whitespace above as git am so kindly told me: > > Applying: docs: Update vbox driver documentation. > .git/rebase-apply/patch:57: trailing whitespace. > > warning: 1 line adds whitespace errors. > > I will fix up before pushing... > > John > > > +graphics type='desktop'/ > > + > > +!--Activate the VRDE server with a port in 3389-3689 > > range-- > > +graphics type='rdp' autoport='yes' multiUser='yes'/ > > > > sound model='sb16'/ > > > > -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 2/2] docs: Document autoport behavior in the vbox driver
--- docs/formatdomain.html.in | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 92e14a919..d3cabac44 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -6100,7 +6100,10 @@ qemu-kvm -net nic,model=? /dev/null TCP port number (with -1 as legacy syntax indicating that it should be auto-allocated). The autoport attribute is the new preferred syntax for indicating auto-allocation of the TCP port to - use. The multiUser attribute is a boolean deciding + use. In the VirtualBox driver, the autoport will make + the hypervisor pick available port from 3389-3689 range when the VM + is started. The chosen port will be reflected in the port + attribute. The multiUser attribute is a boolean deciding whether multiple simultaneous connections to the VM are permitted. The replaceUser attribute is a boolean deciding whether the existing connection must be dropped and a new connection must -- 2.14.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 0/2] Update documentation for latest vbox changes.
* update docs/drvvbox.html.in to show support for * update docs/fomatdomain.html.in to describe autoport behavior in the vbox driver Dawid Zamirski (2): docs: Update vbox driver documentation. docs: Document autoport behavior in the vbox driver docs/drvvbox.html.in | 28 +++- docs/formatdomain.html.in | 5 - 2 files changed, 31 insertions(+), 2 deletions(-) -- 2.14.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 1/2] docs: Update vbox driver documentation.
* libvirt no longer supports vbox <= 3.x * update XML definition sample to show how to attach disks to VBOX's SAS controller and how to change IDE controller model. * update XML to show how to create RDP display with autoport. --- docs/drvvbox.html.in | 28 +++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/docs/drvvbox.html.in b/docs/drvvbox.html.in index 63f166b24..a56f5db11 100644 --- a/docs/drvvbox.html.in +++ b/docs/drvvbox.html.in @@ -5,7 +5,7 @@ VirtualBox hypervisor driver The libvirt VirtualBox driver can manage any VirtualBox version -from version 2.2 onwards. +from version 4.0 onwards. Project Links @@ -68,6 +68,14 @@ vbox+ssh://u...@example.com/session (remote access, SSH tunnelled) /features devices +!--Set IDE controller model to PIIX4 (default PIIX3)-- +controller type='ide' model='piix4'/ + +controller type='scsi' index='0'/ + +!--VirtualBox SAS Controller-- +controller type='scsi' index='1' model='lsisas1068'/ + disk type='file' device='cdrom' source file='/home/user/Downloads/slax-6.0.9.iso'/ target dev='hdc'/ @@ -79,6 +87,19 @@ vbox+ssh://u...@example.com/session (remote access, SSH tunnelled) target dev='hdd'/ /disk +!--Attach to the SCSI controller (index=0, default)-- +disk type='file' device='disk' + source file='/home/user/tmp/vbox2.vdi'/ + target dev='sda' bus='scsi'/ +/disk + +!--Attach to the SAS controller (index=1)-- +disk type='file' device='disk' + source file='/home/user/tmp/vbox3.vdi'/ + target dev='sda' bus='scsi'/ + address type='drive' controller='1' bus='0' target='0' unit='0'/ +/disk + disk type='file' device='floppy' source file='/home/user/tmp/WIN98C.IMG'/ target dev='fda'/ @@ -101,6 +122,11 @@ vbox+ssh://u...@example.com/session (remote access, SSH tunnelled) mac address='56:16:3e:5d:c7:9e'/ model type='82540eM'/ /interface + +graphics type='desktop'/ + +!--Activate the VRDE server with a port in 3389-3689 range-- +graphics type='rdp' autoport='yes' multiUser='yes'/ sound model='sb16'/ -- 2.14.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v2 12/15] vbox: Correctly generate drive name in dumpxml
On Fri, 2017-11-03 at 09:52 -0400, John Ferlan wrote: > > On 10/24/2017 03:35 PM, Dawid Zamirski wrote: > > If a VBOX VM has e.g. a SATA and SCSI disk attached, the XML > > generated > > by dumpxml used to produce "sda" for both of those disks. This is > > an > > invalid domain XML as libvirt does not allow duplicate device > > names. To > > address this, keep the running total of disks that will use "sd" > > prefix > > for device name and pass it to the vboxGenerateMediumName which no > > longer tries to "compute" the value based only on current and max > > port and slot values. After this the vboxGetMaxPortSlotValues is > > not > > needed and was deleted. > > --- > > src/vbox/vbox_common.c | 414 +-- > > -- > > 1 file changed, 177 insertions(+), 237 deletions(-) > > > > I think this needs a bit more splitting. > > 1. As noted in patch 10, managing StorageBus_SAS should already be > separated so that it doesn't show as a new range/comparison check > here > > 2. The rename of vboxDumpIDEHDDs to vboxDumpDisks and change from > void > to int should be its own patch. While it seems superfluous, it makes > review that much easier. NB: I have a couple more thoughts within > the > function about > > 3. I think the changes to vboxSnapshotGetReadWriteDisks and > vboxSnapshotGetReadOnlyDisks could be in a separate patch and is > where > the vboxGetMaxPortSlotValues would get deleted. Although I'm not 100% > sure w/r/t the relationship. Perhaps once vboxDumpDisks is cleaned up > a > bit before making the change described in the commit message it'd be > clearer. Just a lot going on. > > Hi John, I've just send V3 [1] when I separated most of the changes into individual patches as you requested. However, I could not separate vboxSnapshotGetReadWrite and vboxSnapshotGetReadOnly disks completely as the changes made to vboxGenerateMedium name must be combined with the removal of vboxGetMaxPortSlotValues so instead, I've isolated the code movement changes where I moved the code to read VBOX's storage controller, slot and port to the beginning of the loop body - either way, I think it's much cleaner and easier to follow the changes now. [1] https://www.redhat.com/archives/libvir-list/2017-November/msg00252. html Dawid > > > diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c > > index 715eb670e..9dc36a1b2 100644 > > --- a/src/vbox/vbox_common.c > > +++ b/src/vbox/vbox_common.c > > @@ -290,61 +290,6 @@ static int openSessionForMachine(vboxDriverPtr > > data, const unsigned char *dom_uu > > return 0; > > } > > > > -/** > > - * function to get the values for max port per > > - * instance and max slots per port for the devices > > - * > > - * @returns true on Success, false on failure. > > - * @param vboxInput IVirtualBox pointer > > - * @param maxPortPerInst Output array of max port per > > instance > > - * @param maxSlotPerPort Output array of max slot per port > > - * > > - */ > > - > > -static bool vboxGetMaxPortSlotValues(IVirtualBox *vbox, > > - PRUint32 *maxPortPerInst, > > - PRUint32 *maxSlotPerPort) > > -{ > > -ISystemProperties *sysProps = NULL; > > - > > -if (!vbox) > > -return false; > > - > > -gVBoxAPI.UIVirtualBox.GetSystemProperties(vbox, ); > > - > > -if (!sysProps) > > -return false; > > - > > -gVBoxAPI.UISystemProperties.GetMaxPortCountForStorageBus(sysPr > > ops, > > - Stora > > geBus_IDE, > > - > > ortPerInst[StorageBus_IDE]); > > -gVBoxAPI.UISystemProperties.GetMaxPortCountForStorageBus(sysPr > > ops, > > - Stora > > geBus_SATA, > > - > > ortPerInst[StorageBus_SATA]); > > -gVBoxAPI.UISystemProperties.GetMaxPortCountForStorageBus(sysPr > > ops, > > - Stora > > geBus_SCSI, > > - > > ortPerInst[StorageBus_SCSI]); > > -gVBoxAPI.UISystemProperties.GetMaxPortCountForStorageBus(sysPr > > ops, > &g
[libvirt] [PATCH v3 02/13] vbox: Process element in domain XML
With this patch, the vbox driver will no longer attach all supported storage controllers by default even if no disk devices are associated with them. Instead, it will attach only those that are implicitly added by virDomainDefAddImplicitController based on element or if explicitly specified via the element. --- src/vbox/vbox_common.c | 199 ++--- src/vbox/vbox_common.h | 7 ++ 2 files changed, 161 insertions(+), 45 deletions(-) diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c index d93b0855f..49df52c12 100644 --- a/src/vbox/vbox_common.c +++ b/src/vbox/vbox_common.c @@ -406,6 +406,154 @@ static char *vboxGenerateMediumName(PRUint32 storageBus, return name; } + +static int +vboxSetStorageController(virDomainControllerDefPtr controller, + vboxDriverPtr data, + IMachine *machine) +{ +PRUnichar *controllerName = NULL; +PRInt32 vboxModel = StorageControllerType_Null; +PRInt32 vboxBusType = StorageBus_Null; +IStorageController *vboxController = NULL; +nsresult rc = 0; +char *debugName = NULL; +int ret = -1; + +/* libvirt controller type => vbox bus type */ +switch ((virDomainControllerType) controller->type) { +case VIR_DOMAIN_CONTROLLER_TYPE_FDC: +VBOX_UTF8_TO_UTF16(VBOX_CONTROLLER_FLOPPY_NAME, ); +vboxBusType = StorageBus_Floppy; + +break; +case VIR_DOMAIN_CONTROLLER_TYPE_IDE: +VBOX_UTF8_TO_UTF16(VBOX_CONTROLLER_IDE_NAME, ); +vboxBusType = StorageBus_IDE; + +break; +case VIR_DOMAIN_CONTROLLER_TYPE_SCSI: +VBOX_UTF8_TO_UTF16(VBOX_CONTROLLER_SCSI_NAME, ); +vboxBusType = StorageBus_SCSI; + +break; +case VIR_DOMAIN_CONTROLLER_TYPE_SATA: +VBOX_UTF8_TO_UTF16(VBOX_CONTROLLER_SATA_NAME, ); +vboxBusType = StorageBus_SATA; + +break; +case VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL: +case VIR_DOMAIN_CONTROLLER_TYPE_CCID: +case VIR_DOMAIN_CONTROLLER_TYPE_USB: +case VIR_DOMAIN_CONTROLLER_TYPE_PCI: +case VIR_DOMAIN_CONTROLLER_TYPE_LAST: +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("The vbox driver does not support %s controller type"), + virDomainControllerTypeToString(controller->type)); +return -1; +} + +/* libvirt scsi model => vbox scsi model */ +if (controller->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI) { +switch ((virDomainControllerModelSCSI) controller->model) { +case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC: +case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_AUTO: +vboxModel = StorageControllerType_LsiLogic; + +break; +case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_BUSLOGIC: +vboxModel = StorageControllerType_BusLogic; + +break; +case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VMPVSCSI: +case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_IBMVSCSI: +case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI: +case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSISAS1068: +case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSISAS1078: +case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LAST: +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("The vbox driver does not support %s SCSI " + "controller model"), + virDomainControllerModelSCSITypeToString(controller->model)); +goto cleanup; +} +/* libvirt ide model => vbox ide model */ +} else if (controller->type == VIR_DOMAIN_CONTROLLER_TYPE_IDE) { +switch ((virDomainControllerModelIDE) controller->model) { +case VIR_DOMAIN_CONTROLLER_MODEL_IDE_PIIX3: +vboxModel = StorageControllerType_PIIX3; + +break; +case VIR_DOMAIN_CONTROLLER_MODEL_IDE_PIIX4: +vboxModel = StorageControllerType_PIIX4; + +break; +case VIR_DOMAIN_CONTROLLER_MODEL_IDE_ICH6: +vboxModel = StorageControllerType_ICH6; + +break; +case VIR_DOMAIN_CONTROLLER_MODEL_IDE_LAST: +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("The vbox driver does not support %s IDE " + "controller model"), + virDomainControllerModelIDETypeToString(controller->model)); +goto cleanup; +} +} + +VBOX_UTF16_TO_UTF8(controllerName, ); +VIR_DEBUG("Adding VBOX storage controller (name: %s, busType: %d)", + debugName, vboxBusType); + +rc = gVBoxAPI.UIMachine.AddStorageController(machine, controllerName, + vboxBusType, ); + +if (NS_FAILED(rc)) { +virReportError(VIR_ERR_INTERNAL_ERROR, + _("Failed to add storage controller " + "(name: %s, busType: %d), rc=%08x"), +
[libvirt] [PATCH v3 13/13] docs: Update news.xml with vbox changes.
--- docs/news.xml | 74 +++ 1 file changed, 74 insertions(+) diff --git a/docs/news.xml b/docs/news.xml index ef855d895..454c63d8b 100644 --- a/docs/news.xml +++ b/docs/news.xml @@ -37,8 +37,82 @@ + + + vbox: Add support for configuring storage controllers + + + The VirtualBox driver now supports the controller + element in the domain XML for configuring storage controllers in VBOX + VMs. Additionally, libvirt's domain XML schema was updated to allow + optional model attribute for controller + type='ide' which is used by the VBOX driver to set the + IDE controller model to be one of 'piix4', 'piix4' (default), or + 'ich6'. Finally, with this change dumpxml generates + controller elements that correspond to current + VBOX VM storage controller configuration. + + + + + vbox: Add support for attaching empty removable disks + + + The VirutalBox driver now supports adding CD-ROM and floppy disk + devices that do not have the disk source specified. Previously such + devices were silently ignored. + + + + + vbox: Add support for attaching SAS storage controllers + + + In VirtualBox, SCSI and SAS are distinct controller types whereas + libvirt does not make such distinction. Therefore, the VBOX driver was + updated to allow attaching SAS controllers via controller + type='scsi' model='lsisas1068' element. If there are + both SCSI and SAS controllers present in the VBOX VM, the domain XML + can associate the disk device using the address + element with the controller attribute, and optionally, + set the port via unit attribute. + + + + + vbox: Do not ignore failures to attach disk devices when defining + + + The define now fails and reports an error if any of the + controller or disk devices specified in the + domain XML fail to attach to the VirtualBox VM. + + + + + vbox: Fix dumpxml to always output disk devices + + + The VirtualBox driver was ignoring any disk devices in + dumpxml output if there was a SAS storage controller + attached to the VM. + + + + + vbox: Fix dumpxml to always generate valid domain XML + + + When a VirtualBox VM has multiple disks attached, each to a different + storage controller that uses 'sd' prefix for block device names e.g. + one disk attached to SATA and one to SCSI controller, it no longer + generates XML where both would have 'sda' device name assigned. + Instead it properly assigns 'sda' and 'sdb' to those disks in the + order of appearance. + + -- 2.14.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v3 04/13] vbox: Rename vboxDumpIDEHDDs to vboxDumpDisks
Because it deals with other disk types as well not just IDE. Also this function now returns -1 on error --- src/vbox/vbox_common.c | 57 ++ 1 file changed, 25 insertions(+), 32 deletions(-) diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c index 4d596075c..2e0d7ee9a 100644 --- a/src/vbox/vbox_common.c +++ b/src/vbox/vbox_common.c @@ -3254,13 +3254,11 @@ vboxDumpStorageControllers(virDomainDefPtr def, IMachine *machine) } -static void -vboxDumpIDEHDDs(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine) +static int +vboxDumpDisks(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine) { -/* dump IDE hdds if present */ vboxArray mediumAttachments = VBOX_ARRAY_INITIALIZER; -bool error = false; -int diskCount = 0; +int ret = -1, diskCount = 0; size_t i; PRUint32 maxPortPerInst[StorageBus_Floppy + 1] = {}; PRUint32 maxSlotPerPort[StorageBus_Floppy + 1] = {}; @@ -3284,24 +3282,22 @@ vboxDumpIDEHDDs(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine) } /* Allocate mem, if fails return error */ -if (VIR_ALLOC_N(def->disks, def->ndisks) >= 0) { -for (i = 0; i < def->ndisks; i++) { -virDomainDiskDefPtr disk = virDomainDiskDefNew(NULL); -if (!disk) { -error = true; -break; -} -def->disks[i] = disk; -} -} else { -error = true; +if (VIR_ALLOC_N(def->disks, def->ndisks) < 0) +goto cleanup; + +for (i = 0; i < def->ndisks; i++) { +virDomainDiskDefPtr disk = virDomainDiskDefNew(NULL); +if (!disk) +goto cleanup; + +def->disks[i] = disk; } -if (!error) -error = !vboxGetMaxPortSlotValues(data->vboxObj, maxPortPerInst, maxSlotPerPort); +if (!vboxGetMaxPortSlotValues(data->vboxObj, maxPortPerInst, maxSlotPerPort)) +goto cleanup; /* get the attachment details here */ -for (i = 0; i < mediumAttachments.count && diskCount < def->ndisks && !error; i++) { +for (i = 0; i < mediumAttachments.count && diskCount < def->ndisks; i++) { IMediumAttachment *imediumattach = mediumAttachments.items[i]; IStorageController *storageController = NULL; PRUnichar *storageControllerName = NULL; @@ -3347,8 +3343,8 @@ vboxDumpIDEHDDs(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine) if (!virDomainDiskGetSource(def->disks[diskCount])) { VBOX_RELEASE(medium); VBOX_RELEASE(storageController); -error = true; -break; + +goto cleanup; } gVBoxAPI.UIStorageController.GetBus(storageController, ); @@ -3385,8 +3381,8 @@ vboxDumpIDEHDDs(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine) deviceInst, devicePort, deviceSlot); VBOX_RELEASE(medium); VBOX_RELEASE(storageController); -error = true; -break; + +goto cleanup; } gVBoxAPI.UIMedium.GetReadOnly(medium, ); @@ -3401,15 +3397,12 @@ vboxDumpIDEHDDs(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine) diskCount++; } +ret = 0; + + cleanup: gVBoxAPI.UArray.vboxArrayRelease(); -/* cleanup on error */ -if (error) { -for (i = 0; i < def->ndisks; i++) -VIR_FREE(def->disks[i]); -VIR_FREE(def->disks); -def->ndisks = 0; -} +return ret; } static int @@ -4103,8 +4096,8 @@ static char *vboxDomainGetXMLDesc(virDomainPtr dom, unsigned int flags) goto cleanup; if (vboxDumpStorageControllers(def, machine) < 0) goto cleanup; - -vboxDumpIDEHDDs(def, data, machine); +if (vboxDumpDisks(def, data, machine) < 0) +goto cleanup; vboxDumpSharedFolders(def, data, machine); vboxDumpNetwork(def, data, machine, networkAdapterCount); -- 2.14.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v3 08/13] vbox: Correctly generate drive name in dumpxml
If a VBOX VM has e.g. a SATA and SCSI disk attached, the XML generated by dumpxml used to produce "sda" for both of those disks. This is an invalid domain XML as libvirt does not allow duplicate device names. To address this, keep the running total of disks that will use "sd" prefix for device name and pass it to the vboxGenerateMediumName which no longer tries to "compute" the value based only on current and max port and slot values. After this the vboxGetMaxPortSlotValues is not needed and was deleted. --- src/vbox/vbox_common.c | 192 ++--- 1 file changed, 52 insertions(+), 140 deletions(-) diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c index 4d39beb1e..57b0fd515 100644 --- a/src/vbox/vbox_common.c +++ b/src/vbox/vbox_common.c @@ -290,61 +290,6 @@ static int openSessionForMachine(vboxDriverPtr data, const unsigned char *dom_uu return 0; } -/** - * function to get the values for max port per - * instance and max slots per port for the devices - * - * @returns true on Success, false on failure. - * @param vboxInput IVirtualBox pointer - * @param maxPortPerInst Output array of max port per instance - * @param maxSlotPerPort Output array of max slot per port - * - */ - -static bool vboxGetMaxPortSlotValues(IVirtualBox *vbox, - PRUint32 *maxPortPerInst, - PRUint32 *maxSlotPerPort) -{ -ISystemProperties *sysProps = NULL; - -if (!vbox) -return false; - -gVBoxAPI.UIVirtualBox.GetSystemProperties(vbox, ); - -if (!sysProps) -return false; - -gVBoxAPI.UISystemProperties.GetMaxPortCountForStorageBus(sysProps, - StorageBus_IDE, - [StorageBus_IDE]); -gVBoxAPI.UISystemProperties.GetMaxPortCountForStorageBus(sysProps, - StorageBus_SATA, - [StorageBus_SATA]); -gVBoxAPI.UISystemProperties.GetMaxPortCountForStorageBus(sysProps, - StorageBus_SCSI, - [StorageBus_SCSI]); -gVBoxAPI.UISystemProperties.GetMaxPortCountForStorageBus(sysProps, - StorageBus_Floppy, - [StorageBus_Floppy]); - -gVBoxAPI.UISystemProperties.GetMaxDevicesPerPortForStorageBus(sysProps, - StorageBus_IDE, - [StorageBus_IDE]); -gVBoxAPI.UISystemProperties.GetMaxDevicesPerPortForStorageBus(sysProps, - StorageBus_SATA, - [StorageBus_SATA]); -gVBoxAPI.UISystemProperties.GetMaxDevicesPerPortForStorageBus(sysProps, - StorageBus_SCSI, - [StorageBus_SCSI]); -gVBoxAPI.UISystemProperties.GetMaxDevicesPerPortForStorageBus(sysProps, - StorageBus_Floppy, - [StorageBus_Floppy]); - -VBOX_RELEASE(sysProps); - -return true; -} /** * function to generate the name for medium, @@ -352,57 +297,39 @@ static bool vboxGetMaxPortSlotValues(IVirtualBox *vbox, * * @returns null terminated string with device name or NULL * for failures - * @param connInput Connection Pointer * @param storageBus Input storage bus type - * @param deviceInst Input device instance number * @param devicePort Input port number * @param deviceSlot Input slot number - * @param aMaxPortPerInst Input array of max port per device instance - * @param aMaxSlotPerPort Input array of max slot per device port - * + * @param sdCount Running total of disk devices with "sd" prefix */ -static char *vboxGenerateMediumName(PRUint32 storageBus, -PRInt32 deviceInst, -PRInt32 devicePort, -PRInt32 deviceSlot, -PRUint32 *aMaxPortPerInst, -PRUint32 *aMaxSlotPerPort) +static char * +vboxGenerateMediumName(PRUint32 storageBus, + PRInt32 devicePort, + PRInt32 deviceSlot, + size_t sdCount) { const char *prefix = NULL;
[libvirt] [PATCH v3 05/13] vbox: Cleanup/prepare snasphot dumpxml functions
This patch prepares the vboxSnapshotGetReadOnlyDisks and vboxSnapshotGetReadWriteDisks functions for further changes so that the code movement does not obstruct the gist of those future changes. This is done primarily because we'll need to know the type of vbox storage controller as early as possible and make decisions based on that info. --- src/vbox/vbox_common.c | 185 - 1 file changed, 105 insertions(+), 80 deletions(-) diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c index 2e0d7ee9a..d26ce1bce 100644 --- a/src/vbox/vbox_common.c +++ b/src/vbox/vbox_common.c @@ -5653,8 +5653,9 @@ vboxDomainSnapshotGet(vboxDriverPtr data, return snapshot; } -static int vboxSnapshotGetReadWriteDisks(virDomainSnapshotDefPtr def, - virDomainSnapshotPtr snapshot) +static int +vboxSnapshotGetReadWriteDisks(virDomainSnapshotDefPtr def, + virDomainSnapshotPtr snapshot) { virDomainPtr dom = snapshot->domain; vboxDriverPtr data = dom->conn->privateData; @@ -5755,26 +5756,72 @@ static int vboxSnapshotGetReadWriteDisks(virDomainSnapshotDefPtr def, void *handle; size_t j = 0; size_t k = 0; + if (!imediumattach) continue; -rc = gVBoxAPI.UIMediumAttachment.GetMedium(imediumattach, ); + +rc = gVBoxAPI.UIMediumAttachment.GetController(imediumattach, + ); if (NS_FAILED(rc)) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("cannot get medium")); + _("Cannot get storage controller name")); goto cleanup; } -if (!disk) -continue; -rc = gVBoxAPI.UIMediumAttachment.GetController(imediumattach, ); + +rc = gVBoxAPI.UIMachine.GetStorageControllerByName(machine, + storageControllerName, + ); +VBOX_UTF16_FREE(storageControllerName); if (NS_FAILED(rc)) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("cannot get controller")); + _("Cannot get storage controller by name")); goto cleanup; } -if (!storageControllerName) { -VBOX_RELEASE(disk); + +rc = gVBoxAPI.UIStorageController.GetBus(storageController, ); +if (NS_FAILED(rc)) { +virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Cannot get storage controller bus")); +VBOX_RELEASE(storageController); +goto cleanup; +} + +rc = gVBoxAPI.UIMediumAttachment.GetType(imediumattach, ); +if (NS_FAILED(rc)) { +virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Cannot get medium attachment type")); +VBOX_RELEASE(storageController); +goto cleanup; +} +rc = gVBoxAPI.UIMediumAttachment.GetPort(imediumattach, ); +if (NS_FAILED(rc)) { +virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Cannot get medium attachment port")); +VBOX_RELEASE(storageController); +goto cleanup; +} +rc = gVBoxAPI.UIMediumAttachment.GetDevice(imediumattach, ); +if (NS_FAILED(rc)) { +virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Cannot get medium attachment slot")); +VBOX_RELEASE(storageController); +goto cleanup; +} + +rc = gVBoxAPI.UIMediumAttachment.GetMedium(imediumattach, ); +if (NS_FAILED(rc)) { +virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Cannot get medium")); +VBOX_RELEASE(storageController); +goto cleanup; +} + +/* skip empty removable disk */ +if (!disk) { +VBOX_RELEASE(storageController); continue; } + handle = gVBoxAPI.UArray.handleMediumGetChildren(disk); rc = gVBoxAPI.UArray.vboxArrayGet(, disk, handle); if (NS_FAILED(rc)) { @@ -5797,53 +5844,25 @@ static int vboxSnapshotGetReadWriteDisks(virDomainSnapshotDefPtr def, char *diskSnapIdStr = NULL; VBOX_UTF16_TO_UTF8(diskSnapId, ); if (STREQ(diskSnapIdStr, snapshotUuidStr)) { -rc = gVBoxAPI.UIMachine.GetStorageControllerByName(machine, - storageControllerName, - ); -VBOX_UTF16_FREE(storageControllerName); -if (!storageController) { -VBOX_RELEASE(child); -
[libvirt] [PATCH v3 11/13] vbox: Generate disk address element in dumpxml
This patch adds element to each device since device names alone won't adequately reflect the storage device layout in the VM. With this patch, the ouput produced by dumpxml will faithfully reproduce the storage layout of the VM if used with define. --- src/vbox/vbox_common.c | 51 ++ 1 file changed, 43 insertions(+), 8 deletions(-) diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c index 661e09a27..8da08240e 100644 --- a/src/vbox/vbox_common.c +++ b/src/vbox/vbox_common.c @@ -3336,25 +3336,60 @@ vboxDumpDisks(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine) goto cleanup; } -if (storageBus == StorageBus_IDE) { +disk->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE; +disk->info.addr.drive.bus = 0; +disk->info.addr.drive.unit = devicePort; + +switch ((enum StorageBus) storageBus) { +case StorageBus_IDE: disk->bus = VIR_DOMAIN_DISK_BUS_IDE; -} else if (storageBus == StorageBus_SATA) { -sdCount++; +disk->info.addr.drive.bus = devicePort; /* primary, secondary */ +disk->info.addr.drive.unit = deviceSlot; /* master, slave */ + +break; +case StorageBus_SATA: disk->bus = VIR_DOMAIN_DISK_BUS_SATA; -} else if (storageBus == StorageBus_SCSI) { sdCount++; + +break; +case StorageBus_SCSI: disk->bus = VIR_DOMAIN_DISK_BUS_SCSI; -} else if (storageBus == StorageBus_Floppy) { +sdCount++; + +break; +case StorageBus_Floppy: disk->bus = VIR_DOMAIN_DISK_BUS_FDC; + +break; +case StorageBus_SAS: +case StorageBus_Null: +virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Unsupported null storage bus")); +goto cleanup; } -if (deviceType == DeviceType_HardDisk) +switch ((enum DeviceType) deviceType) { +case DeviceType_HardDisk: disk->device = VIR_DOMAIN_DISK_DEVICE_DISK; -else if (deviceType == DeviceType_Floppy) + +break; +case DeviceType_Floppy: disk->device = VIR_DOMAIN_DISK_DEVICE_FLOPPY; -else if (deviceType == DeviceType_DVD) + +break; +case DeviceType_DVD: disk->device = VIR_DOMAIN_DISK_DEVICE_CDROM; +break; +case DeviceType_Network: +case DeviceType_USB: +case DeviceType_SharedFolder: +case DeviceType_Null: +virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unsupported vbox device type: %d"), deviceType); +goto cleanup; +} + if (readOnly == PR_TRUE) disk->src->readonly = true; -- 2.14.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v3 03/13] vbox: Add vboxDumpStorageControllers
--- src/vbox/vbox_common.c | 109 + 1 file changed, 109 insertions(+) diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c index 49df52c12..4d596075c 100644 --- a/src/vbox/vbox_common.c +++ b/src/vbox/vbox_common.c @@ -3147,6 +3147,113 @@ vboxHostDeviceGetXMLDesc(vboxDriverPtr data, virDomainDefPtr def, IMachine *mach goto release_filters; } + +static int +vboxDumpStorageControllers(virDomainDefPtr def, IMachine *machine) +{ +vboxArray storageControllers = VBOX_ARRAY_INITIALIZER; +IStorageController *controller = NULL; +PRUint32 storageBus = StorageBus_Null; +PRUint32 controllerType = StorageControllerType_Null; +virDomainControllerDefPtr cont = NULL; +size_t i = 0; +int model = -1, ret = -1; +virDomainControllerType type = VIR_DOMAIN_CONTROLLER_TYPE_LAST; + +gVBoxAPI.UArray.vboxArrayGet(, machine, + gVBoxAPI.UArray.handleMachineGetStorageControllers(machine)); + +for (i = 0; i < storageControllers.count; i++) { +controller = storageControllers.items[i]; +storageBus = StorageBus_Null; +controllerType = StorageControllerType_Null; +type = VIR_DOMAIN_CONTROLLER_TYPE_LAST; +model = -1; + +if (!controller) +continue; + +gVBoxAPI.UIStorageController.GetBus(controller, ); +gVBoxAPI.UIStorageController.GetControllerType(controller, + ); + +/* vbox controller model => libvirt controller model */ +switch ((enum StorageControllerType) controllerType) { +case StorageControllerType_PIIX3: +model = VIR_DOMAIN_CONTROLLER_MODEL_IDE_PIIX3; + +break; +case StorageControllerType_PIIX4: +model = VIR_DOMAIN_CONTROLLER_MODEL_IDE_PIIX4; + +break; +case StorageControllerType_ICH6: +model = VIR_DOMAIN_CONTROLLER_MODEL_IDE_ICH6; + +break; +case StorageControllerType_BusLogic: +model = VIR_DOMAIN_CONTROLLER_MODEL_SCSI_BUSLOGIC; + +break; +case StorageControllerType_LsiLogic: +model = VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC; + +break; +case StorageControllerType_LsiLogicSas: +case StorageControllerType_IntelAhci: +case StorageControllerType_I82078: +case StorageControllerType_Null: +model = -1; + +break; +} + +/* vbox controller bus => libvirt controller type */ +switch ((enum StorageBus) storageBus) { +case StorageBus_IDE: +type = VIR_DOMAIN_CONTROLLER_TYPE_IDE; + +break; +case StorageBus_SCSI: +case StorageBus_SAS: +type = VIR_DOMAIN_CONTROLLER_TYPE_SCSI; + +break; +case StorageBus_SATA: +type = VIR_DOMAIN_CONTROLLER_TYPE_SATA; + +break; +case StorageBus_Floppy: +type = VIR_DOMAIN_CONTROLLER_TYPE_FDC; + +break; +case StorageBus_Null: +virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Unsupported null storage bus")); + +goto cleanup; +} + +if (type != VIR_DOMAIN_CONTROLLER_TYPE_LAST) { +cont = virDomainDefAddController(def, type, -1, model); +if (!cont) { +virReportError(VIR_ERR_INTERNAL_ERROR, + _("Failed to add %s controller type definition"), + virDomainControllerTypeToString(type)); +goto cleanup; +} +} +} + +ret = 0; + + cleanup: +gVBoxAPI.UArray.vboxArrayRelease(); + +return ret; +} + + static void vboxDumpIDEHDDs(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine) { @@ -3994,6 +4101,8 @@ static char *vboxDomainGetXMLDesc(virDomainPtr dom, unsigned int flags) goto cleanup; if (vboxDumpDisplay(def, data, machine) < 0) goto cleanup; +if (vboxDumpStorageControllers(def, machine) < 0) +goto cleanup; vboxDumpIDEHDDs(def, data, machine); -- 2.14.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v3 06/13] vbox: Do not free disk definitions on cleanup
Both vboxSnapshotGetReadWriteDisks and vboxSnapshotGetReadWriteDisks do not need to free the def->disks on cleanup because it's being done by the caller via virDomainSnaphotDefFree --- src/vbox/vbox_common.c | 14 ++ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c index d26ce1bce..79030e36e 100644 --- a/src/vbox/vbox_common.c +++ b/src/vbox/vbox_common.c @@ -5883,13 +5883,8 @@ vboxSnapshotGetReadWriteDisks(virDomainSnapshotDefPtr def, ret = 0; cleanup: -if (ret < 0) { -for (i = 0; i < def->ndisks; i++) -VIR_FREE(def->disks[i].src); -VIR_FREE(def->disks); -def->ndisks = 0; -} VBOX_RELEASE(snap); + return ret; } @@ -6105,16 +6100,11 @@ vboxSnapshotGetReadOnlyDisks(virDomainSnapshotPtr snapshot, ret = 0; cleanup: -if (ret < 0) { -for (i = 0; i < def->dom->ndisks; i++) -virDomainDiskDefFree(def->dom->disks[i]); -VIR_FREE(def->dom->disks); -def->dom->ndisks = 0; -} VBOX_RELEASE(disk); VBOX_RELEASE(storageController); gVBoxAPI.UArray.vboxArrayRelease(); VBOX_RELEASE(snap); + return ret; } -- 2.14.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v3 09/13] vbox: Cleanup vboxDumpDisks implementation
Primer the code for further changes: * move variable declarations to the top of the function * group together free/release statements * error check and report VBOX API calls used --- src/vbox/vbox_common.c | 190 +++-- 1 file changed, 122 insertions(+), 68 deletions(-) diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c index 57b0fd515..248f315eb 100644 --- a/src/vbox/vbox_common.c +++ b/src/vbox/vbox_common.c @@ -3186,6 +3186,16 @@ vboxDumpDisks(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine) { vboxArray mediumAttachments = VBOX_ARRAY_INITIALIZER; int ret = -1, diskCount = 0; +IMediumAttachment *mediumAttachment = NULL; +IMedium *medium = NULL; +IStorageController *controller = NULL; +PRUnichar *controllerName = NULL, *mediumLocUtf16 = NULL; +PRUint32 deviceType, storageBus; +PRInt32 devicePort, deviceSlot; +PRBool readOnly; +nsresult rc; +virDomainDiskDefPtr disk = NULL; +char *mediumLocUtf8 = NULL; size_t sdCount = 0, i; def->ndisks = 0; @@ -3194,15 +3204,14 @@ vboxDumpDisks(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine) /* get the number of attachments */ for (i = 0; i < mediumAttachments.count; i++) { -IMediumAttachment *imediumattach = mediumAttachments.items[i]; -if (imediumattach) { -IMedium *medium = NULL; +mediumAttachment = mediumAttachments.items[i]; +if (!mediumAttachment) +continue; -gVBoxAPI.UIMediumAttachment.GetMedium(imediumattach, ); -if (medium) { -def->ndisks++; -VBOX_RELEASE(medium); -} +gVBoxAPI.UIMediumAttachment.GetMedium(mediumAttachment, ); +if (medium) { +def->ndisks++; +VBOX_RELEASE(medium); } } @@ -3211,7 +3220,7 @@ vboxDumpDisks(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine) goto cleanup; for (i = 0; i < def->ndisks; i++) { -virDomainDiskDefPtr disk = virDomainDiskDefNew(NULL); +disk = virDomainDiskDefNew(NULL); if (!disk) goto cleanup; @@ -3220,103 +3229,140 @@ vboxDumpDisks(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine) /* get the attachment details here */ for (i = 0; i < mediumAttachments.count && diskCount < def->ndisks; i++) { -IMediumAttachment *imediumattach = mediumAttachments.items[i]; -IStorageController *storageController = NULL; -PRUnichar *storageControllerName = NULL; -PRUint32 deviceType = DeviceType_Null; -PRUint32 storageBus = StorageBus_Null; -PRBool readOnly = PR_FALSE; -IMedium *medium = NULL; -PRUnichar *mediumLocUtf16 = NULL; -char *mediumLocUtf8 = NULL; -PRInt32 devicePort = 0; -PRInt32 deviceSlot = 0; - -if (!imediumattach) +mediumAttachment = mediumAttachments.items[i]; +controller = NULL; +controllerName = NULL; +deviceType = DeviceType_Null; +storageBus = StorageBus_Null; +readOnly = PR_FALSE; +medium = NULL; +mediumLocUtf16 = NULL; +mediumLocUtf8 = NULL; +devicePort = 0; +deviceSlot = 0; +disk = def->disks[diskCount]; + +if (!mediumAttachment) continue; -gVBoxAPI.UIMediumAttachment.GetMedium(imediumattach, ); +rc = gVBoxAPI.UIMediumAttachment.GetMedium(mediumAttachment, ); +if (NS_FAILED(rc)) { +virReportError(VIR_ERR_INTERNAL_ERROR, + _("Could not get IMedium, rc=%08x"), rc); +goto cleanup; +} + if (!medium) continue; -gVBoxAPI.UIMediumAttachment.GetController(imediumattach, ); -if (!storageControllerName) { -VBOX_RELEASE(medium); -continue; +rc = gVBoxAPI.UIMediumAttachment.GetController(mediumAttachment, + ); +if (NS_FAILED(rc)) { +virReportError(VIR_ERR_INTERNAL_ERROR, + _("Failed to get storage controller name, rc=%08x"), + rc); +goto cleanup; } -gVBoxAPI.UIMachine.GetStorageControllerByName(machine, - storageControllerName, - ); -VBOX_UTF16_FREE(storageControllerName); -if (!storageController) { -VBOX_RELEASE(medium); -continue; +rc = gVBoxAPI.UIMachine.GetStorageControllerByName(machine, + controllerName, + ); +if (NS_FAILED(rc)) { +virReportError(VIR_ERR_INTERNAL_ERROR, + _("Could not
[libvirt] [PATCH v3 10/13] vbox: Process empty removable disks in dumpxml
Previously any removable storage device without media attached was omitted from domain XML dump. They're still (rightfully) omitted in snapshot XMl dump but need to be accounted properly to for the device names to stay in 'sync' between domain and snapshot XML dumps. --- src/vbox/vbox_common.c | 82 ++ 1 file changed, 49 insertions(+), 33 deletions(-) diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c index 248f315eb..661e09a27 100644 --- a/src/vbox/vbox_common.c +++ b/src/vbox/vbox_common.c @@ -3185,7 +3185,7 @@ static int vboxDumpDisks(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine) { vboxArray mediumAttachments = VBOX_ARRAY_INITIALIZER; -int ret = -1, diskCount = 0; +int ret = -1; IMediumAttachment *mediumAttachment = NULL; IMedium *medium = NULL; IStorageController *controller = NULL; @@ -3208,11 +3208,15 @@ vboxDumpDisks(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine) if (!mediumAttachment) continue; -gVBoxAPI.UIMediumAttachment.GetMedium(mediumAttachment, ); -if (medium) { -def->ndisks++; -VBOX_RELEASE(medium); +rc = gVBoxAPI.UIMediumAttachment.GetMedium(mediumAttachment, ); +if (NS_FAILED(rc)) { +virReportError(VIR_ERR_INTERNAL_ERROR, + _("Could not get IMedium, rc=%08x"), rc); +goto cleanup; } + +def->ndisks++; +VBOX_RELEASE(medium); } /* Allocate mem, if fails return error */ @@ -3228,7 +3232,7 @@ vboxDumpDisks(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine) } /* get the attachment details here */ -for (i = 0; i < mediumAttachments.count && diskCount < def->ndisks; i++) { +for (i = 0; i < mediumAttachments.count; i++) { mediumAttachment = mediumAttachments.items[i]; controller = NULL; controllerName = NULL; @@ -3240,7 +3244,7 @@ vboxDumpDisks(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine) mediumLocUtf8 = NULL; devicePort = 0; deviceSlot = 0; -disk = def->disks[diskCount]; +disk = def->disks[i]; if (!mediumAttachment) continue; @@ -3252,9 +3256,6 @@ vboxDumpDisks(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine) goto cleanup; } -if (!medium) -continue; - rc = gVBoxAPI.UIMediumAttachment.GetController(mediumAttachment, ); if (NS_FAILED(rc)) { @@ -3274,22 +3275,6 @@ vboxDumpDisks(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine) goto cleanup; } -rc = gVBoxAPI.UIMedium.GetLocation(medium, ); -if (NS_FAILED(rc)) { -virReportError(VIR_ERR_INTERNAL_ERROR, - _("Could not get medium storage location, rc=%08x"), - rc); -goto cleanup; -} - -VBOX_UTF16_TO_UTF8(mediumLocUtf16, ); - -if (virDomainDiskSetSource(disk, mediumLocUtf8) < 0) { -virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("Could not set disk source")); -goto cleanup; -} - rc = gVBoxAPI.UIMediumAttachment.GetType(mediumAttachment, ); if (NS_FAILED(rc)) { virReportError(VIR_ERR_INTERNAL_ERROR, @@ -3315,11 +3300,30 @@ vboxDumpDisks(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine) rc); goto cleanup; } -rc = gVBoxAPI.UIMedium.GetReadOnly(medium, ); -if (NS_FAILED(rc)) { -virReportError(VIR_ERR_INTERNAL_ERROR, - _("Could not get read only state, rc=%08x"), rc); -goto cleanup; + +if (medium) { +rc = gVBoxAPI.UIMedium.GetLocation(medium, ); +if (NS_FAILED(rc)) { +virReportError(VIR_ERR_INTERNAL_ERROR, + _("Could not get medium storage location, rc=%08x"), + rc); +goto cleanup; +} + +VBOX_UTF16_TO_UTF8(mediumLocUtf16, ); + +if (virDomainDiskSetSource(disk, mediumLocUtf8) < 0) { +virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Could not set disk source")); +goto cleanup; +} + +rc = gVBoxAPI.UIMedium.GetReadOnly(medium, ); +if (NS_FAILED(rc)) { +virReportError(VIR_ERR_INTERNAL_ERROR, + _("Could not get read only state, rc=%08x"), rc); +goto cleanup; +} } disk->dst = vboxGenerateMediumName(storageBus, devicePort, deviceSlot, @@ -3356,8 +3360,6 @@ vboxDumpDisks(virDomainDefPtr def, vboxDriverPtr data,
[libvirt] [PATCH v3 12/13] vbox: Add SAS controller support
In VirtualBox SAS and SCSI are separate controller types whereas libvirt does not make such distinction. This patch adds support for attaching the VBOX SAS controllers by mapping the 'lsisas1068' controller model in libvirt XML to VBOX SAS controller type. If VBOX VM has disks attached to both SCSI and SAS controller libvirt domain XML will have two elements with index and model attributes set accordingly. In this case, each respective element must have element specified to assign it to respective SCSI controller. --- src/vbox/vbox_common.c | 86 -- src/vbox/vbox_common.h | 1 + 2 files changed, 70 insertions(+), 17 deletions(-) diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c index 8da08240e..a1d9b2e7d 100644 --- a/src/vbox/vbox_common.c +++ b/src/vbox/vbox_common.c @@ -312,20 +312,27 @@ vboxGenerateMediumName(PRUint32 storageBus, char *name = NULL; int total = 0; -if ((storageBus < StorageBus_IDE) || -(storageBus > StorageBus_Floppy)) -return NULL; - -if (storageBus == StorageBus_IDE) { +switch ((enum StorageBus) storageBus) { +case StorageBus_IDE: prefix = "hd"; total = devicePort * 2 + deviceSlot; -} else if ((storageBus == StorageBus_SATA) || - (storageBus == StorageBus_SCSI)) { + +break; +case StorageBus_SATA: +case StorageBus_SCSI: +case StorageBus_SAS: prefix = "sd"; total = sdCount; -} else if (storageBus == StorageBus_Floppy) { + +break; +case StorageBus_Floppy: total = deviceSlot; prefix = "fd"; + +break; +case StorageBus_Null: + +return NULL; } name = virIndexToDiskName(total, prefix); @@ -391,11 +398,17 @@ vboxSetStorageController(virDomainControllerDefPtr controller, case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_BUSLOGIC: vboxModel = StorageControllerType_BusLogic; +break; +case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSISAS1068: +/* in vbox, lsisas has a dedicated SAS bus type with no model */ +VBOX_UTF16_FREE(controllerName); +VBOX_UTF8_TO_UTF16(VBOX_CONTROLLER_SAS_NAME, ); +vboxBusType = StorageBus_SAS; + break; case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VMPVSCSI: case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_IBMVSCSI: case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI: -case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSISAS1068: case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSISAS1078: case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LAST: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, @@ -1034,7 +1047,7 @@ static int vboxAttachDrives(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine) { size_t i; -int type, ret = 0; +int type, ret = 0, model = -1; const char *src = NULL; nsresult rc = 0; virDomainDiskDefPtr disk = NULL; @@ -1113,6 +1126,13 @@ vboxAttachDrives(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine) case VIR_DOMAIN_DISK_BUS_SCSI: VBOX_UTF8_TO_UTF16(VBOX_CONTROLLER_SCSI_NAME, ); +model = virDomainDeviceFindControllerModel(def, >info, + VIR_DOMAIN_CONTROLLER_TYPE_SCSI); +if (model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSISAS1068) { +VBOX_UTF16_FREE(storageCtlName); +VBOX_UTF8_TO_UTF16(VBOX_CONTROLLER_SAS_NAME, ); +} + break; case VIR_DOMAIN_DISK_BUS_FDC: VBOX_UTF8_TO_UTF16(VBOX_CONTROLLER_FLOPPY_NAME, ); @@ -3127,6 +3147,9 @@ vboxDumpStorageControllers(virDomainDefPtr def, IMachine *machine) break; case StorageControllerType_LsiLogicSas: +model = VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSISAS1068; + +break; case StorageControllerType_IntelAhci: case StorageControllerType_I82078: case StorageControllerType_Null: @@ -3195,12 +3218,13 @@ vboxDumpDisks(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine) PRBool readOnly; nsresult rc; virDomainDiskDefPtr disk = NULL; +virDomainControllerDefPtr ctrl = NULL; char *mediumLocUtf8 = NULL; -size_t sdCount = 0, i; +size_t sdCount = 0, i, j; def->ndisks = 0; gVBoxAPI.UArray.vboxArrayGet(, machine, - gVBoxAPI.UArray.handleMachineGetMediumAttachments(machine)); + gVBoxAPI.UArray.handleMachineGetMediumAttachments(machine)); /* get the number of attachments */ for (i = 0; i < mediumAttachments.count; i++) { @@ -3353,15 +3377,38 @@ vboxDumpDisks(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine) break; case StorageBus_SCSI: +case StorageBus_SAS: disk->bus = VIR_DOMAIN_DISK_BUS_SCSI; sdCount++; +/* In vbox, if
[libvirt] [PATCH v3 07/13] vbox: Swap vboxSnapshotGetReadOnlyDisks arguments
So that the function signature matches vboxSnapshotGetReadWriteDisks --- src/vbox/vbox_common.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c index 79030e36e..4d39beb1e 100644 --- a/src/vbox/vbox_common.c +++ b/src/vbox/vbox_common.c @@ -5889,8 +5889,8 @@ vboxSnapshotGetReadWriteDisks(virDomainSnapshotDefPtr def, } static int -vboxSnapshotGetReadOnlyDisks(virDomainSnapshotPtr snapshot, - virDomainSnapshotDefPtr def) +vboxSnapshotGetReadOnlyDisks(virDomainSnapshotDefPtr def, + virDomainSnapshotPtr snapshot) { virDomainPtr dom = snapshot->domain; vboxDriverPtr data = dom->conn->privateData; @@ -6173,7 +6173,7 @@ static char *vboxDomainSnapshotGetXMLDesc(virDomainSnapshotPtr snapshot, if (vboxSnapshotGetReadWriteDisks(def, snapshot) < 0) VIR_DEBUG("Could not get read write disks for snapshot"); -if (vboxSnapshotGetReadOnlyDisks(snapshot, def) < 0) +if (vboxSnapshotGetReadOnlyDisks(def, snapshot) < 0) VIR_DEBUG("Could not get Readonly disks for snapshot"); } -- 2.14.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v3 00/13] vbox: Improve handling of storage devices
v2: https://www.redhat.com/archives/libvir-list/2017-October/msg01108.html Changes since v2: * Rebase on master * Do not segfault in 'Cleanup partially-defined VM on failure' when code jumps to cleanup and machine is NULL * Take out SAS controller handling code into a separate patch * Split up the snapshot function cleanup code into separate patches * Fixed code formatting as pointed out in review * Rename vboxDumpIDEHDDs -> vboxDumpDisks into a separate patch * Add docs/news.xml patch to describe improvements/fixes in the series Dawid Zamirski (13): vbox: Cleanup partially-defined VM on failure vbox: Process element in domain XML vbox: Add vboxDumpStorageControllers vbox: Rename vboxDumpIDEHDDs to vboxDumpDisks vbox: Cleanup/prepare snasphot dumpxml functions vbox: Do not free disk definitions on cleanup vbox: Swap vboxSnapshotGetReadOnlyDisks arguments vbox: Correctly generate drive name in dumpxml vbox: Cleanup vboxDumpDisks implementation vbox: Process empty removable disks in dumpxml vbox: Generate disk address element in dumpxml vbox: Add SAS controller support docs: Update news.xml with vbox changes. docs/news.xml | 74 src/vbox/vbox_common.c | 1105 +++- src/vbox/vbox_common.h |8 + 3 files changed, 792 insertions(+), 395 deletions(-) -- 2.14.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v2 10/15] vbox: Process element in domain XML
On Fri, 2017-11-03 at 09:51 -0400, John Ferlan wrote: > > On 10/24/2017 03:35 PM, Dawid Zamirski wrote: > > > > +case VIR_DOMAIN_CONTROLLER_TYPE_SCSI: > > +VBOX_UTF8_TO_UTF16(VBOX_CONTROLLER_SCSI_NAME, > > ); > > +vboxBusType = StorageBus_SCSI; > > + > > +break; > > +case VIR_DOMAIN_CONTROLLER_TYPE_SATA: > > +VBOX_UTF8_TO_UTF16(VBOX_CONTROLLER_SATA_NAME, > > ); > > +vboxBusType = StorageBus_SATA; > > > I think prior to this patch - there should be a patch that "manages" > all > those range check differences, storageBus comparison checks, etc. for > VIR_DOMAIN_CONTROLLER_TYPE_SATA that end up in future patches. > > John Up until this patch, the series modifies the definexml functionality in which case input is libvirt XML that is translated to vbox values. The supported libvirt types are 'validated' by the typed switch...case statement so it's not possible to run into a vbox value that the driver does not recognize. The patches that follow are for dumpxml and those do get updated to handle StorageBus_SAS (the new one introduced in this series) in patch #12 (see vboxGenerateMediumName change) and in patch #15 where vboxDumpDisks is changed to use typed switch statement on storageBus. Dawid > > > + > > +break; > > +case VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL: > > +case VIR_DOMAIN_CONTROLLER_TYPE_CCID: > > +case VIR_DOMAIN_CONTROLLER_TYPE_USB: > > +case VIR_DOMAIN_CONTROLLER_TYPE_PCI: > > +case VIR_DOMAIN_CONTROLLER_TYPE_LAST: > > +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, > > + _("The vbox driver does not support %s > > controller type"), > > + virDomainControllerTypeToString(controller- > > >type)); > > +return -1; > > +} > > + > > +/* libvirt scsi model => vbox scsi model */ > > +if (controller->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI) { > > +switch ((virDomainControllerModelSCSI) controller->model) > > { > > +case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC: > > +case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_AUTO: > > +vboxModel = StorageControllerType_LsiLogic; > > + > > +break; > > +case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_BUSLOGIC: > > +vboxModel = StorageControllerType_BusLogic; > > + > > +break; > > +case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSISAS1068: > > +/* in vbox, lsisas has a dedicated SAS bus type with > > no model */ > > +VBOX_UTF16_FREE(controllerName); > > +VBOX_UTF8_TO_UTF16(VBOX_CONTROLLER_SAS_NAME, > > ); > > +vboxBusType = StorageBus_SAS; > > + > > +break; > > +case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VMPVSCSI: > > +case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_IBMVSCSI: > > +case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI: > > +case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSISAS1078: > > +case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LAST: > > +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, > > + _("The vbox driver does not support %s > > SCSI " > > + "controller model"), > > + virDomainControllerModelSCSITypeToStrin > > g(controller->model)); > > +goto cleanup; > > +} > > +/* libvirt ide model => vbox ide model */ > > +} else if (controller->type == VIR_DOMAIN_CONTROLLER_TYPE_IDE) > > { > > +switch ((virDomainControllerModelIDE) controller->model) { > > +case VIR_DOMAIN_CONTROLLER_MODEL_IDE_PIIX3: > > +vboxModel = StorageControllerType_PIIX3; > > + > > +break; > > +case VIR_DOMAIN_CONTROLLER_MODEL_IDE_PIIX4: > > +vboxModel = StorageControllerType_PIIX4; > > + > > +break; > > +case VIR_DOMAIN_CONTROLLER_MODEL_IDE_ICH6: > > +vboxModel = StorageControllerType_ICH6; > > + > > +break; > > +case VIR_DOMAIN_CONTROLLER_MODEL_IDE_LAST: > > +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, > > + _("The vbox driver does not support %s > > IDE " > > + "controller model"), > > + virDomainControllerModelIDETypeToStri > > ng(controller->m
Re: [libvirt] [PATCH v2 05/15] vbox: Cleanup vboxAttachDrives implementation
On Fri, 2017-11-03 at 09:43 -0400, John Ferlan wrote: > > On 10/24/2017 03:35 PM, Dawid Zamirski wrote: > > This commit primes vboxAttachDrives for further changes so when > > they > > are made, the diff is less noisy: > > > > * move variable declarations to the top of the function > > * add disk variable to replace all the def->disks[i] instances > > * add cleanup at the end of the loop body, so it's all in one place > > rather than scattered through the loop body. It's purposefully > > called 'cleanup' rather than 'skip' or 'continue' because future > > commit will treat errors as hard-failures. > > --- > > src/vbox/vbox_common.c | 95 > > -- > > 1 file changed, 46 insertions(+), 49 deletions(-) > > > > diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c > > index fa8471e68..b949c4db7 100644 > > --- a/src/vbox/vbox_common.c > > +++ b/src/vbox/vbox_common.c > > @@ -959,8 +959,17 @@ static void > > vboxAttachDrives(virDomainDefPtr def, vboxDriverPtr data, IMachine > > *machine) > > { > > size_t i; > > +int type, format; > > +const char *src = NULL; > > nsresult rc = 0; > > +virDomainDiskDefPtr disk = NULL; > > PRUnichar *storageCtlName = NULL; > > +IMedium *medium = NULL; > > +PRUnichar *mediumFileUtf16 = NULL, *mediumEmpty = NULL; > > +PRUint32 devicePort, deviceSlot, deviceType, accessMode; > > +vboxIID mediumUUID; > > + > > +VBOX_IID_INITIALIZE(); > > The cleanup: label would clean this up on the first pass through the > loop, so it needs to move outside the last }. > The VBOX_IID_INITIALIZE macro is a simple struct initializer that is equivalent of vboxIID mediumUUID = {NULL, true}; as a matter of fact, src/vbox/vbox_tmpl.c uses VBOX_IID_INITIALIZER macro which is exactly that, but that macro is not available to vbox_common.c This is likely another remanent of VBOX <= 3 support that needs to be cleaned up - I will do so in a separate patch as it will touch to many parts of the driver and when you take a closer look we don't really need vboxIID struct at all and can simply use PRUnichar directly for VBOX UUIDs. > I can do this for you; however, I have a question - something I > noticed > while reviewing patch 7. There's a call: > > rc = gVBoxAPI.UIMedium.GetId(medium, ); > > for which it wasn't clear whether the mediumUUID is overwritten. If > it > is, then although existing - it probably needs some cleanup and of > course would change the flow a bit to doing that initializer each > time > through the loop. Yes, it is overwritten but since the cleanup: label is at the end of the loop body it will set mediumUIID to {NULL, true} which is the same as calling VBOX_IID_INITIALIZE (see _vboxIIDUnalloc in src/vbox/vbox_tmpl.c) > > Moving it does have a ripple effect on subsequent patches, but it's > manageable. > > If moving it to the end is acceptable, then As per above, I'd rather leave this patch "as is" as the (future) driver cleanup patches for vboxIID will make this clearer. > > Reviewed-by: John Ferlan <jfer...@redhat.com> > > otherwise let me know and I'll let you repost as part of a v3 > > John > > > > > /* add a storage controller for the mediums to be attached */ > > /* this needs to change when multiple controller are supported > > for > > @@ -1003,57 +1012,50 @@ vboxAttachDrives(virDomainDefPtr def, > > vboxDriverPtr data, IMachine *machine) > > } > > > > for (i = 0; i < def->ndisks; i++) { > > -const char *src = virDomainDiskGetSource(def->disks[i]); > > -int type = virDomainDiskGetType(def->disks[i]); > > -int format = virDomainDiskGetFormat(def->disks[i]); > > +disk = def->disks[i]; > > +src = virDomainDiskGetSource(disk); > > +type = virDomainDiskGetType(disk); > > +format = virDomainDiskGetFormat(disk); > > +deviceType = DeviceType_Null; > > +accessMode = AccessMode_ReadOnly; > > +devicePort = disk->info.addr.drive.unit; > > +deviceSlot = disk->info.addr.drive.bus; > > > > VIR_DEBUG("disk(%zu) type: %d", i, type); > > -VIR_DEBUG("disk(%zu) device: %d", i, def->disks[i]- > > >device); > > -VIR_DEBUG("disk(%zu) bus:%d", i, def->disks[i]- > > >bus); > > +VIR_DEBUG("disk(%zu) device: %d", i, disk->device); > > +
Re: [libvirt] [PATCH v2 10/15] vbox: Process element in domain XML
On Fri, 2017-11-03 at 09:51 -0400, John Ferlan wrote: > > On 10/24/2017 03:35 PM, Dawid Zamirski wrote: > > This patch enables the VBOX driver to process the > > element > > in domain XML through which one can now customize the controller > > model. > > > > Since VirtualBox has two distinct SAS and SCSI they do not "map" > > directly to libvirt XML, he VBOX driver uses > model="lsisas1068" /> to create SAS controller in VBOX VM. > > Additionally > > once can set model on the IDE controller to be one of "piix3", > > "piix4" > > or "ich6". > > --- > > src/vbox/vbox_common.c | 214 > > ++--- > > src/vbox/vbox_common.h | 8 ++ > > 2 files changed, 176 insertions(+), 46 deletions(-) > > > > So beyond patch 3 which I know you have to repost anyway - starting > with > this patch and going forward, I figure you have to repost anyway as > long > as I get the question in patch 5 answered of course... > > This patch left me with a concern. Up to this point vboxAttachDrives > would add at least one controller for each type supported regardless > of > whether the VM used it. > > After this patch only those controllers defined in the VM XML will be > added. Which would seem to be fine, except for the case of hotplug > which > I wasn't clear whether vbox support or not. > > Let's say the VM is defined with and IDE controller, if someone tried > to > add a SCSI disk after startup, then there'd be no SCSI controller > already present. > I've just checked this with VirutalBox GUI and the only thing that can be changed on live VM is removable media (CD/DVD). All options to add disk devices to controller are disabled when VM is running. Neither quick web search returned anything useful regarding hot-add disk support on VBOX. Having said that, the original behavior was, IIRC, the reason why I actually started working on this series. According to our tech support they have ran into a couple of cases where the OS would BSOD (some legacy Windows OS e.g. 2000 or XP) when there was a controller (without a disk) attached to VM that the OS did not handle well. It sounded very strange to me but I've been told it was not a one-off case though I personally haven't reproduced it. Unfortunately, I won't be able to provide more details as we no longer use VBox internally (migrated to KVM) so those potential test cases are no longer around. > > > diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c > > index 2bd891efb..9d45e4a76 100644 > > --- a/src/vbox/vbox_common.c > > +++ b/src/vbox/vbox_common.c > > @@ -406,6 +406,160 @@ static char *vboxGenerateMediumName(PRUint32 > > storageBus, > > return name; > > } > > > > + > > +static int > > +vboxSetStorageController(virDomainControllerDefPtr controller, > > + vboxDriverPtr data, > > + IMachine *machine) > > +{ > > +PRUnichar *controllerName = NULL; > > +PRInt32 vboxModel = StorageControllerType_Null; > > +PRInt32 vboxBusType = StorageBus_Null; > > +IStorageController *vboxController = NULL; > > +nsresult rc = 0; > > +char *debugName = NULL; > > +int ret = -1; > > + > > +/* libvirt controller type => vbox bus type */ > > +switch ((virDomainControllerType) controller->type) { > > +case VIR_DOMAIN_CONTROLLER_TYPE_FDC: > > +VBOX_UTF8_TO_UTF16(VBOX_CONTROLLER_FLOPPY_NAME, > > ); > > +vboxBusType = StorageBus_Floppy; > > + > > +break; > > +case VIR_DOMAIN_CONTROLLER_TYPE_IDE: > > +VBOX_UTF8_TO_UTF16(VBOX_CONTROLLER_IDE_NAME, > > ); > > +vboxBusType = StorageBus_IDE; > > + > > +break; > > +case VIR_DOMAIN_CONTROLLER_TYPE_SCSI: > > +VBOX_UTF8_TO_UTF16(VBOX_CONTROLLER_SCSI_NAME, > > ); > > +vboxBusType = StorageBus_SCSI; > > + > > +break; > > +case VIR_DOMAIN_CONTROLLER_TYPE_SATA: > > +VBOX_UTF8_TO_UTF16(VBOX_CONTROLLER_SATA_NAME, > > ); > > +vboxBusType = StorageBus_SATA; > > > I think prior to this patch - there should be a patch that "manages" > all > those range check differences, storageBus comparison checks, etc. for > VIR_DOMAIN_CONTROLLER_TYPE_SATA that end up in future patches. > > John > > > + > > +break; > > +case VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL: > > +case VIR_DOMAIN_CONTROLLER_TYPE_CCID: > > +case
Re: [libvirt] [PATCH v2 03/15] vbox: Cleanup partially-defined VM on failure
On Tue, 2017-10-24 at 15:35 -0400, Dawid Zamirski wrote: > Since the VBOX API requires to register an initial VM before > proceeding > to attach any remaining devices to it, any failure to attach such > devices should result in automatic cleanup of the initially > registered > VM so that the state of VBOX registry remains clean without any > leftover > "aborted" VMs in it. Failure to cleanup of such partial VMs results > in a > warning log so that actual define error stays on the top of the error > stack. > --- > src/vbox/vbox_common.c | 41 +++- > - > 1 file changed, 27 insertions(+), 14 deletions(-) > > diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c > index 92ee37164..812c940e6 100644 > --- a/src/vbox/vbox_common.c > +++ b/src/vbox/vbox_common.c > @@ -1853,6 +1853,8 @@ vboxDomainDefineXMLFlags(virConnectPtr conn, > const char *xml, unsigned int flags > char uuidstr[VIR_UUID_STRING_BUFLEN]; > virDomainPtr ret = NULL; > unsigned int parse_flags = VIR_DOMAIN_DEF_PARSE_INACTIVE; > +bool machineReady = false; > + > > virCheckFlags(VIR_DOMAIN_DEFINE_VALIDATE, NULL); > > @@ -1862,12 +1864,12 @@ vboxDomainDefineXMLFlags(virConnectPtr conn, > const char *xml, unsigned int flags > if (!data->vboxObj) > return ret; > > -VBOX_IID_INITIALIZE(); > if (!(def = virDomainDefParseString(xml, data->caps, data- > >xmlopt, > NULL, parse_flags))) { > -goto cleanup; > +return ret; > } > > +VBOX_IID_INITIALIZE(); > virUUIDFormat(def->uuid, uuidstr); > > rc = gVBoxAPI.UIVirtualBox.CreateMachine(data, def, , > uuidstr); > @@ -1959,30 +1961,41 @@ vboxDomainDefineXMLFlags(virConnectPtr conn, > const char *xml, unsigned int flags > vboxAttachUSB(def, data, machine); > vboxAttachSharedFolder(def, data, machine); > > -/* Save the machine settings made till now and close the > - * session. also free up the mchiid variable used. > +machineReady = true; > + > + cleanup: > +/* Save the machine settings made till now, even when jumped > here on error, > + * as otherwise unregister won't cleanup properly. For example, > it won't > + * close media that were partially attached. The VBOX SDK docs > say that > + * unregister implicitly calls saveSettings but evidently it's > not so... > */ > rc = gVBoxAPI.UIMachine.SaveSettings(machine); There's one more code path in this function that causes a segfault here due to machine == NULL (e.g. when CreateMachine fails). I already have patched this but I'll hold off with sending V3 until this series is reviewed and feedback is available. > -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v2 3/3] vbox: Read runtime RDP port and handle autoport
On Wed, 2017-10-25 at 17:35 -0400, John Ferlan wrote: > > On 10/24/2017 05:09 PM, Dawid Zamirski wrote: > > VirutalBox has a IVRDEServerInfo structure available that > > gives the effective runtime port that the VM is using when it's > > running. This is useful when the "TCP/Ports" VBox property was set > > to > > port range (e.g. via autoport = "yes" or via VBoxManage) in which > > case it would be impossible to get the "active" port otherwise. > > --- > > src/vbox/vbox_common.c| 3 +- > > src/vbox/vbox_tmpl.c | 134 > > +++--- > > src/vbox/vbox_uniformed_api.h | 2 +- > > 3 files changed, 104 insertions(+), 35 deletions(-) > > > > diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c > > index 92ee37164..d542f2b76 100644 > > --- a/src/vbox/vbox_common.c > > +++ b/src/vbox/vbox_common.c > > @@ -3326,7 +3326,8 @@ vboxDumpDisplay(virDomainDefPtr def, > > vboxDriverPtr data, IMachine *machine) > > if (VIR_ALLOC(graphics) < 0) > > goto cleanup; > > > > -gVBoxAPI.UIVRDEServer.GetPorts(data, VRDEServer, > > graphics); > > +gVBoxAPI.UIVRDEServer.GetPorts(data, VRDEServer, machine, > > graphics); > > +gVBoxAPI.UISession.Close(data->vboxSession); > > But @data is used shortly after this and I don't see in the calling > tree > a corresponding UISession.Open* of some type or am I missing it in > some > called function? > > > The rest looks good - just need to know about this. I can remove > before > pushing or make some other sort of simple adjustment. Yep this should be removed - it's a left over from my old internal patch [1], that I forgot to remove when preparing for upstream submission. It was originally preceded with OpenExisting (aka LockMachine) to get the IConsole - the new patch does it internally in the vboxGetActiveVRDEServerPort function. https://github.com/datto/libvirt/commit/a3cb830bfce10b1a614c18a6ac50783 45433d900#diff-747d3af65e7ac81a564b7cb4fcd01eb6R3516 Thank you, Dawid > > John > > (I'm at KVM Forum in Prague - so normal work schedule is a bit off) > > > > > > > -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v2 0/3] Update VRDE server port handling.
v1: https://www.redhat.com/archives/libvir-list/2017-October/msg00421.html Changes since v1: * separate out the patch that drops VBOX_SESSION_OPEN/CLOSE macros. * reverse logic to check for rdp.autoport instead of rdp.port to avoid handling port = -1 * do not set rdp.port = -1 if vboxGetActiveRdpPort returns -1 and add more verbose code comments to clarify the logic Dawid Zamirski (3): vbox: Remove old unflexible macros vbox: Make autoport set RDP port range. vbox: Read runtime RDP port and handle autoport src/vbox/vbox_common.c| 3 +- src/vbox/vbox_tmpl.c | 159 ++ src/vbox/vbox_uniformed_api.h | 2 +- 3 files changed, 118 insertions(+), 46 deletions(-) -- 2.14.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v2 1/3] vbox: Remove old unflexible macros
The VBOX_SESSION_OPEN/CLOSE macros are only called in _vboxDomainSnapshotRestore and they are unflexible because: * assume the caller will have variable named "data" * can only create Write lock type As per above, it's not that hard to simply use the VBOX API directly. --- src/vbox/vbox_tmpl.c | 10 ++ 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c index dffeabde0..ce2ee9037 100644 --- a/src/vbox/vbox_tmpl.c +++ b/src/vbox/vbox_tmpl.c @@ -144,12 +144,6 @@ if (strUtf16) {\ (unsigned)(iid)->m3[7]);\ }\ -#define VBOX_SESSION_OPEN(/* unused */ iid_value, /* in */ machine) \ -machine->vtbl->LockMachine(machine, data->vboxSession, LockType_Write) - -#define VBOX_SESSION_CLOSE() \ -data->vboxSession->vtbl->UnlockMachine(data->vboxSession) - #define VBOX_IID_INITIALIZER { NULL, true } static void @@ -323,7 +317,7 @@ _vboxDomainSnapshotRestore(virDomainPtr dom, goto cleanup; } -rc = VBOX_SESSION_OPEN(domiid.value, machine); +rc = machine->vtbl->LockMachine(machine, data->vboxSession, LockType_Write); #if VBOX_API_VERSION < 500 if (NS_SUCCEEDED(rc)) rc = data->vboxSession->vtbl->GetConsole(data->vboxSession, ); @@ -368,7 +362,7 @@ _vboxDomainSnapshotRestore(virDomainPtr dom, #if VBOX_API_VERSION < 500 VBOX_RELEASE(console); #endif /*VBOX_API_VERSION < 500*/ -VBOX_SESSION_CLOSE(); +data->vboxSession->vtbl->UnlockMachine(data->vboxSession); vboxIIDUnalloc(); return ret; } -- 2.14.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v2 2/3] vbox: Make autoport set RDP port range.
From: Dawid Zamirski <dzr...@gmail.com> Originally autoport in vbox driver was setting the port to default value (3389) which caused multiple VM instances use the same port. Since libvirt XML does not allow to set port ranges, this patch changes the "autoport" behavior to set VBox's "TCP/Ports" property to an arbitrary port range (3389-3689) to avoid that issue. --- src/vbox/vbox_tmpl.c | 15 --- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c index ce2ee9037..2b3f2e3eb 100644 --- a/src/vbox/vbox_tmpl.c +++ b/src/vbox/vbox_tmpl.c @@ -146,6 +146,9 @@ if (strUtf16) {\ #define VBOX_IID_INITIALIZER { NULL, true } +/* default RDP port range to use for auto-port setting */ +#define VBOX_RDP_AUTOPORT_RANGE "3389-3689" + static void _vboxIIDUnalloc(vboxDriverPtr data, vboxIID *iid) { @@ -1595,15 +1598,21 @@ _vrdeServerGetPorts(vboxDriverPtr data ATTRIBUTE_UNUSED, } static nsresult -_vrdeServerSetPorts(vboxDriverPtr data ATTRIBUTE_UNUSED, -IVRDEServer *VRDEServer, virDomainGraphicsDefPtr graphics) +_vrdeServerSetPorts(vboxDriverPtr data, IVRDEServer *VRDEServer, +virDomainGraphicsDefPtr graphics) { nsresult rc = 0; PRUnichar *VRDEPortsKey = NULL; PRUnichar *VRDEPortsValue = NULL; VBOX_UTF8_TO_UTF16("TCP/Ports", ); -VRDEPortsValue = PRUnicharFromInt(data->pFuncs, graphics->data.rdp.port); + +if (graphics->data.rdp.autoport) +VBOX_UTF8_TO_UTF16(VBOX_RDP_AUTOPORT_RANGE, ); +else +VRDEPortsValue = PRUnicharFromInt(data->pFuncs, + graphics->data.rdp.port); + rc = VRDEServer->vtbl->SetVRDEProperty(VRDEServer, VRDEPortsKey, VRDEPortsValue); VBOX_UTF16_FREE(VRDEPortsKey); -- 2.14.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v2 3/3] vbox: Read runtime RDP port and handle autoport
VirutalBox has a IVRDEServerInfo structure available that gives the effective runtime port that the VM is using when it's running. This is useful when the "TCP/Ports" VBox property was set to port range (e.g. via autoport = "yes" or via VBoxManage) in which case it would be impossible to get the "active" port otherwise. --- src/vbox/vbox_common.c| 3 +- src/vbox/vbox_tmpl.c | 134 +++--- src/vbox/vbox_uniformed_api.h | 2 +- 3 files changed, 104 insertions(+), 35 deletions(-) diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c index 92ee37164..d542f2b76 100644 --- a/src/vbox/vbox_common.c +++ b/src/vbox/vbox_common.c @@ -3326,7 +3326,8 @@ vboxDumpDisplay(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine) if (VIR_ALLOC(graphics) < 0) goto cleanup; -gVBoxAPI.UIVRDEServer.GetPorts(data, VRDEServer, graphics); +gVBoxAPI.UIVRDEServer.GetPorts(data, VRDEServer, machine, graphics); +gVBoxAPI.UISession.Close(data->vboxSession); graphics->type = VIR_DOMAIN_GRAPHICS_TYPE_RDP; diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c index 2b3f2e3eb..c7682f13c 100644 --- a/src/vbox/vbox_tmpl.c +++ b/src/vbox/vbox_tmpl.c @@ -221,29 +221,6 @@ _vboxIIDFromArrayItem(vboxDriverPtr data, vboxIID *iid, _vboxIIDFromArrayItem(data, iid, array, idx) #define DEBUGIID(msg, strUtf16) DEBUGPRUnichar(msg, strUtf16) -/** - * Converts Utf-16 string to int - */ -static int PRUnicharToInt(PCVBOXXPCOM pFuncs, PRUnichar *strUtf16) -{ -char *strUtf8 = NULL; -int ret = 0; - -if (!strUtf16) -return -1; - -pFuncs->pfnUtf16ToUtf8(strUtf16, ); -if (!strUtf8) -return -1; - -if (virStrToLong_i(strUtf8, NULL, 10, ) < 0) -ret = -1; - -pFuncs->pfnUtf8Free(strUtf8); - -return ret; -} - /** * Converts int to Utf-16 string */ @@ -280,6 +257,54 @@ static virDomainState _vboxConvertState(PRUint32 state) } } + +static int +vboxGetActiveVRDEServerPort(ISession *session, IMachine *machine) +{ +nsresult rc; +PRInt32 port = -1; +IVRDEServerInfo *vrdeInfo = NULL; +IConsole *console = NULL; + +rc = machine->vtbl->LockMachine(machine, session, LockType_Shared); +if (NS_FAILED(rc)) { +VIR_WARN("Could not obtain shared lock on VBox VM, rc=%08x", rc); +return -1; +} + +rc = session->vtbl->GetConsole(session, ); +if (NS_FAILED(rc)) { +VIR_WARN("Could not get VBox session console, rc=%08x", rc); +goto cleanup; +} + +/* it may be null if VM is not running */ +if (!console) +goto cleanup; + +rc = console->vtbl->GetVRDEServerInfo(console, ); + +if (NS_FAILED(rc) || !vrdeInfo) { +VIR_WARN("Could not get VBox VM VRDEServerInfo, rc=%08x", rc); +goto cleanup; +} + +rc = vrdeInfo->vtbl->GetPort(vrdeInfo, ); + +if (NS_FAILED(rc)) { +VIR_WARN("Could not read port from VRDEServerInfo, rc=%08x", rc); +goto cleanup; +} + + cleanup: +VBOX_RELEASE(console); +VBOX_RELEASE(vrdeInfo); +session->vtbl->UnlockMachine(session); + +return port; +} + + static int _vboxDomainSnapshotRestore(virDomainPtr dom, IMachine *machine, @@ -1576,24 +1601,67 @@ _vrdeServerSetEnabled(IVRDEServer *VRDEServer, PRBool enabled) } static nsresult -_vrdeServerGetPorts(vboxDriverPtr data ATTRIBUTE_UNUSED, -IVRDEServer *VRDEServer, virDomainGraphicsDefPtr graphics) +_vrdeServerGetPorts(vboxDriverPtr data, IVRDEServer *VRDEServer, +IMachine *machine, virDomainGraphicsDefPtr graphics) { nsresult rc; PRUnichar *VRDEPortsKey = NULL; PRUnichar *VRDEPortsValue = NULL; +PRInt32 port = -1; +ssize_t nmatches = 0; +char **matches = NULL; +char *portUtf8 = NULL; + +/* get active (effective) port - available only when VM is running and has + * the VBOX extensions installed (without extenstions RDP server + * functionality is disabled) + */ +port = vboxGetActiveVRDEServerPort(data->vboxSession, machine); +if (port > 0) +graphics->data.rdp.port = port; + +/* get the port (or port range) set in VM properties, this info will + * be used to determine whether to set autoport flag + */ VBOX_UTF8_TO_UTF16("TCP/Ports", ); -rc = VRDEServer->vtbl->GetVRDEProperty(VRDEServer, VRDEPortsKey, ); -VBOX_UTF16_FREE(VRDEPortsKey); -if (VRDEPortsValue) { -/* even if vbox supports mutilpe ports, single port for now here */ -graphics->data.rdp.port = PRUnicharToInt(data->pFuncs, VRDEPortsValue); -VBOX_UTF16_FREE(VRDEPortsValue); -} else { -graphics->data.rdp.autoport = true; +rc = VRDEServer->vtbl->GetVRDEProperty(VRDEServer, VRDEPortsKey, + ); + +if (NS_FAILED(rc)) { +virReportError(VIR_ERR_INTERNAL_ERROR, +
[libvirt] [PATCH v2 13/15] vbox: Cleanup vboxDumpDisks implementation
Primer the code for further changes: * move variable declarations to the top of the function * group together free/release statements * error check and report VBOX API calls used --- src/vbox/vbox_common.c | 188 +++-- 1 file changed, 120 insertions(+), 68 deletions(-) diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c index 9dc36a1b2..ee6421aae 100644 --- a/src/vbox/vbox_common.c +++ b/src/vbox/vbox_common.c @@ -3202,6 +3202,16 @@ static int vboxDumpDisks(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine) { vboxArray mediumAttachments = VBOX_ARRAY_INITIALIZER; +IMediumAttachment *mediumAttachment = NULL; +IMedium *medium = NULL; +IStorageController *controller = NULL; +PRUnichar *controllerName = NULL, *mediumLocUtf16 = NULL; +PRUint32 deviceType, storageBus; +PRInt32 devicePort, deviceSlot; +PRBool readOnly; +nsresult rc; +virDomainDiskDefPtr disk = NULL; +char *mediumLocUtf8 = NULL; size_t sdCount = 0, i; int diskCount = 0; int ret = -1; @@ -3212,15 +3222,14 @@ vboxDumpDisks(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine) /* get the number of attachments */ for (i = 0; i < mediumAttachments.count; i++) { -IMediumAttachment *imediumattach = mediumAttachments.items[i]; -if (imediumattach) { -IMedium *medium = NULL; +mediumAttachment = mediumAttachments.items[i]; +if (!mediumAttachment) +continue; -gVBoxAPI.UIMediumAttachment.GetMedium(imediumattach, ); -if (medium) { -def->ndisks++; -VBOX_RELEASE(medium); -} +gVBoxAPI.UIMediumAttachment.GetMedium(mediumAttachment, ); +if (medium) { +def->ndisks++; +VBOX_RELEASE(medium); } } @@ -3229,7 +3238,7 @@ vboxDumpDisks(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine) goto cleanup; for (i = 0; i < def->ndisks; i++) { -virDomainDiskDefPtr disk = virDomainDiskDefNew(NULL); +disk = virDomainDiskDefNew(NULL); if (!disk) goto cleanup; @@ -3238,104 +3247,141 @@ vboxDumpDisks(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine) /* get the attachment details here */ for (i = 0; i < mediumAttachments.count && diskCount < def->ndisks; i++) { -IMediumAttachment *imediumattach = mediumAttachments.items[i]; -IStorageController *storageController = NULL; -PRUnichar *storageControllerName = NULL; -PRUint32 deviceType = DeviceType_Null; -PRUint32 storageBus = StorageBus_Null; -PRBool readOnly = PR_FALSE; -IMedium *medium = NULL; -PRUnichar *mediumLocUtf16 = NULL; -char *mediumLocUtf8 = NULL; -PRInt32 devicePort = 0; -PRInt32 deviceSlot = 0; - -if (!imediumattach) +mediumAttachment = mediumAttachments.items[i]; +controller = NULL; +controllerName = NULL; +deviceType = DeviceType_Null; +storageBus = StorageBus_Null; +readOnly = PR_FALSE; +medium = NULL; +mediumLocUtf16 = NULL; +mediumLocUtf8 = NULL; +devicePort = 0; +deviceSlot = 0; +disk = def->disks[diskCount]; + +if (!mediumAttachment) continue; -gVBoxAPI.UIMediumAttachment.GetMedium(imediumattach, ); +rc = gVBoxAPI.UIMediumAttachment.GetMedium(mediumAttachment, ); +if (NS_FAILED(rc)) { +virReportError(VIR_ERR_INTERNAL_ERROR, + _("Could not get IMedium, rc=%08x"), rc); +goto cleanup; +} + if (!medium) continue; -gVBoxAPI.UIMediumAttachment.GetController(imediumattach, ); -if (!storageControllerName) { -VBOX_RELEASE(medium); -continue; +rc = gVBoxAPI.UIMediumAttachment.GetController(mediumAttachment, + ); +if (NS_FAILED(rc)) { +virReportError(VIR_ERR_INTERNAL_ERROR, + _("Failed to get storage controller name, rc=%08x"), + rc); +goto cleanup; } -gVBoxAPI.UIMachine.GetStorageControllerByName(machine, - storageControllerName, - ); -VBOX_UTF16_FREE(storageControllerName); -if (!storageController) { -VBOX_RELEASE(medium); -continue; +rc = gVBoxAPI.UIMachine.GetStorageControllerByName(machine, + controllerName, + ); +if (NS_FAILED(rc)) { +virReportError(VIR_ERR_INTERNAL_ERROR, + _("Could not get
[libvirt] [PATCH v2 11/15] vbox: Add vboxDumpStorageControllers
--- src/vbox/vbox_common.c | 119 + 1 file changed, 119 insertions(+) diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c index 9d45e4a76..715eb670e 100644 --- a/src/vbox/vbox_common.c +++ b/src/vbox/vbox_common.c @@ -3153,6 +3153,123 @@ vboxHostDeviceGetXMLDesc(vboxDriverPtr data, virDomainDefPtr def, IMachine *mach goto release_filters; } + +static int +vboxDumpStorageControllers(virDomainDefPtr def, IMachine *machine) +{ +vboxArray storageControllers = VBOX_ARRAY_INITIALIZER; +IStorageController *controller = NULL; +PRUint32 storageBus = StorageBus_Null; +PRUint32 controllerType = StorageControllerType_Null; +virDomainControllerDefPtr cont = NULL; +size_t i = 0; +int model = -1, ret = -1; +virDomainControllerType type = VIR_DOMAIN_CONTROLLER_TYPE_LAST; + +gVBoxAPI.UArray.vboxArrayGet(, machine, + gVBoxAPI.UArray.handleMachineGetStorageControllers(machine)); + +for (i = 0; i < storageControllers.count; i++) { +controller = storageControllers.items[i]; +storageBus = StorageBus_Null; +controllerType = StorageControllerType_Null; +type = VIR_DOMAIN_CONTROLLER_TYPE_LAST; +model = -1; + +if (!controller) +continue; + +gVBoxAPI.UIStorageController.GetBus(controller, ); +gVBoxAPI.UIStorageController.GetControllerType(controller, + ); + +/* vbox controller model => libvirt controller model */ +switch ((enum StorageControllerType) controllerType) { +case StorageControllerType_PIIX3: +model = VIR_DOMAIN_CONTROLLER_MODEL_IDE_PIIX3; + +break; +case StorageControllerType_PIIX4: +model = VIR_DOMAIN_CONTROLLER_MODEL_IDE_PIIX4; + +break; +case StorageControllerType_ICH6: +model = VIR_DOMAIN_CONTROLLER_MODEL_IDE_ICH6; + +break; +case StorageControllerType_BusLogic: +model = VIR_DOMAIN_CONTROLLER_MODEL_SCSI_BUSLOGIC; + +break; +case StorageControllerType_LsiLogic: +model = VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC; + +break; +case StorageControllerType_LsiLogicSas: +model = VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSISAS1068; + +break; +case StorageControllerType_IntelAhci: +case StorageControllerType_I82078: +case StorageControllerType_Null: +model = -1; + +break; +} + +/* vbox controller bus => libvirt controller type */ +switch ((enum StorageBus) storageBus) { +case StorageBus_IDE: +type = VIR_DOMAIN_CONTROLLER_TYPE_IDE; + +break; +case StorageBus_SCSI: +case StorageBus_SAS: +type = VIR_DOMAIN_CONTROLLER_TYPE_SCSI; + +break; +case StorageBus_SATA: +type = VIR_DOMAIN_CONTROLLER_TYPE_SATA; + +break; +case StorageBus_Floppy: +type = VIR_DOMAIN_CONTROLLER_TYPE_FDC; + +break; +case StorageBus_Null: +virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Unsupported null storage bus")); + +goto cleanup; +} + +if (type != VIR_DOMAIN_CONTROLLER_TYPE_LAST) { +cont = virDomainDefAddController(def, type, -1, model); +if (!cont) { +virReportError(VIR_ERR_INTERNAL_ERROR, + _("Failed to add %s controller type definition"), + virDomainControllerTypeToString(type)); +goto cleanup; +} +} +} + +ret = 0; + + cleanup: +gVBoxAPI.UArray.vboxArrayRelease(); + +if (ret < 0) { +for (i = 0; i < def->ncontrollers; i++) +virDomainControllerDefFree(def->controllers[i]); +VIR_FREE(def->controllers); +def->ncontrollers = 0; +} + +return ret; +} + + static void vboxDumpIDEHDDs(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine) { @@ -4000,6 +4117,8 @@ static char *vboxDomainGetXMLDesc(virDomainPtr dom, unsigned int flags) goto cleanup; if (vboxDumpDisplay(def, data, machine) < 0) goto cleanup; +if (vboxDumpStorageControllers(def, machine) < 0) +goto cleanup; vboxDumpIDEHDDs(def, data, machine); -- 2.14.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v2 14/15] vbox: Process empty removable disks in dumpxml
Previously any removable storage device without media attached was omitted from domain XML dump. They're still (rightfully) omitted in snapshot XMl dump but need to be accounted properly to for the device names to stay in 'sync' between domain and snapshot XML dumps. --- src/vbox/vbox_common.c | 128 - 1 file changed, 74 insertions(+), 54 deletions(-) diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c index ee6421aae..d1d8804c7 100644 --- a/src/vbox/vbox_common.c +++ b/src/vbox/vbox_common.c @@ -3213,7 +3213,6 @@ vboxDumpDisks(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine) virDomainDiskDefPtr disk = NULL; char *mediumLocUtf8 = NULL; size_t sdCount = 0, i; -int diskCount = 0; int ret = -1; def->ndisks = 0; @@ -3226,11 +3225,15 @@ vboxDumpDisks(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine) if (!mediumAttachment) continue; -gVBoxAPI.UIMediumAttachment.GetMedium(mediumAttachment, ); -if (medium) { -def->ndisks++; -VBOX_RELEASE(medium); +rc = gVBoxAPI.UIMediumAttachment.GetMedium(mediumAttachment, ); +if (NS_FAILED(rc)) { +virReportError(VIR_ERR_INTERNAL_ERROR, + _("Could not get IMedium, rc=%08x"), rc); +goto cleanup; } + +def->ndisks++; +VBOX_RELEASE(medium); } /* Allocate mem, if fails return error */ @@ -3246,7 +3249,7 @@ vboxDumpDisks(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine) } /* get the attachment details here */ -for (i = 0; i < mediumAttachments.count && diskCount < def->ndisks; i++) { +for (i = 0; i < mediumAttachments.count; i++) { mediumAttachment = mediumAttachments.items[i]; controller = NULL; controllerName = NULL; @@ -3258,7 +3261,7 @@ vboxDumpDisks(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine) mediumLocUtf8 = NULL; devicePort = 0; deviceSlot = 0; -disk = def->disks[diskCount]; +disk = def->disks[i]; if (!mediumAttachment) continue; @@ -3270,9 +3273,6 @@ vboxDumpDisks(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine) goto cleanup; } -if (!medium) -continue; - rc = gVBoxAPI.UIMediumAttachment.GetController(mediumAttachment, ); if (NS_FAILED(rc)) { @@ -3292,22 +3292,6 @@ vboxDumpDisks(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine) goto cleanup; } -rc = gVBoxAPI.UIMedium.GetLocation(medium, ); -if (NS_FAILED(rc)) { -virReportError(VIR_ERR_INTERNAL_ERROR, - _("Could not get medium storage location, rc=%08x"), - rc); -goto cleanup; -} - -VBOX_UTF16_TO_UTF8(mediumLocUtf16, ); - -if (virDomainDiskSetSource(disk, mediumLocUtf8) < 0) { -virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("Could not set disk source")); -goto cleanup; -} - rc = gVBoxAPI.UIMediumAttachment.GetType(mediumAttachment, ); if (NS_FAILED(rc)) { virReportError(VIR_ERR_INTERNAL_ERROR, @@ -,11 +3317,30 @@ vboxDumpDisks(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine) rc); goto cleanup; } -rc = gVBoxAPI.UIMedium.GetReadOnly(medium, ); -if (NS_FAILED(rc)) { -virReportError(VIR_ERR_INTERNAL_ERROR, - _("Could not get read only state, rc=%08x"), rc); -goto cleanup; + +if (medium) { +rc = gVBoxAPI.UIMedium.GetLocation(medium, ); +if (NS_FAILED(rc)) { +virReportError(VIR_ERR_INTERNAL_ERROR, + _("Could not get medium storage location, rc=%08x"), + rc); +goto cleanup; +} + +VBOX_UTF16_TO_UTF8(mediumLocUtf16, ); + +if (virDomainDiskSetSource(disk, mediumLocUtf8) < 0) { +virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Could not set disk source")); +goto cleanup; +} + +rc = gVBoxAPI.UIMedium.GetReadOnly(medium, ); +if (NS_FAILED(rc)) { +virReportError(VIR_ERR_INTERNAL_ERROR, + _("Could not get read only state, rc=%08x"), rc); +goto cleanup; +} } disk->dst = vboxGenerateMediumName(storageBus, devicePort, deviceSlot, @@ -3375,8 +3378,6 @@ vboxDumpDisks(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine) virDomainDiskSetType(disk, VIR_STORAGE_TYPE_FILE); -
[libvirt] [PATCH v2 12/15] vbox: Correctly generate drive name in dumpxml
If a VBOX VM has e.g. a SATA and SCSI disk attached, the XML generated by dumpxml used to produce "sda" for both of those disks. This is an invalid domain XML as libvirt does not allow duplicate device names. To address this, keep the running total of disks that will use "sd" prefix for device name and pass it to the vboxGenerateMediumName which no longer tries to "compute" the value based only on current and max port and slot values. After this the vboxGetMaxPortSlotValues is not needed and was deleted. --- src/vbox/vbox_common.c | 414 + 1 file changed, 177 insertions(+), 237 deletions(-) diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c index 715eb670e..9dc36a1b2 100644 --- a/src/vbox/vbox_common.c +++ b/src/vbox/vbox_common.c @@ -290,61 +290,6 @@ static int openSessionForMachine(vboxDriverPtr data, const unsigned char *dom_uu return 0; } -/** - * function to get the values for max port per - * instance and max slots per port for the devices - * - * @returns true on Success, false on failure. - * @param vboxInput IVirtualBox pointer - * @param maxPortPerInst Output array of max port per instance - * @param maxSlotPerPort Output array of max slot per port - * - */ - -static bool vboxGetMaxPortSlotValues(IVirtualBox *vbox, - PRUint32 *maxPortPerInst, - PRUint32 *maxSlotPerPort) -{ -ISystemProperties *sysProps = NULL; - -if (!vbox) -return false; - -gVBoxAPI.UIVirtualBox.GetSystemProperties(vbox, ); - -if (!sysProps) -return false; - -gVBoxAPI.UISystemProperties.GetMaxPortCountForStorageBus(sysProps, - StorageBus_IDE, - [StorageBus_IDE]); -gVBoxAPI.UISystemProperties.GetMaxPortCountForStorageBus(sysProps, - StorageBus_SATA, - [StorageBus_SATA]); -gVBoxAPI.UISystemProperties.GetMaxPortCountForStorageBus(sysProps, - StorageBus_SCSI, - [StorageBus_SCSI]); -gVBoxAPI.UISystemProperties.GetMaxPortCountForStorageBus(sysProps, - StorageBus_Floppy, - [StorageBus_Floppy]); - -gVBoxAPI.UISystemProperties.GetMaxDevicesPerPortForStorageBus(sysProps, - StorageBus_IDE, - [StorageBus_IDE]); -gVBoxAPI.UISystemProperties.GetMaxDevicesPerPortForStorageBus(sysProps, - StorageBus_SATA, - [StorageBus_SATA]); -gVBoxAPI.UISystemProperties.GetMaxDevicesPerPortForStorageBus(sysProps, - StorageBus_SCSI, - [StorageBus_SCSI]); -gVBoxAPI.UISystemProperties.GetMaxDevicesPerPortForStorageBus(sysProps, - StorageBus_Floppy, - [StorageBus_Floppy]); - -VBOX_RELEASE(sysProps); - -return true; -} /** * function to generate the name for medium, @@ -352,57 +297,40 @@ static bool vboxGetMaxPortSlotValues(IVirtualBox *vbox, * * @returns null terminated string with device name or NULL * for failures - * @param connInput Connection Pointer * @param storageBus Input storage bus type - * @param deviceInst Input device instance number * @param devicePort Input port number * @param deviceSlot Input slot number - * @param aMaxPortPerInst Input array of max port per device instance - * @param aMaxSlotPerPort Input array of max slot per device port - * + * @param sdCount Running total of disk devices with "sd" prefix */ -static char *vboxGenerateMediumName(PRUint32 storageBus, -PRInt32 deviceInst, -PRInt32 devicePort, -PRInt32 deviceSlot, -PRUint32 *aMaxPortPerInst, -PRUint32 *aMaxSlotPerPort) +static char * +vboxGenerateMediumName(PRUint32 storageBus, + PRInt32 devicePort, + PRInt32 deviceSlot, + size_t sdCount) { const char *prefix = NULL;
[libvirt] [PATCH v2 06/15] vbox: Errors in vboxAttachDrives are now critical
Previously, if one tried to define a VBOX VM and the API failed to perform the requested actions for some reason, it would just log the error and move on to process remaining disk definitions. This is not desired as it could result in incorrectly defined VM without the caller even knowing about it. So now all the code paths that call virReportError are now treated as hard failures as they should have been. --- src/vbox/vbox_common.c | 22 +++--- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c index b949c4db7..9f4bf18a3 100644 --- a/src/vbox/vbox_common.c +++ b/src/vbox/vbox_common.c @@ -955,17 +955,17 @@ vboxSetBootDeviceOrder(virDomainDefPtr def, vboxDriverPtr data, } } -static void +static int vboxAttachDrives(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine) { size_t i; -int type, format; +int type, format, ret = 0; const char *src = NULL; nsresult rc = 0; virDomainDiskDefPtr disk = NULL; PRUnichar *storageCtlName = NULL; IMedium *medium = NULL; -PRUnichar *mediumFileUtf16 = NULL, *mediumEmpty = NULL; +PRUnichar *mediumFileUtf16 = NULL; PRUint32 devicePort, deviceSlot, deviceType, accessMode; vboxIID mediumUUID; @@ -1049,6 +1049,7 @@ vboxAttachDrives(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine) deviceType = DeviceType_Floppy; accessMode = AccessMode_ReadWrite; } else { +ret = -1; goto cleanup; } @@ -1056,19 +1057,17 @@ vboxAttachDrives(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine) deviceType, accessMode, ); if (!medium) { -VBOX_UTF8_TO_UTF16("", ); - rc = gVBoxAPI.UIVirtualBox.OpenMedium(data->vboxObj, mediumFileUtf16, deviceType, accessMode, ); -VBOX_UTF16_FREE(mediumEmpty); } if (!medium) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to attach the following disk/dvd/floppy " "to the machine: %s, rc=%08x"), src, rc); +ret = -1; goto cleanup; } @@ -1078,6 +1077,7 @@ vboxAttachDrives(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine) _("Can't get the UUID of the file to be attached " "as harddisk/dvd/floppy: %s, rc=%08x"), src, rc); +ret = -1; goto cleanup; } @@ -1117,6 +1117,8 @@ vboxAttachDrives(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine) virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not attach the file as " "harddisk/dvd/floppy: %s, rc=%08x"), src, rc); +ret = -1; +goto cleanup; } else { DEBUGIID("Attached HDD/DVD/Floppy with UUID", ); } @@ -1125,8 +1127,13 @@ vboxAttachDrives(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine) vboxIIDUnalloc(); VBOX_UTF16_FREE(mediumFileUtf16); VBOX_UTF16_FREE(storageCtlName); + +if (ret < 0) +break; } } + +return ret; } static void @@ -1857,7 +1864,8 @@ vboxDomainDefineXMLFlags(virConnectPtr conn, const char *xml, unsigned int flags gVBoxAPI.UISession.GetMachine(data->vboxSession, ); vboxSetBootDeviceOrder(def, data, machine); -vboxAttachDrives(def, data, machine); +if (vboxAttachDrives(def, data, machine) < 0) +goto cleanup; vboxAttachSound(def, machine); if (vboxAttachNetwork(def, data, machine) < 0) goto cleanup; -- 2.14.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v2 00/15] vbox: Improve handling of storage devices
From: Dawid Zamirski <dzr...@gmail.com> v1: https://www.redhat.com/archives/libvir-list/2017-October/msg00381.html Changes since v1: * split out the original patches into smaller ones, with each bugfix or cleanup task is in its own isolated and compilable patch * make sure switch statements are type casted and all cases are handled * fixed implementation of partial VM cleanup code and isolated into separate patch (patch #3) * squashed doc and rng updates into a single patch (#9), updated doc wording as suggested * addressed other minor issues (add debug statements, code formatting, better comments, commit message spelling etc) Dawid Zamirski (15): vbox: Update ATTRIBUTE_UNUSED usage vbox: Close media when undefining domains vbox: Cleanup partially-defined VM on failure vbox: vboxAttachDrives now relies on address info vbox: Cleanup vboxAttachDrives implementation vbox: Errors in vboxAttachDrives are now critical vbox: Support empty removable drives. vbox: Add more IStorageController API mappings domain: Allow 'model' attribute for ide controller vbox: Process element in domain XML vbox: Add vboxDumpStorageControllers vbox: Correctly generate drive name in dumpxml vbox: Cleanup vboxDumpDisks implementation vbox: Process empty removable disks in dumpxml vbox: Generate disk address element in dumpxml docs/formatdomain.html.in |4 + docs/schemas/domaincommon.rng | 18 +- src/conf/domain_conf.c|9 + src/conf/domain_conf.h|9 + src/libvirt_private.syms |2 + src/vbox/vbox_common.c| 1422 + src/vbox/vbox_common.h| 21 + src/vbox/vbox_tmpl.c | 93 ++- src/vbox/vbox_uniformed_api.h |3 + 9 files changed, 983 insertions(+), 598 deletions(-) -- 2.14.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v2 10/15] vbox: Process element in domain XML
This patch enables the VBOX driver to process the element in domain XML through which one can now customize the controller model. Since VirtualBox has two distinct SAS and SCSI they do not "map" directly to libvirt XML, he VBOX driver uses to create SAS controller in VBOX VM. Additionally once can set model on the IDE controller to be one of "piix3", "piix4" or "ich6". --- src/vbox/vbox_common.c | 214 ++--- src/vbox/vbox_common.h | 8 ++ 2 files changed, 176 insertions(+), 46 deletions(-) diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c index 2bd891efb..9d45e4a76 100644 --- a/src/vbox/vbox_common.c +++ b/src/vbox/vbox_common.c @@ -406,6 +406,160 @@ static char *vboxGenerateMediumName(PRUint32 storageBus, return name; } + +static int +vboxSetStorageController(virDomainControllerDefPtr controller, + vboxDriverPtr data, + IMachine *machine) +{ +PRUnichar *controllerName = NULL; +PRInt32 vboxModel = StorageControllerType_Null; +PRInt32 vboxBusType = StorageBus_Null; +IStorageController *vboxController = NULL; +nsresult rc = 0; +char *debugName = NULL; +int ret = -1; + +/* libvirt controller type => vbox bus type */ +switch ((virDomainControllerType) controller->type) { +case VIR_DOMAIN_CONTROLLER_TYPE_FDC: +VBOX_UTF8_TO_UTF16(VBOX_CONTROLLER_FLOPPY_NAME, ); +vboxBusType = StorageBus_Floppy; + +break; +case VIR_DOMAIN_CONTROLLER_TYPE_IDE: +VBOX_UTF8_TO_UTF16(VBOX_CONTROLLER_IDE_NAME, ); +vboxBusType = StorageBus_IDE; + +break; +case VIR_DOMAIN_CONTROLLER_TYPE_SCSI: +VBOX_UTF8_TO_UTF16(VBOX_CONTROLLER_SCSI_NAME, ); +vboxBusType = StorageBus_SCSI; + +break; +case VIR_DOMAIN_CONTROLLER_TYPE_SATA: +VBOX_UTF8_TO_UTF16(VBOX_CONTROLLER_SATA_NAME, ); +vboxBusType = StorageBus_SATA; + +break; +case VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL: +case VIR_DOMAIN_CONTROLLER_TYPE_CCID: +case VIR_DOMAIN_CONTROLLER_TYPE_USB: +case VIR_DOMAIN_CONTROLLER_TYPE_PCI: +case VIR_DOMAIN_CONTROLLER_TYPE_LAST: +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("The vbox driver does not support %s controller type"), + virDomainControllerTypeToString(controller->type)); +return -1; +} + +/* libvirt scsi model => vbox scsi model */ +if (controller->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI) { +switch ((virDomainControllerModelSCSI) controller->model) { +case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC: +case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_AUTO: +vboxModel = StorageControllerType_LsiLogic; + +break; +case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_BUSLOGIC: +vboxModel = StorageControllerType_BusLogic; + +break; +case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSISAS1068: +/* in vbox, lsisas has a dedicated SAS bus type with no model */ +VBOX_UTF16_FREE(controllerName); +VBOX_UTF8_TO_UTF16(VBOX_CONTROLLER_SAS_NAME, ); +vboxBusType = StorageBus_SAS; + +break; +case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VMPVSCSI: +case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_IBMVSCSI: +case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI: +case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSISAS1078: +case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LAST: +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("The vbox driver does not support %s SCSI " + "controller model"), + virDomainControllerModelSCSITypeToString(controller->model)); +goto cleanup; +} +/* libvirt ide model => vbox ide model */ +} else if (controller->type == VIR_DOMAIN_CONTROLLER_TYPE_IDE) { +switch ((virDomainControllerModelIDE) controller->model) { +case VIR_DOMAIN_CONTROLLER_MODEL_IDE_PIIX3: +vboxModel = StorageControllerType_PIIX3; + +break; +case VIR_DOMAIN_CONTROLLER_MODEL_IDE_PIIX4: +vboxModel = StorageControllerType_PIIX4; + +break; +case VIR_DOMAIN_CONTROLLER_MODEL_IDE_ICH6: +vboxModel = StorageControllerType_ICH6; + +break; +case VIR_DOMAIN_CONTROLLER_MODEL_IDE_LAST: +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("The vbox driver does not support %s IDE " + "controller model"), + virDomainControllerModelIDETypeToString(controller->model)); +goto cleanup; +} +} + +VBOX_UTF16_TO_UTF8(controllerName, ); +VIR_DEBUG("Adding VBOX storage controller (name: %s, busType: %d)", + debugName, vboxBusType); + +rc =
[libvirt] [PATCH v2 15/15] vbox: Generate disk address element in dumpxml
This patch adds element to each device since device names alone won't adequately reflect the storage device layout in the VM. With this patch, the ouput produced by dumpxml will faithfully reproduce the storage layout of the VM if used with define. --- src/vbox/vbox_common.c | 79 +++--- 1 file changed, 68 insertions(+), 11 deletions(-) diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c index d1d8804c7..95d35631f 100644 --- a/src/vbox/vbox_common.c +++ b/src/vbox/vbox_common.c @@ -3211,8 +3211,9 @@ vboxDumpDisks(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine) PRBool readOnly; nsresult rc; virDomainDiskDefPtr disk = NULL; +virDomainControllerDefPtr ctrl = NULL; char *mediumLocUtf8 = NULL; -size_t sdCount = 0, i; +size_t sdCount = 0, i, j; int ret = -1; def->ndisks = 0; @@ -3353,26 +3354,83 @@ vboxDumpDisks(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine) goto cleanup; } -if (storageBus == StorageBus_IDE) { +disk->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE; +disk->info.addr.drive.bus = 0; +disk->info.addr.drive.unit = devicePort; + +switch ((enum StorageBus) storageBus) { +case StorageBus_IDE: disk->bus = VIR_DOMAIN_DISK_BUS_IDE; -} else if (storageBus == StorageBus_SATA) { -sdCount++; +disk->info.addr.drive.bus = devicePort; /* primary, secondary */ +disk->info.addr.drive.unit = deviceSlot; /* master, slave */ + +break; +case StorageBus_SATA: disk->bus = VIR_DOMAIN_DISK_BUS_SATA; -} else if (storageBus == StorageBus_SCSI || - storageBus == StorageBus_SAS) { sdCount++; + +break; +case StorageBus_SCSI: +case StorageBus_SAS: disk->bus = VIR_DOMAIN_DISK_BUS_SCSI; -} else if (storageBus == StorageBus_Floppy) { +sdCount++; + +/* In vbox, if there's a disk attached to SAS controller, there will + * be libvirt SCSI controller present with model "lsi1068", and we + * need to find its index + */ +for (j = 0; j < def->ncontrollers; j++) { +ctrl = def->controllers[j]; + +if (ctrl->type != VIR_DOMAIN_CONTROLLER_TYPE_SCSI) +continue; + +if (storageBus == StorageBus_SAS && +ctrl->model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSISAS1068) { +disk->info.addr.drive.controller = ctrl->idx; +break; +} + +if (storageBus == StorageBus_SCSI && +ctrl->model != VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSISAS1068) { +disk->info.addr.drive.controller = ctrl->idx; +break; +} +} + +break; +case StorageBus_Floppy: disk->bus = VIR_DOMAIN_DISK_BUS_FDC; + +break; +case StorageBus_Null: +virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Unsupported null storage bus")); +goto cleanup; } -if (deviceType == DeviceType_HardDisk) +switch ((enum DeviceType) deviceType) { +case DeviceType_HardDisk: disk->device = VIR_DOMAIN_DISK_DEVICE_DISK; -else if (deviceType == DeviceType_Floppy) + +break; +case DeviceType_Floppy: disk->device = VIR_DOMAIN_DISK_DEVICE_FLOPPY; -else if (deviceType == DeviceType_DVD) + +break; +case DeviceType_DVD: disk->device = VIR_DOMAIN_DISK_DEVICE_CDROM; +break; +case DeviceType_Network: +case DeviceType_USB: +case DeviceType_SharedFolder: +case DeviceType_Null: +virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unsupported vbox device type: %d"), deviceType); +goto cleanup; +} + if (readOnly == PR_TRUE) disk->src->readonly = true; @@ -4098,7 +4156,6 @@ static char *vboxDomainGetXMLDesc(virDomainPtr dom, unsigned int flags) goto cleanup; if (vboxDumpStorageControllers(def, machine) < 0) goto cleanup; - if (vboxDumpDisks(def, data, machine) < 0) goto cleanup; -- 2.14.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v2 01/15] vbox: Update ATTRIBUTE_UNUSED usage
Since the removal of VBOX <= 3x, the function arguments are actually used so they should not be marked with ATTRIBUTE_UNUSED anymore. --- src/vbox/vbox_tmpl.c | 49 +++-- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c index dffeabde0..4aa5e9a63 100644 --- a/src/vbox/vbox_tmpl.c +++ b/src/vbox/vbox_tmpl.c @@ -665,7 +665,9 @@ _virtualboxCreateHardDisk(IVirtualBox *vboxObj, PRUnichar *format, #if VBOX_API_VERSION < 500 return vboxObj->vtbl->CreateHardDisk(vboxObj, format, location, medium); #elif VBOX_API_VERSION >= 500 /*VBOX_API_VERSION >= 500*/ -return vboxObj->vtbl->CreateMedium(vboxObj, format, location, AccessMode_ReadWrite, DeviceType_HardDisk, medium); +return vboxObj->vtbl->CreateMedium(vboxObj, format, location, + AccessMode_ReadWrite, + DeviceType_HardDisk, medium); #endif /*VBOX_API_VERSION >= 500*/ } @@ -676,38 +678,33 @@ _virtualboxRegisterMachine(IVirtualBox *vboxObj, IMachine *machine) } static nsresult -_virtualboxFindHardDisk(IVirtualBox *vboxObj, PRUnichar *location, -PRUint32 deviceType ATTRIBUTE_UNUSED, +_virtualboxFindHardDisk(IVirtualBox *vboxObj, +PRUnichar *location, +PRUint32 deviceType, PRUint32 accessMode ATTRIBUTE_UNUSED, IMedium **medium) { #if VBOX_API_VERSION < 4002000 -return vboxObj->vtbl->FindMedium(vboxObj, location, - deviceType, medium); +return vboxObj->vtbl->FindMedium(vboxObj, location, deviceType, medium); #else /* VBOX_API_VERSION >= 4002000 */ -return vboxObj->vtbl->OpenMedium(vboxObj, location, - deviceType, accessMode, PR_FALSE, medium); +return vboxObj->vtbl->OpenMedium(vboxObj, location, deviceType, accessMode, + PR_FALSE, medium); #endif /* VBOX_API_VERSION >= 4002000 */ } static nsresult -_virtualboxOpenMedium(IVirtualBox *vboxObj ATTRIBUTE_UNUSED, - PRUnichar *location ATTRIBUTE_UNUSED, - PRUint32 deviceType ATTRIBUTE_UNUSED, - PRUint32 accessMode ATTRIBUTE_UNUSED, - IMedium **medium ATTRIBUTE_UNUSED) +_virtualboxOpenMedium(IVirtualBox *vboxObj, + PRUnichar *location, + PRUint32 deviceType, + PRUint32 accessMode, + IMedium **medium) { #if VBOX_API_VERSION == 400 -return vboxObj->vtbl->OpenMedium(vboxObj, - location, - deviceType, accessMode, +return vboxObj->vtbl->OpenMedium(vboxObj, location, deviceType, accessMode, medium); #elif VBOX_API_VERSION >= 4001000 -return vboxObj->vtbl->OpenMedium(vboxObj, - location, - deviceType, accessMode, - false, - medium); +return vboxObj->vtbl->OpenMedium(vboxObj, location, deviceType, accessMode, + false, medium); #endif } @@ -759,12 +756,12 @@ _machineGetStorageControllerByName(IMachine *machine, PRUnichar *name, } static nsresult -_machineAttachDevice(IMachine *machine ATTRIBUTE_UNUSED, - PRUnichar *name ATTRIBUTE_UNUSED, - PRInt32 controllerPort ATTRIBUTE_UNUSED, - PRInt32 device ATTRIBUTE_UNUSED, - PRUint32 type ATTRIBUTE_UNUSED, - IMedium * medium ATTRIBUTE_UNUSED) +_machineAttachDevice(IMachine *machine, + PRUnichar *name, + PRInt32 controllerPort, + PRInt32 device, + PRUint32 type, + IMedium * medium) { return machine->vtbl->AttachDevice(machine, name, controllerPort, device, type, medium); -- 2.14.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v2 09/15] domain: Allow 'model' attribute for ide controller
The optional values are 'piix3', 'piix4' or 'ich6'. Those will be needed to allow setting IDE controller model in VirtualBox driver. --- docs/formatdomain.html.in | 4 docs/schemas/domaincommon.rng | 18 -- src/conf/domain_conf.c| 9 + src/conf/domain_conf.h| 9 + src/libvirt_private.syms | 2 ++ 5 files changed, 40 insertions(+), 2 deletions(-) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 4609e2ec2..8dff685ad 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -3648,6 +3648,10 @@ Since 1.3.5, USB controllers accept a ports attribute to configure how many devices can be connected to the controller. +ide +Since 3.9.0 for the vbox driver, the +ide controller has an optional attribute +model, which is one of "piix3", "piix4" or "ich6". diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 710b3af7f..9cec1a063 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -1975,12 +1975,11 @@ - + fdc -ide sata ccid @@ -2041,6 +2040,21 @@ + + + + ide + + + + + piix3 + piix4 + ich6 + + + + diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 77c20c697..57f291624 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -377,6 +377,11 @@ VIR_ENUM_IMPL(virDomainControllerModelUSB, VIR_DOMAIN_CONTROLLER_MODEL_USB_LAST, "qemu-xhci", "none") +VIR_ENUM_IMPL(virDomainControllerModelIDE, VIR_DOMAIN_CONTROLLER_MODEL_IDE_LAST, + "piix3", + "piix4", + "ich6") + VIR_ENUM_IMPL(virDomainFS, VIR_DOMAIN_FS_TYPE_LAST, "mount", "block", @@ -9785,6 +9790,8 @@ virDomainControllerModelTypeFromString(const virDomainControllerDef *def, return virDomainControllerModelUSBTypeFromString(model); else if (def->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI) return virDomainControllerModelPCITypeFromString(model); +else if (def->type == VIR_DOMAIN_CONTROLLER_TYPE_IDE) +return virDomainControllerModelIDETypeFromString(model); return -1; } @@ -9800,6 +9807,8 @@ virDomainControllerModelTypeToString(virDomainControllerDefPtr def, return virDomainControllerModelUSBTypeToString(model); else if (def->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI) return virDomainControllerModelPCITypeToString(model); +else if (def->type == VIR_DOMAIN_CONTROLLER_TYPE_IDE) +return virDomainControllerModelIDETypeToString(model); return NULL; } diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 38de70b15..0def905b2 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -748,6 +748,14 @@ typedef enum { VIR_DOMAIN_CONTROLLER_MODEL_USB_LAST } virDomainControllerModelUSB; +typedef enum { +VIR_DOMAIN_CONTROLLER_MODEL_IDE_PIIX3, +VIR_DOMAIN_CONTROLLER_MODEL_IDE_PIIX4, +VIR_DOMAIN_CONTROLLER_MODEL_IDE_ICH6, + +VIR_DOMAIN_CONTROLLER_MODEL_IDE_LAST +} virDomainControllerModelIDE; + # define IS_USB2_CONTROLLER(ctrl) \ (((ctrl)->type == VIR_DOMAIN_CONTROLLER_TYPE_USB) && \ ((ctrl)->model == VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_EHCI1 || \ @@ -3219,6 +3227,7 @@ VIR_ENUM_DECL(virDomainControllerModelPCI) VIR_ENUM_DECL(virDomainControllerPCIModelName) VIR_ENUM_DECL(virDomainControllerModelSCSI) VIR_ENUM_DECL(virDomainControllerModelUSB) +VIR_ENUM_DECL(virDomainControllerModelIDE) VIR_ENUM_DECL(virDomainFS) VIR_ENUM_DECL(virDomainFSDriver) VIR_ENUM_DECL(virDomainFSAccessMode) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 448d962b2..2e67366b7 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -234,6 +234,8 @@ virDomainControllerFindUnusedIndex; virDomainControllerInsert; virDomainControllerInsertPreAlloced; virDomainControllerIsPSeriesPHB; +virDomainControllerModelIDETypeFromString; +virDomainControllerModelIDETypeToString; virDomainControllerModelPCITypeToString; virDomainControllerModelSCSITypeFromString; virDomainControllerModelSCSITypeToString; -- 2.14.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v2 07/15] vbox: Support empty removable drives.
Original code was checking for non empty disk source before proceeding to actually attach disk device to VM. This prevented from creating empty removable devices like DVD or floppy. Therefore, this patch re-organizes the loop work-flow to allow such configurations as well as makes the code follow better libvirt practices. Additionally, adjusted debug logs to be more helpful - removed old ones and added new which give more valuable info for troubleshooting. --- src/vbox/vbox_common.c | 206 +++-- 1 file changed, 130 insertions(+), 76 deletions(-) diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c index 9f4bf18a3..2bd891efb 100644 --- a/src/vbox/vbox_common.c +++ b/src/vbox/vbox_common.c @@ -959,11 +959,12 @@ static int vboxAttachDrives(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine) { size_t i; -int type, format, ret = 0; +int type, ret = 0; const char *src = NULL; nsresult rc = 0; virDomainDiskDefPtr disk = NULL; PRUnichar *storageCtlName = NULL; +char *controllerName = NULL; IMedium *medium = NULL; PRUnichar *mediumFileUtf16 = NULL; PRUint32 devicePort, deviceSlot, deviceType, accessMode; @@ -1015,47 +1016,104 @@ vboxAttachDrives(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine) disk = def->disks[i]; src = virDomainDiskGetSource(disk); type = virDomainDiskGetType(disk); -format = virDomainDiskGetFormat(disk); deviceType = DeviceType_Null; accessMode = AccessMode_ReadOnly; devicePort = disk->info.addr.drive.unit; deviceSlot = disk->info.addr.drive.bus; -VIR_DEBUG("disk(%zu) type: %d", i, type); -VIR_DEBUG("disk(%zu) device: %d", i, disk->device); -VIR_DEBUG("disk(%zu) bus:%d", i, disk->bus); -VIR_DEBUG("disk(%zu) src:%s", i, src); -VIR_DEBUG("disk(%zu) dst:%s", i, disk->dst); -VIR_DEBUG("disk(%zu) driverName: %s", i, - virDomainDiskGetDriver(disk)); -VIR_DEBUG("disk(%zu) driverType: %s", i, - virStorageFileFormatTypeToString(format)); -VIR_DEBUG("disk(%zu) cachemode: %d", i, disk->cachemode); -VIR_DEBUG("disk(%zu) readonly: %s", i, (disk->src->readonly - ? "True" : "False")); -VIR_DEBUG("disk(%zu) shared: %s", i, (disk->src->shared - ? "True" : "False")); - -if (type == VIR_STORAGE_TYPE_FILE && src) { -VBOX_UTF8_TO_UTF16(src, ); +if (type != VIR_STORAGE_TYPE_FILE) { +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Unsupported storage type %s, the only supported " + "type is %s"), + virStorageTypeToString(type), + virStorageTypeToString(VIR_STORAGE_TYPE_FILE)); +ret = -1; +goto cleanup; +} -if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK) { -deviceType = DeviceType_HardDisk; -accessMode = AccessMode_ReadWrite; -} else if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) { -deviceType = DeviceType_DVD; -accessMode = AccessMode_ReadOnly; -} else if (disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY) { -deviceType = DeviceType_Floppy; -accessMode = AccessMode_ReadWrite; -} else { +switch ((virDomainDiskDevice) disk->device) { +case VIR_DOMAIN_DISK_DEVICE_DISK: +if (!src) { +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Missing disk source file path")); ret = -1; goto cleanup; } -gVBoxAPI.UIVirtualBox.FindHardDisk(data->vboxObj, mediumFileUtf16, - deviceType, accessMode, ); +deviceType = DeviceType_HardDisk; +accessMode = AccessMode_ReadWrite; + +break; + +case VIR_DOMAIN_DISK_DEVICE_CDROM: +deviceType = DeviceType_DVD; +accessMode = AccessMode_ReadOnly; + +break; +case VIR_DOMAIN_DISK_DEVICE_FLOPPY: +deviceType = DeviceType_Floppy; +accessMode = AccessMode_ReadWrite; + +break; +case VIR_DOMAIN_DISK_DEVICE_LUN: +case VIR_DOMAIN_DISK_DEVICE_LAST: +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("The vbox driver does not support %s disk device"), + virDomainDiskDeviceTypeToString(disk->device)); +ret = -1; +goto cleanup; +} + +switch ((virDomainDiskBus) disk->bus) { +case VIR_DOMAIN_DISK_BUS_IDE: +
[libvirt] [PATCH v2 08/15] vbox: Add more IStorageController API mappings
This patch exposes additional methods of the native VBOX API to the libvirt 'unified' vbox API to deal with IStorageController. The exposed methods are: * IStorageController->GetStorageControllerType() * IStorageController->SetStorageControllerType() * IMachine->GetStorageControllers() --- src/vbox/vbox_common.h| 13 + src/vbox/vbox_tmpl.c | 20 src/vbox/vbox_uniformed_api.h | 3 +++ 3 files changed, 36 insertions(+) diff --git a/src/vbox/vbox_common.h b/src/vbox/vbox_common.h index c6da8929d..b08ad1e3e 100644 --- a/src/vbox/vbox_common.h +++ b/src/vbox/vbox_common.h @@ -235,6 +235,19 @@ enum StorageBus StorageBus_SAS = 5 }; +enum StorageControllerType +{ +StorageControllerType_Null = 0, +StorageControllerType_LsiLogic = 1, +StorageControllerType_BusLogic = 2, +StorageControllerType_IntelAhci = 3, +StorageControllerType_PIIX3 = 4, +StorageControllerType_PIIX4 = 5, +StorageControllerType_ICH6 = 6, +StorageControllerType_I82078 = 7, +StorageControllerType_LsiLogicSas = 8 +}; + enum AccessMode { AccessMode_ReadOnly = 1, diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c index 2679b60f7..a25f14c09 100644 --- a/src/vbox/vbox_tmpl.c +++ b/src/vbox/vbox_tmpl.c @@ -550,6 +550,11 @@ static void* _handleUSBGetDeviceFilters(IUSBCommon *USBCommon) return USBCommon->vtbl->GetDeviceFilters; } +static void* _handleMachineGetStorageControllers(IMachine *machine) +{ +return machine->vtbl->GetStorageControllers; +} + static void* _handleMachineGetMediumAttachments(IMachine *machine) { return machine->vtbl->GetMediumAttachments; @@ -1916,6 +1921,18 @@ _storageControllerGetBus(IStorageController *storageController, PRUint32 *bus) return storageController->vtbl->GetBus(storageController, bus); } +static nsresult +_storageControllerGetControllerType(IStorageController *storageController, PRUint32 *controllerType) +{ +return storageController->vtbl->GetControllerType(storageController, controllerType); +} + +static nsresult +_storageControllerSetControllerType(IStorageController *storageController, PRUint32 controllerType) +{ +return storageController->vtbl->SetControllerType(storageController, controllerType); +} + static nsresult _sharedFolderGetHostPath(ISharedFolder *sharedFolder, PRUnichar **hostPath) { @@ -2265,6 +2282,7 @@ static vboxUniformedArray _UArray = { .handleGetMachines = _handleGetMachines, .handleGetHardDisks = _handleGetHardDisks, .handleUSBGetDeviceFilters = _handleUSBGetDeviceFilters, +.handleMachineGetStorageControllers = _handleMachineGetStorageControllers, .handleMachineGetMediumAttachments = _handleMachineGetMediumAttachments, .handleMachineGetSharedFolders = _handleMachineGetSharedFolders, .handleSnapshotGetChildren = _handleSnapshotGetChildren, @@ -2496,6 +2514,8 @@ static vboxUniformedIMediumAttachment _UIMediumAttachment = { static vboxUniformedIStorageController _UIStorageController = { .GetBus = _storageControllerGetBus, +.GetControllerType = _storageControllerGetControllerType, +.SetControllerType = _storageControllerSetControllerType, }; static vboxUniformedISharedFolder _UISharedFolder = { diff --git a/src/vbox/vbox_uniformed_api.h b/src/vbox/vbox_uniformed_api.h index 2ccaf43e8..dc0b391b2 100644 --- a/src/vbox/vbox_uniformed_api.h +++ b/src/vbox/vbox_uniformed_api.h @@ -135,6 +135,7 @@ typedef struct { void* (*handleGetMachines)(IVirtualBox *vboxObj); void* (*handleGetHardDisks)(IVirtualBox *vboxObj); void* (*handleUSBGetDeviceFilters)(IUSBCommon *USBCommon); +void* (*handleMachineGetStorageControllers)(IMachine *machine); void* (*handleMachineGetMediumAttachments)(IMachine *machine); void* (*handleMachineGetSharedFolders)(IMachine *machine); void* (*handleSnapshotGetChildren)(ISnapshot *snapshot); @@ -410,6 +411,8 @@ typedef struct { /* Functions for IStorageController */ typedef struct { nsresult (*GetBus)(IStorageController *storageController, PRUint32 *bus); +nsresult (*SetControllerType)(IStorageController *storageController, PRUint32 controllerType); +nsresult (*GetControllerType)(IStorageController *storageController, PRUint32 *controllerType); } vboxUniformedIStorageController; /* Functions for ISharedFolder */ -- 2.14.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v2 05/15] vbox: Cleanup vboxAttachDrives implementation
This commit primes vboxAttachDrives for further changes so when they are made, the diff is less noisy: * move variable declarations to the top of the function * add disk variable to replace all the def->disks[i] instances * add cleanup at the end of the loop body, so it's all in one place rather than scattered through the loop body. It's purposefully called 'cleanup' rather than 'skip' or 'continue' because future commit will treat errors as hard-failures. --- src/vbox/vbox_common.c | 95 -- 1 file changed, 46 insertions(+), 49 deletions(-) diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c index fa8471e68..b949c4db7 100644 --- a/src/vbox/vbox_common.c +++ b/src/vbox/vbox_common.c @@ -959,8 +959,17 @@ static void vboxAttachDrives(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine) { size_t i; +int type, format; +const char *src = NULL; nsresult rc = 0; +virDomainDiskDefPtr disk = NULL; PRUnichar *storageCtlName = NULL; +IMedium *medium = NULL; +PRUnichar *mediumFileUtf16 = NULL, *mediumEmpty = NULL; +PRUint32 devicePort, deviceSlot, deviceType, accessMode; +vboxIID mediumUUID; + +VBOX_IID_INITIALIZE(); /* add a storage controller for the mediums to be attached */ /* this needs to change when multiple controller are supported for @@ -1003,57 +1012,50 @@ vboxAttachDrives(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine) } for (i = 0; i < def->ndisks; i++) { -const char *src = virDomainDiskGetSource(def->disks[i]); -int type = virDomainDiskGetType(def->disks[i]); -int format = virDomainDiskGetFormat(def->disks[i]); +disk = def->disks[i]; +src = virDomainDiskGetSource(disk); +type = virDomainDiskGetType(disk); +format = virDomainDiskGetFormat(disk); +deviceType = DeviceType_Null; +accessMode = AccessMode_ReadOnly; +devicePort = disk->info.addr.drive.unit; +deviceSlot = disk->info.addr.drive.bus; VIR_DEBUG("disk(%zu) type: %d", i, type); -VIR_DEBUG("disk(%zu) device: %d", i, def->disks[i]->device); -VIR_DEBUG("disk(%zu) bus:%d", i, def->disks[i]->bus); +VIR_DEBUG("disk(%zu) device: %d", i, disk->device); +VIR_DEBUG("disk(%zu) bus:%d", i, disk->bus); VIR_DEBUG("disk(%zu) src:%s", i, src); -VIR_DEBUG("disk(%zu) dst:%s", i, def->disks[i]->dst); +VIR_DEBUG("disk(%zu) dst:%s", i, disk->dst); VIR_DEBUG("disk(%zu) driverName: %s", i, - virDomainDiskGetDriver(def->disks[i])); + virDomainDiskGetDriver(disk)); VIR_DEBUG("disk(%zu) driverType: %s", i, virStorageFileFormatTypeToString(format)); -VIR_DEBUG("disk(%zu) cachemode: %d", i, def->disks[i]->cachemode); -VIR_DEBUG("disk(%zu) readonly: %s", i, (def->disks[i]->src->readonly +VIR_DEBUG("disk(%zu) cachemode: %d", i, disk->cachemode); +VIR_DEBUG("disk(%zu) readonly: %s", i, (disk->src->readonly ? "True" : "False")); -VIR_DEBUG("disk(%zu) shared: %s", i, (def->disks[i]->src->shared +VIR_DEBUG("disk(%zu) shared: %s", i, (disk->src->shared ? "True" : "False")); if (type == VIR_STORAGE_TYPE_FILE && src) { -IMedium *medium = NULL; -vboxIID mediumUUID; -PRUnichar *mediumFileUtf16 = NULL; -PRUint32 deviceType = DeviceType_Null; -PRUint32 accessMode = AccessMode_ReadOnly; -PRInt32 devicePort = def->disks[i]->info.addr.drive.unit; -PRInt32 deviceSlot = def->disks[i]->info.addr.drive.bus; - -VBOX_IID_INITIALIZE(); VBOX_UTF8_TO_UTF16(src, ); -if (def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_DISK) { +if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK) { deviceType = DeviceType_HardDisk; accessMode = AccessMode_ReadWrite; -} else if (def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_CDROM) { +} else if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) { deviceType = DeviceType_DVD; accessMode = AccessMode_ReadOnly; -} else if (def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY) { +} else if (disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY) { deviceType = DeviceType_Floppy; accessMode = AccessMode_ReadWrite; } else { -VBOX_UTF16_FREE(mediumFileUtf16); -continue; +goto cleanup; } gVBoxAPI.UIVirtualBox.FindHardDisk(data->vboxObj, mediumFileUtf16, deviceType, accessMode, );
[libvirt] [PATCH v2 03/15] vbox: Cleanup partially-defined VM on failure
Since the VBOX API requires to register an initial VM before proceeding to attach any remaining devices to it, any failure to attach such devices should result in automatic cleanup of the initially registered VM so that the state of VBOX registry remains clean without any leftover "aborted" VMs in it. Failure to cleanup of such partial VMs results in a warning log so that actual define error stays on the top of the error stack. --- src/vbox/vbox_common.c | 41 +++-- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c index 92ee37164..812c940e6 100644 --- a/src/vbox/vbox_common.c +++ b/src/vbox/vbox_common.c @@ -1853,6 +1853,8 @@ vboxDomainDefineXMLFlags(virConnectPtr conn, const char *xml, unsigned int flags char uuidstr[VIR_UUID_STRING_BUFLEN]; virDomainPtr ret = NULL; unsigned int parse_flags = VIR_DOMAIN_DEF_PARSE_INACTIVE; +bool machineReady = false; + virCheckFlags(VIR_DOMAIN_DEFINE_VALIDATE, NULL); @@ -1862,12 +1864,12 @@ vboxDomainDefineXMLFlags(virConnectPtr conn, const char *xml, unsigned int flags if (!data->vboxObj) return ret; -VBOX_IID_INITIALIZE(); if (!(def = virDomainDefParseString(xml, data->caps, data->xmlopt, NULL, parse_flags))) { -goto cleanup; +return ret; } +VBOX_IID_INITIALIZE(); virUUIDFormat(def->uuid, uuidstr); rc = gVBoxAPI.UIVirtualBox.CreateMachine(data, def, , uuidstr); @@ -1959,30 +1961,41 @@ vboxDomainDefineXMLFlags(virConnectPtr conn, const char *xml, unsigned int flags vboxAttachUSB(def, data, machine); vboxAttachSharedFolder(def, data, machine); -/* Save the machine settings made till now and close the - * session. also free up the mchiid variable used. +machineReady = true; + + cleanup: +/* Save the machine settings made till now, even when jumped here on error, + * as otherwise unregister won't cleanup properly. For example, it won't + * close media that were partially attached. The VBOX SDK docs say that + * unregister implicitly calls saveSettings but evidently it's not so... */ rc = gVBoxAPI.UIMachine.SaveSettings(machine); if (NS_FAILED(rc)) { virReportError(VIR_ERR_INTERNAL_ERROR, - _("failed no saving settings, rc=%08x"), (unsigned)rc); -goto cleanup; + _("Failed to save VM settings, rc=%08x"), rc); +machineReady = false; } gVBoxAPI.UISession.Close(data->vboxSession); -vboxIIDUnalloc(); - -ret = virGetDomain(conn, def->name, def->uuid, -1); -VBOX_RELEASE(machine); -virDomainDefFree(def); +if (machineReady) { +ret = virGetDomain(conn, def->name, def->uuid, -1); +} else { +/* Unregister incompletely configured VM to not leave garbage behind */ +rc = gVBoxAPI.unregisterMachine(data, , ); -return ret; +if (NS_SUCCEEDED(rc)) +gVBoxAPI.deleteConfig(machine); +else +VIR_WARN("Could not cleanup partially created VM after failure, " + "rc=%08x", rc); +} - cleanup: +vboxIIDUnalloc(); VBOX_RELEASE(machine); virDomainDefFree(def); -return NULL; + +return ret; } static virDomainPtr -- 2.14.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v2 02/15] vbox: Close media when undefining domains
When registering a VM we call OpenMedium on each disk image which adds it to vbox's global media registry. Therefore, we should make sure to call Close when unregistering VM so we cleanup the media registry entries after ourselves - this does not remove disk image files. This follows the behaviour of the VBoxManage unregistervm command. --- src/vbox/vbox_tmpl.c | 24 +++- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c index 4aa5e9a63..2679b60f7 100644 --- a/src/vbox/vbox_tmpl.c +++ b/src/vbox/vbox_tmpl.c @@ -378,6 +378,8 @@ _unregisterMachine(vboxDriverPtr data, vboxIID *iid, IMachine **machine) { nsresult rc; vboxArray media = VBOX_ARRAY_INITIALIZER; +size_t i; + rc = data->vboxObj->vtbl->FindMachine(data->vboxObj, iid->value, machine); if (NS_FAILED(rc)) { virReportError(VIR_ERR_NO_DOMAIN, "%s", @@ -385,12 +387,24 @@ _unregisterMachine(vboxDriverPtr data, vboxIID *iid, IMachine **machine) return rc; } -/* We're not interested in the array returned by the Unregister method, - * but in the side effect of unregistering the virtual machine. In order - * to call the Unregister method correctly we need to use the vboxArray - * wrapper here. */ rc = vboxArrayGetWithUintArg(, *machine, (*machine)->vtbl->Unregister, - CleanupMode_DetachAllReturnNone); + CleanupMode_DetachAllReturnHardDisksOnly); + +if (NS_FAILED(rc)) +goto cleanup; + +/* close each medium attached to VM to remove from media registry */ +for (i = 0; i < media.count; i++) { +IMedium *medium = media.items[i]; + +if (!medium) +continue; + +/* it's ok to ignore failure here - e.g. it may be used by another VM */ +ignore_value(medium->vtbl->Close(medium)); +} + + cleanup: vboxArrayUnalloc(); return rc; } -- 2.14.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v2 04/15] vbox: vboxAttachDrives now relies on address info
Previously, the driver was computing VBOX's devicePort/deviceSlot values based on device name and max port/slot values. While this worked, it completely ignored values. Additionally, libvirt's built-in virDomainDiskDefAssignAddress already does a good job setting default values on virDomainDeviceDriveAddress struct which we can use to set devicePort and deviceSlot and accomplish the same result while allowing the cusomizing those via XML. Also, this allows to remove some code which will make further patches smaller. --- src/vbox/vbox_common.c | 104 - 1 file changed, 7 insertions(+), 97 deletions(-) diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c index 812c940e6..fa8471e68 100644 --- a/src/vbox/vbox_common.c +++ b/src/vbox/vbox_common.c @@ -346,68 +346,6 @@ static bool vboxGetMaxPortSlotValues(IVirtualBox *vbox, return true; } -/** - * function to get the StorageBus, Port number - * and Device number for the given devicename - * e.g: hda has StorageBus = IDE, port = 0, - * device = 0 - * - * @returns true on Success, false on failure. - * @param deviceName Input device name - * @param aMaxPortPerInst Input array of max port per device instance - * @param aMaxSlotPerPort Input array of max slot per device port - * @param storageBus Input storage bus type - * @param deviceInst Output device instance number - * @param devicePort Output port number - * @param deviceSlot Output slot number - * - */ -static bool vboxGetDeviceDetails(const char *deviceName, - PRUint32 *aMaxPortPerInst, - PRUint32 *aMaxSlotPerPort, - PRUint32 storageBus, - PRInt32 *deviceInst, - PRInt32 *devicePort, - PRInt32 *deviceSlot) -{ -int total = 0; -PRUint32 maxPortPerInst = 0; -PRUint32 maxSlotPerPort = 0; - -if (!deviceName || -!deviceInst || -!devicePort || -!deviceSlot || -!aMaxPortPerInst || -!aMaxSlotPerPort) -return false; - -if ((storageBus < StorageBus_IDE) || -(storageBus > StorageBus_Floppy)) -return false; - -total = virDiskNameToIndex(deviceName); - -maxPortPerInst = aMaxPortPerInst[storageBus]; -maxSlotPerPort = aMaxSlotPerPort[storageBus]; - -if (!maxPortPerInst || -!maxSlotPerPort || -(total < 0)) -return false; - -*deviceInst = total / (maxPortPerInst * maxSlotPerPort); -*devicePort = (total % (maxPortPerInst * maxSlotPerPort)) / maxSlotPerPort; -*deviceSlot = (total % (maxPortPerInst * maxSlotPerPort)) % maxSlotPerPort; - -VIR_DEBUG("name=%s, total=%d, storageBus=%u, deviceInst=%d, " - "devicePort=%d deviceSlot=%d, maxPortPerInst=%u maxSlotPerPort=%u", - deviceName, total, storageBus, *deviceInst, *devicePort, - *deviceSlot, maxPortPerInst, maxSlotPerPort); - -return true; -} - /** * function to generate the name for medium, * for e.g: hda, sda, etc @@ -1022,14 +960,7 @@ vboxAttachDrives(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine) { size_t i; nsresult rc = 0; -PRUint32 maxPortPerInst[StorageBus_Floppy + 1] = {}; -PRUint32 maxSlotPerPort[StorageBus_Floppy + 1] = {}; PRUnichar *storageCtlName = NULL; -bool error = false; - -/* get the max port/slots/etc for the given storage bus */ -error = !vboxGetMaxPortSlotValues(data->vboxObj, maxPortPerInst, - maxSlotPerPort); /* add a storage controller for the mediums to be attached */ /* this needs to change when multiple controller are supported for @@ -1071,7 +1002,7 @@ vboxAttachDrives(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine) VBOX_RELEASE(storageCtl); } -for (i = 0; i < def->ndisks && !error; i++) { +for (i = 0; i < def->ndisks; i++) { const char *src = virDomainDiskGetSource(def->disks[i]); int type = virDomainDiskGetType(def->disks[i]); int format = virDomainDiskGetFormat(def->disks[i]); @@ -1095,12 +1026,10 @@ vboxAttachDrives(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine) IMedium *medium = NULL; vboxIID mediumUUID; PRUnichar *mediumFileUtf16 = NULL; -PRUint32 storageBus = StorageBus_Null; PRUint32 deviceType = DeviceType_Null; PRUint32 accessMode = AccessMode_ReadOnly; -PRInt32 deviceInst = 0; -PRInt32 devicePort = 0; -PRInt32 deviceSlot = 0; +PRInt32 devicePort = def->disks[i]->info.addr.drive.unit; +PRInt32 deviceSlot = def->disks[i]->info.addr.drive.bus; VBOX_IID_INITIALIZE(); VBOX_UTF8_TO_UTF16(src, ); @@ -1166,35
Re: [libvirt] [PATCH 5/6] vbox: Process controller definitions from xml.
On Tue, 2017-10-17 at 15:46 -0400, John Ferlan wrote: > > On 10/09/2017 04:49 PM, Dawid Zamirski wrote: > > From: Dawid Zamirski <dzamir...@datto.com> > > > Lots of potentially use DEBUG information being lost. IDC, but seems > a > shame to not have it. Although it can be overkill when DEBUG is > enabled > - it does help sometimes in debugging problems. Your call... I've removed those because they basically print out the values of the XML I just passed in and I know them from XML already. I've added a more useful (at least for me) debug statement in (WIP) V2 that prints the arguments passed to VBOX's AttachDevice method - those are 'computed' based on XML input by this very code so it's more helpful to know what those final values are when debugging. > > > - > > -if (type == VIR_STORAGE_TYPE_FILE && src) { > > -IMedium *medium = NULL; > > -vboxIID mediumUUID; > > -PRUnichar *mediumFileUtf16 = NULL; > > -PRUint32 storageBus = StorageBus_Null; > > -PRUint32 deviceType = DeviceType_Null; > > -PRUint32 accessMode = AccessMode_ReadOnly; > > -PRInt32 deviceInst = 0; > > -PRInt32 devicePort = 0; > > -PRInt32 deviceSlot = 0; > > +for (i = 0; i < def->ndisks; i++) { > > +disk = def->disks[i]; > > +const char *src = virDomainDiskGetSource(disk); > > +int type = virDomainDiskGetType(disk); > > > > -VBOX_IID_INITIALIZE(); > > -VBOX_UTF8_TO_UTF16(src, ); > > +if (type != VIR_STORAGE_TYPE_FILE) { > > +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, > > + _("Unsupported storage type %s, the > > only supported " > > + "type is %s"), > > + virStorageTypeToString(type), > > + virStorageTypeToString(VIR_STORAGE_TYPE > > _FILE)); > > +return -1; > > +} > > > > -if (def->disks[i]->device == > > VIR_DOMAIN_DISK_DEVICE_DISK) { > > -deviceType = DeviceType_HardDisk; > > -accessMode = AccessMode_ReadWrite; > > -} else if (def->disks[i]->device == > > VIR_DOMAIN_DISK_DEVICE_CDROM) { > > -deviceType = DeviceType_DVD; > > -accessMode = AccessMode_ReadOnly; > > -} else if (def->disks[i]->device == > > VIR_DOMAIN_DISK_DEVICE_FLOPPY) { > > -deviceType = DeviceType_Floppy; > > -accessMode = AccessMode_ReadWrite; > > -} else { > > -VBOX_UTF16_FREE(mediumFileUtf16); > > -continue; > > -} > > +if (!src && disk->device == VIR_DOMAIN_DISK_DEVICE_DISK) { > > I think more typically there are checks against != *_CDROM || > *_FLOPPY > although perhaps this check should go slightly later [1] > > > +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", > > + _("Missing disk source file path")); > > +return -1; > > +} > > > > -gVBoxAPI.UIVirtualBox.FindHardDisk(data->vboxObj, > > mediumFileUtf16, > > - deviceType, > > accessMode, ); > > +IMedium *medium = NULL; > > +vboxIID mediumUUID; > > Since you call vboxIIDUnalloc later on this [2], perhaps this should > be > initialized to NULL... Although, I see it only gets set when "if > (src)", > so perhaps that becomes the key for Unalloc too. > > > +PRUnichar *mediumFileUtf16 = NULL; > > +PRUint32 deviceType = DeviceType_Null; > > +PRUint32 accessMode = AccessMode_ReadOnly; > > +PRInt32 deviceSlot = disk->info.addr.drive.bus; > > +PRInt32 devicePort = disk->info.addr.drive.unit; > > +int model = -1; > > We really prefer to see definitions grouped together at the top > rather > than in the middle of code > > > + > > +if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK) { > > [1] If you move that !src check here, then you're accomplishing the > same result as previously but making it more obvious (at least for > me) > since _LUN isn't supported... > > > +deviceType = DeviceType_HardDisk; > > +accessMode = AccessMode_ReadWrite; > > +} else if (disk->device == VIR
Re: [libvirt] [PATCH 2/6] domain: Allow 'model' attribute for ide controller.
On Tue, 2017-10-17 at 15:46 -0400, John Ferlan wrote: > > On 10/09/2017 04:49 PM, Dawid Zamirski wrote: > > From: Dawid Zamirski <dzamir...@datto.com> > > > > The optional values are 'piix3', 'piix4' or 'ich6'. Those will be > > needed to allow setting IDE controller model in VirtualBox driver. > > --- > > docs/schemas/domaincommon.rng | 18 -- > > src/conf/domain_conf.c| 9 + > > src/conf/domain_conf.h| 9 + > > src/libvirt_private.syms | 2 ++ > > 4 files changed, 36 insertions(+), 2 deletions(-) > > > > Patches 2 & 3 should be combined and you'll need to provide an > xml2xml > example here, modifying tests/qemuxml2xmltest.c in order to add your > test. Search for controller type='scsi' and model= being set in any > of > the tests/*/*.xml files. Then generate your test that would have > controller type='ide' ... model='xxx' (just one example is fine). > I understand that the patch with test cases should be separated, corrent? > You may also need to alter virDomainControllerDefValidate to ensure > perhaps some existing assumptions on VIR_DOMAIN_CONTROLLER_TYPE_IDE > aren't lost if ->model is filled in. > That's clear, no problem... > I am far from being an expert on IDE controllers and their existing > assumptions, but if you search on VIR_DOMAIN_CONTROLLER_TYPE_IDE > references you will find the existing ones. My assumption has been > that > the current model assumption is piix3 - so by adding piix4 and ich6 > you'll need to alter code in order to handle any assumptions those > models have; otherwise, once code finds IDE it assumes piix3 and > those > assumptions may not work well for piix4 and ich6. > ...though, I'm a little concerned with this part. While I'm somewhat familiar with libvirt qemu driver and can confirm that it implies PIIX3 for IDE (at least libvirt does by checking if emulated machine is 440FX although qemu itself seems to support PIIX4 as well [1]), I'm not so sure I could easily determine "defaults" for other drivers like ESX (especially this one being closed-source) - AFAIK those drivers basically allow to attach "an IDE controller" without any specifics on what particular model of the southbridge the hypervisor should emulate - I guess it's likely determined by the "machine" type or hwVersion (ESX) and I suppose vbox is an "oddball" here allowing to set IDE controller model independently. Would it be acceptable to update each driver to check that ->model == -1 and error out if it's not? In other words, qemu would allow model {-1,piix3}, vbox {-1,piix3,piix4,ich6} everything else would accept just -1 - guess those could be enforced by implementing virDomainDeviceDefValidateCallback in each driver. [1] https://github.com/qemu/qemu/blob/master/hw/ide/piix.c#L285 > > diff --git a/docs/schemas/domaincommon.rng > > b/docs/schemas/domaincommon.rng > > index 4dbda6932..c3f1557f0 100644 > > --- a/docs/schemas/domaincommon.rng > > +++ b/docs/schemas/domaincommon.rng > > @@ -1927,12 +1927,11 @@ > > > > > > > > - > > + > > > > > > > > fdc > > -ide > > sata > > ccid > > > > @@ -1993,6 +1992,21 @@ > > > > > > > > + > > + > > + > > + ide > > + > > + > > + > > + > > + piix3 > > + piix4 > > + ich6 > > + > > + > > + > > + > > > > > > > > diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c > > index 54be9028d..493bf83ff 100644 > > --- a/src/conf/domain_conf.c > > +++ b/src/conf/domain_conf.c > > @@ -378,6 +378,11 @@ VIR_ENUM_IMPL(virDomainControllerModelUSB, > > VIR_DOMAIN_CONTROLLER_MODEL_USB_LAST, > >"qemu-xhci", > >"none") > > > > +VIR_ENUM_IMPL(virDomainControllerModelIDE, > > VIR_DOMAIN_CONTROLLER_MODEL_IDE_LAST, > > + "piix3", > > + "piix4", > > + "ich6") > > + > > VIR_ENUM_IMPL(virDomainFS, VIR_DOMAIN_FS_TYPE_LAST, > >"mount", > >
Re: [libvirt] [PATCH 1/6] vbox: Close media when undefining domains.
On Tue, 2017-10-17 at 15:44 -0400, John Ferlan wrote: > > On 10/09/2017 04:49 PM, Dawid Zamirski wrote: > > From: Dawid Zamirski <dzamir...@datto.com> > > > > When registering a VM we call OpenMedium on each disk image which > > adds it > > to vbox's global media registry. Therefore, we should make sure to > > call > > Close when unregistering VM so we cleanup the media registry > > entries > > after ourselves - this does not remove disk image files. This > > follows > > the behaviour of the VBoxManage unregistervm command. > > --- > > src/vbox/vbox_tmpl.c | 24 +++- > > 1 file changed, 19 insertions(+), 5 deletions(-) > > > > I'm not a vbox expert by any stretch, looking at this mostly because > it's been sitting on list unreviewed... Thank you :-) > > > diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c > > index dffeabde0..ac3b8fa00 100644 > > --- a/src/vbox/vbox_tmpl.c > > +++ b/src/vbox/vbox_tmpl.c > > @@ -378,6 +378,8 @@ _unregisterMachine(vboxDriverPtr data, vboxIID > > *iid, IMachine **machine) > > { > > nsresult rc; > > vboxArray media = VBOX_ARRAY_INITIALIZER; > > +size_t i; > > + > > rc = data->vboxObj->vtbl->FindMachine(data->vboxObj, iid- > > >value, machine); > > if (NS_FAILED(rc)) { > > virReportError(VIR_ERR_NO_DOMAIN, "%s", > > @@ -385,12 +387,24 @@ _unregisterMachine(vboxDriverPtr data, > > vboxIID *iid, IMachine **machine) > > return rc; > > } > > > > -/* We're not interested in the array returned by the > > Unregister method, > > - * but in the side effect of unregistering the virtual > > machine. In order > > - * to call the Unregister method correctly we need to use the > > vboxArray > > - * wrapper here. */ > > I think you should keep the second sentence here - "In order to > call..." > - IDC either way, but that would seem to still be important. > Since this patch adds a code that loops over this array to close each IMedium instance it's self-documenting so no there's need for code comments here. > > rc = vboxArrayGetWithUintArg(, *machine, (*machine)- > > >vtbl->Unregister, > > - CleanupMode_DetachAllReturnNone); > > + CleanupMode_DetachAllReturnHardDi > > sksOnly); > > + > > +if (NS_FAILED(rc)) > > +goto cleanup; > > + > > +/* close each medium attached to VM to remove from media > > registry */ > > +for (i = 0; i < media.count; i++) { > > +IMedium *medium = media.items[i]; > > + > > +if (!medium) > > +continue; > > + > > So the vboxSnapshotRedefine and vboxDomainSnapshotDeleteMetadataOnly > APIs that use CleanupMode_DetachAllReturnHardDisksOnly seem to go > through some great pain to determine whether it's a "fake" disk or > not - > would this code need the same kind of logic? > > /me wonders how much the existing code could be made more common - > beyond the "isCurrent" in the latter function the code appears to be > the > same. If this code needs it, then it might be worth the effort to > pass > 'isCurrent' to some common helper and for the other caller, just pass > true instead... Which would be similar if this code needed that. I intentionally tried to stay away from touching the snapshot related functions even though it seems that they could share some code. Since I've been working on this on and off between projects at work, at initial stages it seemed like a couple of lines of code "here and there" would let me set/change vbox storage controller models via libvirtxml. Unfortunately, as I dug deeper and tested all sorts of combinations more bugs (even in master branch) seemed to pop out and the series grew to be much bigger than I originally intended. However, since I'll have to reorganize the commits for V2 anyway, I'll take a look at those functions and see what I can do. > > > +/* it's ok to ignore failure here - e.g. it may be used by > > another VM */ > > +medium->vtbl->Close(medium); > > You could place an ignore_value(); around this. Again see the two > API's > above they have a detailed explanation. > > > John > > > +} > > + > > + cleanup: > > vboxArrayUnalloc(); > > return rc; > > } > > > > -- > libvir-list mailing list > libvir-list@redhat.com > https://www.redhat.com/mailman/listinfo/libvir-list -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 1/3] vbox: Make autoport set RDP port range.
Originally autoport in vbox driver was setting the port to default value (3389) which caused mutiple VM instances use the same port. Since libvirt XML does not allow to set port ranges, this patch changes the "autoport" behavior to set VBox's "TCP/Ports" property to an arbitraty port range (3389-3689) to avoid that issue. --- src/vbox/vbox_tmpl.c | 16 +--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c index dffeabde0..8e47d90d6 100644 --- a/src/vbox/vbox_tmpl.c +++ b/src/vbox/vbox_tmpl.c @@ -152,6 +152,9 @@ if (strUtf16) {\ #define VBOX_IID_INITIALIZER { NULL, true } +/* default RDP port range to use for auto-port setting */ +#define VBOX_RDP_AUTOPORT_RANGE "3389-3689" + static void _vboxIIDUnalloc(vboxDriverPtr data, vboxIID *iid) { @@ -1601,20 +1604,27 @@ _vrdeServerGetPorts(vboxDriverPtr data ATTRIBUTE_UNUSED, } static nsresult -_vrdeServerSetPorts(vboxDriverPtr data ATTRIBUTE_UNUSED, -IVRDEServer *VRDEServer, virDomainGraphicsDefPtr graphics) +_vrdeServerSetPorts(vboxDriverPtr data, IVRDEServer *VRDEServer, +virDomainGraphicsDefPtr graphics) { nsresult rc = 0; PRUnichar *VRDEPortsKey = NULL; PRUnichar *VRDEPortsValue = NULL; VBOX_UTF8_TO_UTF16("TCP/Ports", ); -VRDEPortsValue = PRUnicharFromInt(data->pFuncs, graphics->data.rdp.port); + +if (graphics->data.rdp.port) +VRDEPortsValue = PRUnicharFromInt(data->pFuncs, + graphics->data.rdp.port); +else if (graphics->data.rdp.autoport) +VBOX_UTF8_TO_UTF16(VBOX_RDP_AUTOPORT_RANGE, ); + rc = VRDEServer->vtbl->SetVRDEProperty(VRDEServer, VRDEPortsKey, VRDEPortsValue); VBOX_UTF16_FREE(VRDEPortsKey); VBOX_UTF16_FREE(VRDEPortsValue); + return rc; } -- 2.14.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 3/3] docs: Fix multiUser/replaceUser in RDP display doc.
The original description got it backwards. --- docs/formatdomain.html.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index c0e3c2221..19a778bce 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -6045,9 +6045,9 @@ qemu-kvm -net nic,model=? /dev/null TCP port number (with -1 as legacy syntax indicating that it should be auto-allocated). The autoport attribute is the new preferred syntax for indicating auto-allocation of the TCP port to - use. The replaceUser attribute is a boolean deciding + use. The multiUser attribute is a boolean deciding whether multiple simultaneous connections to the VM are permitted. - The multiUser attribute is a boolean deciding whether + The replaceUser attribute is a boolean deciding whether the existing connection must be dropped and a new connection must be established by the VRDP server, when a new client connects in single connection mode. -- 2.14.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 2/3] vbox: Read runtime RDP port and handle autoport.
VirutalBox has a IVRDEServerInfo sturcture available that gives the effective runtime port that the VM is using when it's running. This is useful when the "TCP/Ports" VBox property was set to port range (e.g. via autoport = "yes" or via VBoxManage) in which case it would be impossible to get the "active" port otherwise. --- src/vbox/vbox_common.c| 3 +- src/vbox/vbox_tmpl.c | 135 +- src/vbox/vbox_uniformed_api.h | 2 +- 3 files changed, 97 insertions(+), 43 deletions(-) diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c index 92ee37164..d542f2b76 100644 --- a/src/vbox/vbox_common.c +++ b/src/vbox/vbox_common.c @@ -3326,7 +3326,8 @@ vboxDumpDisplay(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine) if (VIR_ALLOC(graphics) < 0) goto cleanup; -gVBoxAPI.UIVRDEServer.GetPorts(data, VRDEServer, graphics); +gVBoxAPI.UIVRDEServer.GetPorts(data, VRDEServer, machine, graphics); +gVBoxAPI.UISession.Close(data->vboxSession); graphics->type = VIR_DOMAIN_GRAPHICS_TYPE_RDP; diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c index 8e47d90d6..ff69cf39c 100644 --- a/src/vbox/vbox_tmpl.c +++ b/src/vbox/vbox_tmpl.c @@ -144,12 +144,6 @@ if (strUtf16) {\ (unsigned)(iid)->m3[7]);\ }\ -#define VBOX_SESSION_OPEN(/* unused */ iid_value, /* in */ machine) \ -machine->vtbl->LockMachine(machine, data->vboxSession, LockType_Write) - -#define VBOX_SESSION_CLOSE() \ -data->vboxSession->vtbl->UnlockMachine(data->vboxSession) - #define VBOX_IID_INITIALIZER { NULL, true } /* default RDP port range to use for auto-port setting */ @@ -227,29 +221,6 @@ _vboxIIDFromArrayItem(vboxDriverPtr data, vboxIID *iid, _vboxIIDFromArrayItem(data, iid, array, idx) #define DEBUGIID(msg, strUtf16) DEBUGPRUnichar(msg, strUtf16) -/** - * Converts Utf-16 string to int - */ -static int PRUnicharToInt(PCVBOXXPCOM pFuncs, PRUnichar *strUtf16) -{ -char *strUtf8 = NULL; -int ret = 0; - -if (!strUtf16) -return -1; - -pFuncs->pfnUtf16ToUtf8(strUtf16, ); -if (!strUtf8) -return -1; - -if (virStrToLong_i(strUtf8, NULL, 10, ) < 0) -ret = -1; - -pFuncs->pfnUtf8Free(strUtf8); - -return ret; -} - /** * Converts int to Utf-16 string */ @@ -286,6 +257,56 @@ static virDomainState _vboxConvertState(PRUint32 state) } } +static int +vboxGetActiveVRDEServerPort(ISession *session, IMachine *machine) +{ +nsresult rc; +PRInt32 port = -1; +IVRDEServerInfo *vrdeInfo = NULL; +IConsole *console = NULL; +int locked = 0; + +rc = machine->vtbl->LockMachine(machine, session, LockType_Shared); +if (NS_FAILED(rc)) { +VIR_WARN("Could not obtain shared lock on VBox VM, rc=%08x", rc); +goto cleanup; +} else { +locked = 1; +} + +rc = session->vtbl->GetConsole(session, ); +if (NS_FAILED(rc)) { +VIR_WARN("Could not get VBox session console, rc=%08x", rc); +goto cleanup; +} + +/* it may be null if VM is not running */ +if (!console) +goto cleanup; + +rc = console->vtbl->GetVRDEServerInfo(console, ); + +if (NS_FAILED(rc) || !vrdeInfo) { +VIR_WARN("Could not get VBox VM VRDEServerInfo, rc=%08x", rc); +goto cleanup; +} + +rc = vrdeInfo->vtbl->GetPort(vrdeInfo, ); + +if (NS_FAILED(rc)) { +VIR_WARN("Could not read port from VRDEServerInfo, rc=%08x", rc); +goto cleanup; +} + + cleanup: +VBOX_RELEASE(console); +VBOX_RELEASE(vrdeInfo); +if (locked) +session->vtbl->UnlockMachine(session); + +return port; +} + static int _vboxDomainSnapshotRestore(virDomainPtr dom, IMachine *machine, @@ -326,7 +347,7 @@ _vboxDomainSnapshotRestore(virDomainPtr dom, goto cleanup; } -rc = VBOX_SESSION_OPEN(domiid.value, machine); +rc = machine->vtbl->LockMachine(machine, data->vboxSession, LockType_Write); #if VBOX_API_VERSION < 500 if (NS_SUCCEEDED(rc)) rc = data->vboxSession->vtbl->GetConsole(data->vboxSession, ); @@ -371,7 +392,7 @@ _vboxDomainSnapshotRestore(virDomainPtr dom, #if VBOX_API_VERSION < 500 VBOX_RELEASE(console); #endif /*VBOX_API_VERSION < 500*/ -VBOX_SESSION_CLOSE(); +data->vboxSession->vtbl->UnlockMachine(data->vboxSession); vboxIIDUnalloc(); return ret; } @@ -1582,24 +1603,56 @@ _vrdeServerSetEnabled(IVRDEServer *VRDEServer, PRBool enabled) } static nsresult -_vrdeServerGetPorts(vboxDriverPtr data ATTRIBUTE_UNUSED, -IVRDEServer *VRDEServer, virDomainGraphicsDefPtr graphics) +_vrdeServerGetPorts(vboxDriverPtr data, IVRDEServer *VRDEServer, +IMachine *machine, virDomainGraphicsDefPtr graphics) { nsresult rc; PRUnichar *VRDEPortsKey = NULL; PRUnichar *VRDEPortsValue = NULL; +PRInt32 port = -1; +ssize_t nmatches
[libvirt] [PATCH 0/3] vbox: Update VRDE server port handling.
Hello, The following patches improve how VRDE is handled by libvirt vbox driver: * When autoport=yes, it will now set the VRDE server to a port range 3389-3689, thus when muliple VMs are started with autoport=yes, they will use non-conflicting ports from this port range - previously all VMs would try to use the default 3389 * When dumping display configuration to XML, first try to read the VRDE port using VRDEServerInfo which provides the "effective" port that the VM is using. Otherwise, fall back to read it from VRDEServer property. * Fix the documentation on RDP wher the descriptions of multiUser and replaceUser were swapped. Dawid Zamirski (3): vbox: Make autoport set RDP port range. vbox: Read runtime RDP port and handle autoport. docs: Fix multiUser/replaceUser in RDP display doc. docs/formatdomain.html.in | 4 +- src/vbox/vbox_common.c| 3 +- src/vbox/vbox_tmpl.c | 151 ++ src/vbox/vbox_uniformed_api.h | 2 +- 4 files changed, 112 insertions(+), 48 deletions(-) -- 2.14.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 3/6] docs: Add info about ide model attribute.
From: Dawid Zamirski <dzamir...@datto.com> --- docs/formatdomain.html.in | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index c0e3c2221..ddcc9f1b1 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -3596,6 +3596,9 @@ Since 1.3.5, USB controllers accept a ports attribute to configure how many devices can be connected to the controller. +ide +An ide controller has an optional attribute +model, which is one of "piix3", "piix4" or "ich6". -- 2.14.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 5/6] vbox: Process controller definitions from xml.
From: Dawid Zamirski <dzamir...@datto.com> Until now the vbox driver was completely ignoring element for storage in the XML definition. This patch adds support for interpretting element for storage devices. With this the following other changes were made to the whole storage attachment code: * vboxAttachDrives no longer "computes" deviceSlot and devicePort values based on the disk device name. This was causing the driver to ignore the values set by element of the device. If that element is omitted in XML, the values produced by default by virDomainDiskDefAssign address should work well. * if any part of storage attachment code fails, i.e wherever we call virReportError, we also fail the DefineXML caller rather than ignoring those issues and moving on. * the DefineXML cleanup part of the code was changed to make sure that any critical failure in device attachment code does not leave any partially defined VM behind. * do not require disk source for removable drives so that "empty" drives can be created for cdrom and floppy types. --- src/vbox/vbox_common.c | 535 ++--- src/vbox/vbox_common.h | 8 + src/vbox/vbox_tmpl.c | 43 ++-- 3 files changed, 310 insertions(+), 276 deletions(-) diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c index 92ee37164..7645b29a0 100644 --- a/src/vbox/vbox_common.c +++ b/src/vbox/vbox_common.c @@ -324,6 +324,9 @@ static bool vboxGetMaxPortSlotValues(IVirtualBox *vbox, gVBoxAPI.UISystemProperties.GetMaxPortCountForStorageBus(sysProps, StorageBus_SCSI, [StorageBus_SCSI]); +gVBoxAPI.UISystemProperties.GetMaxPortCountForStorageBus(sysProps, + StorageBus_SAS, + [StorageBus_SAS]); gVBoxAPI.UISystemProperties.GetMaxPortCountForStorageBus(sysProps, StorageBus_Floppy, [StorageBus_Floppy]); @@ -337,6 +340,9 @@ static bool vboxGetMaxPortSlotValues(IVirtualBox *vbox, gVBoxAPI.UISystemProperties.GetMaxDevicesPerPortForStorageBus(sysProps, StorageBus_SCSI, [StorageBus_SCSI]); +gVBoxAPI.UISystemProperties.GetMaxDevicesPerPortForStorageBus(sysProps, + StorageBus_SAS, + [StorageBus_SAS]); gVBoxAPI.UISystemProperties.GetMaxDevicesPerPortForStorageBus(sysProps, StorageBus_Floppy, [StorageBus_Floppy]); @@ -346,68 +352,6 @@ static bool vboxGetMaxPortSlotValues(IVirtualBox *vbox, return true; } -/** - * function to get the StorageBus, Port number - * and Device number for the given devicename - * e.g: hda has StorageBus = IDE, port = 0, - * device = 0 - * - * @returns true on Success, false on failure. - * @param deviceName Input device name - * @param aMaxPortPerInst Input array of max port per device instance - * @param aMaxSlotPerPort Input array of max slot per device port - * @param storageBus Input storage bus type - * @param deviceInst Output device instance number - * @param devicePort Output port number - * @param deviceSlot Output slot number - * - */ -static bool vboxGetDeviceDetails(const char *deviceName, - PRUint32 *aMaxPortPerInst, - PRUint32 *aMaxSlotPerPort, - PRUint32 storageBus, - PRInt32 *deviceInst, - PRInt32 *devicePort, - PRInt32 *deviceSlot) -{ -int total = 0; -PRUint32 maxPortPerInst = 0; -PRUint32 maxSlotPerPort = 0; - -if (!deviceName || -!deviceInst || -!devicePort || -!deviceSlot || -!aMaxPortPerInst || -!aMaxSlotPerPort) -return false; - -if ((storageBus < StorageBus_IDE) || -(storageBus > StorageBus_Floppy)) -return false; - -total = virDiskNameToIndex(deviceName); - -maxPortPerInst = aMaxPortPerInst[storageBus]; -maxSlotPerPort = aMaxSlotPerPort[storageBus]; - -if (!maxPortPerInst || -!maxSlotPerPort || -(total < 0)) -return false; - -*deviceInst = total / (maxPortPerInst * maxSlotPerPort); -*devicePort = (total % (maxPortPerInst * maxSlotPerPort)) / maxSlo
[libvirt] [PATCH 6/6] vbox: Update XML dump of storage devices.
From: Dawid Zamirski <dzamir...@datto.com> * added vboxDumpStorageControllers * replaced vboxDumpIDEHDDs with vboxDumpDisks which has been refectored quite a bit to handle removable devices, the new SAS controller support etc. * align the logic in vboxSnapshotGetReadWriteDisks and vboxSnapshotGetReadOnlyDisks to more closely resemble vboxDumpDisks. * vboxGenerateMediumName was simplified to no longer "compute" the device name value as deviePort/deviceSlot and their upper bound values are no longer enough to do this accurately due to the added SAS bus support which does not "map" directly into libvirt XML semantics * vboxGetMaxPortSlotValues is now removed as it's no longer used --- src/vbox/vbox_common.c | 691 - 1 file changed, 393 insertions(+), 298 deletions(-) diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c index 7645b29a0..dd876645a 100644 --- a/src/vbox/vbox_common.c +++ b/src/vbox/vbox_common.c @@ -290,126 +290,44 @@ static int openSessionForMachine(vboxDriverPtr data, const unsigned char *dom_uu return 0; } -/** - * function to get the values for max port per - * instance and max slots per port for the devices - * - * @returns true on Success, false on failure. - * @param vboxInput IVirtualBox pointer - * @param maxPortPerInst Output array of max port per instance - * @param maxSlotPerPort Output array of max slot per port - * - */ - -static bool vboxGetMaxPortSlotValues(IVirtualBox *vbox, - PRUint32 *maxPortPerInst, - PRUint32 *maxSlotPerPort) -{ -ISystemProperties *sysProps = NULL; - -if (!vbox) -return false; - -gVBoxAPI.UIVirtualBox.GetSystemProperties(vbox, ); - -if (!sysProps) -return false; - -gVBoxAPI.UISystemProperties.GetMaxPortCountForStorageBus(sysProps, - StorageBus_IDE, - [StorageBus_IDE]); -gVBoxAPI.UISystemProperties.GetMaxPortCountForStorageBus(sysProps, - StorageBus_SATA, - [StorageBus_SATA]); -gVBoxAPI.UISystemProperties.GetMaxPortCountForStorageBus(sysProps, - StorageBus_SCSI, - [StorageBus_SCSI]); -gVBoxAPI.UISystemProperties.GetMaxPortCountForStorageBus(sysProps, - StorageBus_SAS, - [StorageBus_SAS]); -gVBoxAPI.UISystemProperties.GetMaxPortCountForStorageBus(sysProps, - StorageBus_Floppy, - [StorageBus_Floppy]); - -gVBoxAPI.UISystemProperties.GetMaxDevicesPerPortForStorageBus(sysProps, - StorageBus_IDE, - [StorageBus_IDE]); -gVBoxAPI.UISystemProperties.GetMaxDevicesPerPortForStorageBus(sysProps, - StorageBus_SATA, - [StorageBus_SATA]); -gVBoxAPI.UISystemProperties.GetMaxDevicesPerPortForStorageBus(sysProps, - StorageBus_SCSI, - [StorageBus_SCSI]); -gVBoxAPI.UISystemProperties.GetMaxDevicesPerPortForStorageBus(sysProps, - StorageBus_SAS, - [StorageBus_SAS]); -gVBoxAPI.UISystemProperties.GetMaxDevicesPerPortForStorageBus(sysProps, - StorageBus_Floppy, - [StorageBus_Floppy]); - -VBOX_RELEASE(sysProps); - -return true; -} - /** * function to generate the name for medium, * for e.g: hda, sda, etc * * @returns null terminated string with device name or NULL * for failures - * @param connInput Connection Pointer * @param storageBus Input storage bus type - * @param deviceInst Input device instance number * @param devicePort Input port number * @param deviceSlot Input slot number - * @param aMaxPortPerInst Input array of max port per device instance - * @param aMaxSlotPerPort Input array of max slot per device port - * + * @param sdC
[libvirt] [PATCH 2/6] domain: Allow 'model' attribute for ide controller.
From: Dawid Zamirski <dzamir...@datto.com> The optional values are 'piix3', 'piix4' or 'ich6'. Those will be needed to allow setting IDE controller model in VirtualBox driver. --- docs/schemas/domaincommon.rng | 18 -- src/conf/domain_conf.c| 9 + src/conf/domain_conf.h| 9 + src/libvirt_private.syms | 2 ++ 4 files changed, 36 insertions(+), 2 deletions(-) diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 4dbda6932..c3f1557f0 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -1927,12 +1927,11 @@ - + fdc -ide sata ccid @@ -1993,6 +1992,21 @@ + + + + ide + + + + + piix3 + piix4 + ich6 + + + + diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 54be9028d..493bf83ff 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -378,6 +378,11 @@ VIR_ENUM_IMPL(virDomainControllerModelUSB, VIR_DOMAIN_CONTROLLER_MODEL_USB_LAST, "qemu-xhci", "none") +VIR_ENUM_IMPL(virDomainControllerModelIDE, VIR_DOMAIN_CONTROLLER_MODEL_IDE_LAST, + "piix3", + "piix4", + "ich6") + VIR_ENUM_IMPL(virDomainFS, VIR_DOMAIN_FS_TYPE_LAST, "mount", "block", @@ -9467,6 +9472,8 @@ virDomainControllerModelTypeFromString(const virDomainControllerDef *def, return virDomainControllerModelUSBTypeFromString(model); else if (def->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI) return virDomainControllerModelPCITypeFromString(model); +else if (def->type == VIR_DOMAIN_CONTROLLER_TYPE_IDE) +return virDomainControllerModelIDETypeFromString(model); return -1; } @@ -9482,6 +9489,8 @@ virDomainControllerModelTypeToString(virDomainControllerDefPtr def, return virDomainControllerModelUSBTypeToString(model); else if (def->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI) return virDomainControllerModelPCITypeToString(model); +else if (def->type == VIR_DOMAIN_CONTROLLER_TYPE_IDE) +return virDomainControllerModelIDETypeToString(model); return NULL; } diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index a42efcfa6..d7f4c3f1e 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -748,6 +748,14 @@ typedef enum { VIR_DOMAIN_CONTROLLER_MODEL_USB_LAST } virDomainControllerModelUSB; +typedef enum { +VIR_DOMAIN_CONTROLLER_MODEL_IDE_PIIX3, +VIR_DOMAIN_CONTROLLER_MODEL_IDE_PIIX4, +VIR_DOMAIN_CONTROLLER_MODEL_IDE_ICH6, + +VIR_DOMAIN_CONTROLLER_MODEL_IDE_LAST +} virDomainControllerModelIDE; + # define IS_USB2_CONTROLLER(ctrl) \ (((ctrl)->type == VIR_DOMAIN_CONTROLLER_TYPE_USB) && \ ((ctrl)->model == VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_EHCI1 || \ @@ -3231,6 +3239,7 @@ VIR_ENUM_DECL(virDomainControllerModelPCI) VIR_ENUM_DECL(virDomainControllerPCIModelName) VIR_ENUM_DECL(virDomainControllerModelSCSI) VIR_ENUM_DECL(virDomainControllerModelUSB) +VIR_ENUM_DECL(virDomainControllerModelIDE) VIR_ENUM_DECL(virDomainFS) VIR_ENUM_DECL(virDomainFSDriver) VIR_ENUM_DECL(virDomainFSAccessMode) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 9243c5591..616b14f82 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -231,6 +231,8 @@ virDomainControllerFindUnusedIndex; virDomainControllerInsert; virDomainControllerInsertPreAlloced; virDomainControllerIsPSeriesPHB; +virDomainControllerModelIDETypeFromString; +virDomainControllerModelIDETypeToString; virDomainControllerModelPCITypeToString; virDomainControllerModelSCSITypeFromString; virDomainControllerModelSCSITypeToString; -- 2.14.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 4/6] vbox: Add more IStorageController API mappings.
From: Dawid Zamirski <dzamir...@datto.com> This patch 'maps' additonal methods for VBOX API to the libvirt unified vbox API to deal with IStorageController. The 'mapped' methods are: * IStorageController->GetStorageControllerType() * IStorageController->SetStorageControllerType() * IMachine->GetStorageControllers() --- src/vbox/vbox_common.h| 13 + src/vbox/vbox_tmpl.c | 20 src/vbox/vbox_uniformed_api.h | 3 +++ 3 files changed, 36 insertions(+) diff --git a/src/vbox/vbox_common.h b/src/vbox/vbox_common.h index c6da8929d..b08ad1e3e 100644 --- a/src/vbox/vbox_common.h +++ b/src/vbox/vbox_common.h @@ -235,6 +235,19 @@ enum StorageBus StorageBus_SAS = 5 }; +enum StorageControllerType +{ +StorageControllerType_Null = 0, +StorageControllerType_LsiLogic = 1, +StorageControllerType_BusLogic = 2, +StorageControllerType_IntelAhci = 3, +StorageControllerType_PIIX3 = 4, +StorageControllerType_PIIX4 = 5, +StorageControllerType_ICH6 = 6, +StorageControllerType_I82078 = 7, +StorageControllerType_LsiLogicSas = 8 +}; + enum AccessMode { AccessMode_ReadOnly = 1, diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c index ac3b8fa00..6592cbd63 100644 --- a/src/vbox/vbox_tmpl.c +++ b/src/vbox/vbox_tmpl.c @@ -550,6 +550,11 @@ static void* _handleUSBGetDeviceFilters(IUSBCommon *USBCommon) return USBCommon->vtbl->GetDeviceFilters; } +static void* _handleMachineGetStorageControllers(IMachine *machine) +{ +return machine->vtbl->GetStorageControllers; +} + static void* _handleMachineGetMediumAttachments(IMachine *machine) { return machine->vtbl->GetMediumAttachments; @@ -1919,6 +1924,18 @@ _storageControllerGetBus(IStorageController *storageController, PRUint32 *bus) return storageController->vtbl->GetBus(storageController, bus); } +static nsresult +_storageControllerGetControllerType(IStorageController *storageController, PRUint32 *controllerType) +{ +return storageController->vtbl->GetControllerType(storageController, controllerType); +} + +static nsresult +_storageControllerSetControllerType(IStorageController *storageController, PRUint32 controllerType) +{ +return storageController->vtbl->SetControllerType(storageController, controllerType); +} + static nsresult _sharedFolderGetHostPath(ISharedFolder *sharedFolder, PRUnichar **hostPath) { @@ -2268,6 +2285,7 @@ static vboxUniformedArray _UArray = { .handleGetMachines = _handleGetMachines, .handleGetHardDisks = _handleGetHardDisks, .handleUSBGetDeviceFilters = _handleUSBGetDeviceFilters, +.handleMachineGetStorageControllers = _handleMachineGetStorageControllers, .handleMachineGetMediumAttachments = _handleMachineGetMediumAttachments, .handleMachineGetSharedFolders = _handleMachineGetSharedFolders, .handleSnapshotGetChildren = _handleSnapshotGetChildren, @@ -2499,6 +2517,8 @@ static vboxUniformedIMediumAttachment _UIMediumAttachment = { static vboxUniformedIStorageController _UIStorageController = { .GetBus = _storageControllerGetBus, +.GetControllerType = _storageControllerGetControllerType, +.SetControllerType = _storageControllerSetControllerType, }; static vboxUniformedISharedFolder _UISharedFolder = { diff --git a/src/vbox/vbox_uniformed_api.h b/src/vbox/vbox_uniformed_api.h index 2ccaf43e8..dc0b391b2 100644 --- a/src/vbox/vbox_uniformed_api.h +++ b/src/vbox/vbox_uniformed_api.h @@ -135,6 +135,7 @@ typedef struct { void* (*handleGetMachines)(IVirtualBox *vboxObj); void* (*handleGetHardDisks)(IVirtualBox *vboxObj); void* (*handleUSBGetDeviceFilters)(IUSBCommon *USBCommon); +void* (*handleMachineGetStorageControllers)(IMachine *machine); void* (*handleMachineGetMediumAttachments)(IMachine *machine); void* (*handleMachineGetSharedFolders)(IMachine *machine); void* (*handleSnapshotGetChildren)(ISnapshot *snapshot); @@ -410,6 +411,8 @@ typedef struct { /* Functions for IStorageController */ typedef struct { nsresult (*GetBus)(IStorageController *storageController, PRUint32 *bus); +nsresult (*SetControllerType)(IStorageController *storageController, PRUint32 controllerType); +nsresult (*GetControllerType)(IStorageController *storageController, PRUint32 *controllerType); } vboxUniformedIStorageController; /* Functions for ISharedFolder */ -- 2.14.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 0/6] vbox: Improve handling of storage devices.
Hello, This patch series reworks the VirtualBox storage device handling code, brief summary: * Extend libvirt schema to specify IDE controller model as VBox supports changing IDE model to PIIX3, PIIX4 or ICH6 and there are known cases of legacy guest OSes being very sensitive to that. * Make the driver recognize element at define time which allows to specify controller model. Previously the driver was completely ignoring that element. * Allow to create vbox SAS controllers via * Handle removable devices - define and dump devices without media. * Make sure media is closed when undefining VMs. Leaving media unclosed may cause errors when defining VMs pointing at the same local path. Dawid Zamirski (6): vbox: Close media when undefining domains. domain: Allow 'model' attribute for ide controller. docs: Add info about ide model attribute. vbox: Add more IStorageController API mappings. vbox: Process controller definitions from xml. vbox: Update XML dump of storage devices. docs/formatdomain.html.in |3 + docs/schemas/domaincommon.rng | 18 +- src/conf/domain_conf.c|9 + src/conf/domain_conf.h|9 + src/libvirt_private.syms |2 + src/vbox/vbox_common.c| 1212 +++-- src/vbox/vbox_common.h| 21 + src/vbox/vbox_tmpl.c | 87 +-- src/vbox/vbox_uniformed_api.h |3 + 9 files changed, 790 insertions(+), 574 deletions(-) -- 2.14.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 1/6] vbox: Close media when undefining domains.
From: Dawid Zamirski <dzamir...@datto.com> When registering a VM we call OpenMedium on each disk image which adds it to vbox's global media registry. Therefore, we should make sure to call Close when unregistering VM so we cleanup the media registry entries after ourselves - this does not remove disk image files. This follows the behaviour of the VBoxManage unregistervm command. --- src/vbox/vbox_tmpl.c | 24 +++- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c index dffeabde0..ac3b8fa00 100644 --- a/src/vbox/vbox_tmpl.c +++ b/src/vbox/vbox_tmpl.c @@ -378,6 +378,8 @@ _unregisterMachine(vboxDriverPtr data, vboxIID *iid, IMachine **machine) { nsresult rc; vboxArray media = VBOX_ARRAY_INITIALIZER; +size_t i; + rc = data->vboxObj->vtbl->FindMachine(data->vboxObj, iid->value, machine); if (NS_FAILED(rc)) { virReportError(VIR_ERR_NO_DOMAIN, "%s", @@ -385,12 +387,24 @@ _unregisterMachine(vboxDriverPtr data, vboxIID *iid, IMachine **machine) return rc; } -/* We're not interested in the array returned by the Unregister method, - * but in the side effect of unregistering the virtual machine. In order - * to call the Unregister method correctly we need to use the vboxArray - * wrapper here. */ rc = vboxArrayGetWithUintArg(, *machine, (*machine)->vtbl->Unregister, - CleanupMode_DetachAllReturnNone); + CleanupMode_DetachAllReturnHardDisksOnly); + +if (NS_FAILED(rc)) +goto cleanup; + +/* close each medium attached to VM to remove from media registry */ +for (i = 0; i < media.count; i++) { +IMedium *medium = media.items[i]; + +if (!medium) +continue; + +/* it's ok to ignore failure here - e.g. it may be used by another VM */ +medium->vtbl->Close(medium); +} + + cleanup: vboxArrayUnalloc(); return rc; } -- 2.14.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [libvirt-php PATCH v2 00/11] Refactor into smaller components
On Thu, 2017-08-03 at 14:34 -0400, Dawid Zamirski wrote: > As per [1], this patch series splits up the large libvirt-php.c into > components that (attempts) to resemble the structure of the libvirt > project. Each patch successive patch was compile-tested while the > whole > series was verified with "make check" and a simple custom written PHP > script. > > > Changes from v1 [2]: > * rebase on master > * include PHP headers in util.h instead of libvirt-php.h this makes >header inter-dependencies easier to manage/understand > * also test each patch on PHP 5 > > [1] https://www.redhat.com/archives/libvir-list/2017-June/msg00991.ht > ml > [2] https://www.redhat.com/archives/libvir-list/2017-August/msg00046. > html > ping? -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [libvirt-php PATCH v2 01/11] Move PHP version compat macros to utils.h
On Thu, 2017-08-03 at 14:34 -0400, Dawid Zamirski wrote: > Also util now includes all the PHP headers. > --- > src/libvirt-php.c | 1 - > src/libvirt-php.h | 157 +--- > > src/util.h| 174 > ++ > 3 files changed, 175 insertions(+), 157 deletions(-) > > diff --git a/src/libvirt-php.c b/src/libvirt-php.c > index 0e0c620..504a8f2 100644 > --- a/src/libvirt-php.c > +++ b/src/libvirt-php.c > @@ -17,7 +17,6 @@ > #endif > > #include "libvirt-php.h" > -#include "util.h" > #include "vncfunc.h" > #include "sockets.h" > > diff --git a/src/libvirt-php.h b/src/libvirt-php.h > index bfc1934..aa3fbf3 100644 > --- a/src/libvirt-php.h > +++ b/src/libvirt-php.h > @@ -7,7 +7,6 @@ > #ifndef PHP_LIBVIRT_H > #define PHP_LIBVIRT_H 1 > > - > /* Network constants */ > #define VIR_NETWORKS_ACTIVE 1 > #define VIR_NETWORKS_INACTIVE 2 > @@ -28,27 +27,6 @@ > #include "config.h" > #endif > > -#ifdef COMPILE_DL_LIBVIRT > -#undef PACKAGE_BUGREPORT > -#undef PACKAGE_NAME > -#undef PACKAGE_STRING > -#undef PACKAGE_TARNAME > -#undef PACKAGE_URL > -#undef PACKAGE_VERSION > -#include "php.h" > - > -#ifdef ZTS > -#include "TSRM.h" > -#endif > - > -#include "php_ini.h" > -#ifdef EXTWIN > -#include "ext/standard/info.h" > -#else > -#include "standard/info.h" > -#endif > -#endif > - > #ifndef VERSION > #define VERSION "0.5.1" > #define VERSION_MAJOR 0 > @@ -63,6 +41,7 @@ > #include > #include > #include > +#include "util.h" > > #ifndef EXTWIN > #include > @@ -109,139 +88,6 @@ typedef uint64_t arch_uint; > #define UINTx PRIx64 > #endif > > -#if PHP_MAJOR_VERSION >= 7 > -typedef size_t strsize_t; > -typedef zend_resource virt_resource; > -typedef virt_resource *virt_resource_handle; > - > -#define VIRT_RETURN_RESOURCE(_resource) \ > -RETVAL_RES(_resource) > - > -#define VIRT_REGISTER_RESOURCE(_resource, _le_resource) \ > -VIRT_RETURN_RESOURCE(zend_register_resource(_resource, > _le_resource)) > - > -#define VIRT_REGISTER_LIST_RESOURCE(_name) do { \ > -zval zret; \ > -ZVAL_RES(, zend_register_resource(res_##_name, > le_libvirt_##_name)); \ > -add_next_index_zval(return_value, ); \ > -} while(0) > - > -#define VIRT_RESOURCE_HANDLE(_resource) \ > -Z_RES_P(_resource) > - > -#define VIRT_FETCH_RESOURCE(_state, _type, _zval, _name, _le) \ > -if ((_state = (_type)zend_fetch_resource(Z_RES_P(*_zval), _name, > _le)) == NULL) { \ > -RETURN_FALSE; \ > -} > - > -#define VIRT_RETVAL_STRING(_str)\ > -RETVAL_STRING(_str) > -#define VIRT_RETVAL_STRINGL(_str, _len) \ > -RETVAL_STRINGL(_str, _len) > -#define VIRT_RETURN_STRING(_str)\ > -RETURN_STRING(_str) > -#define VIRT_RETURN_STRINGL(_str, _len) \ > -RETURN_STRINGL(_str, _len) > -#define VIRT_ZVAL_STRINGL(_zv, _str, _len) \ > -ZVAL_STRINGL(_zv, _str, _len) > -#define VIRT_ADD_INDEX_STRING(_arg, _idx, _str) \ > -add_index_string(_arg, _idx, _str) > -#define VIRT_ADD_NEXT_INDEX_STRING(_arg, _str) \ > -add_next_index_string(_arg, _str) > -#define VIRT_ADD_ASSOC_STRING(_arg, _key, _str) \ > -add_assoc_string(_arg, _key, _str) > -#define VIRT_ADD_ASSOC_STRING_EX(_arg, _key, _key_len, _value) \ > -add_assoc_string_ex(_arg, _key, _key_len, _value) > - > -#define VIRT_FOREACH(_ht, _pos, _zv) \ > -for (zend_hash_internal_pointer_reset_ex(_ht, &_pos); \ > - (_zv = zend_hash_get_current_data_ex(_ht, &_pos)) != NULL; > \ > - zend_hash_move_forward_ex(_ht, &_pos)) \ > - > -#define VIRT_FOREACH_END(_dummy) > - > -#define VIRT_HASH_CURRENT_KEY_INFO(_ht, _pos, _idx, _info) \ > -do { \ > -zend_string *tmp_key_info; \ > -_info.type = zend_hash_get_current_key_ex(_ht, _key_info, > &_idx, &_pos); \ > -_info.name = ZSTR_VAL(tmp_key_info); \ > -_info.length = ZSTR_LEN(tmp_key_info); \ > -} while(0) > - > -#define VIRT_ARRAY_INIT(_name) do { \ > -zval z##_name; \ > -_name = ##_name; \ > -array_init(_name); \ > -} while(0) > - > -#else /* PHP_MAJOR_VERSION < 7 */ > -typedef int strsize_t; > -typedef long zend_long; > -typedef unsigned long zend_ulong; > -typedef zend_rsrc_list_entry virt_resource; > -typedef long virt_resource_handle; > - > -#define VIRT_RETURN_RESOURCE(_resource) \ > -RETVAL_RESOURCE((long) _resource) > - &g
[libvirt] [libvirt-php PATCH v2 08/11] Split up the bindings for libvirt snapshot API
--- src/Makefile.am| 1 + src/libvirt-php.c | 257 + src/libvirt-php.h | 18 +--- src/libvirt-snapshot.c | 244 ++ src/libvirt-snapshot.h | 58 +++ 5 files changed, 306 insertions(+), 272 deletions(-) create mode 100644 src/libvirt-snapshot.c create mode 100644 src/libvirt-snapshot.h diff --git a/src/Makefile.am b/src/Makefile.am index 32b23cf..1b78011 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -26,6 +26,7 @@ libvirt_php_la_SOURCES = \ libvirt-node.c libvirt-node.h \ libvirt-stream.c libvirt-stream.h \ libvirt-domain.c libvirt-domain.h \ + libvirt-snapshot.c libvirt-snapshot.h \ libvirt-network.c libvirt-network.h \ libvirt-storage.c libvirt-storage.h libvirt_php_la_CFLAGS = \ diff --git a/src/libvirt-php.c b/src/libvirt-php.c index a4108a6..6481a4a 100644 --- a/src/libvirt-php.c +++ b/src/libvirt-php.c @@ -23,6 +23,7 @@ #include "libvirt-node.h" #include "libvirt-stream.h" #include "libvirt-domain.h" +#include "libvirt-snapshot.h" #include "libvirt-network.h" #include "libvirt-storage.h" @@ -39,7 +40,6 @@ const char *features_binaries[] = { NULL }; /* ZEND thread safe per request globals definition */ int le_libvirt_nodedev; -int le_libvirt_snapshot; int le_libvirt_nwfilter; ZEND_BEGIN_ARG_INFO_EX(arginfo_libvirt_connect, 0, 0, 0) @@ -476,13 +476,7 @@ static zend_function_entry libvirt_functions[] = { PHP_FE_LIBVIRT_CONNECTION PHP_FE_LIBVIRT_STREAM PHP_FE_LIBVIRT_DOMAIN -/* Domain snapshot functions */ -PHP_FE(libvirt_domain_has_current_snapshot, arginfo_libvirt_conn_optflags) -PHP_FE(libvirt_domain_snapshot_create, arginfo_libvirt_conn_optflags) -PHP_FE(libvirt_domain_snapshot_get_xml, arginfo_libvirt_conn_optflags) -PHP_FE(libvirt_domain_snapshot_revert, arginfo_libvirt_conn_optflags) -PHP_FE(libvirt_domain_snapshot_delete, arginfo_libvirt_conn_optflags) -PHP_FE(libvirt_domain_snapshot_lookup_by_name, arginfo_libvirt_domain_snapshot_lookup_by_name) +PHP_FE_LIBVIRT_SNAPSHOT PHP_FE_LIBVIRT_STORAGE PHP_FE_LIBVIRT_NETWORK PHP_FE_LIBVIRT_NODE @@ -502,7 +496,6 @@ static zend_function_entry libvirt_functions[] = { PHP_FE(libvirt_nwfilter_lookup_by_uuid_string, arginfo_libvirt_conn_uuid) PHP_FE(libvirt_nwfilter_lookup_by_uuid, arginfo_libvirt_conn_uuid) /* List functions */ -PHP_FE(libvirt_list_domain_snapshots,arginfo_libvirt_conn_optflags) PHP_FE(libvirt_list_nodedevs,arginfo_libvirt_conn_optcap) PHP_FE(libvirt_list_all_nwfilters, arginfo_libvirt_conn) PHP_FE(libvirt_list_nwfilters, arginfo_libvirt_conn) @@ -1212,33 +1205,6 @@ static void php_libvirt_nodedev_dtor(virt_resource *rsrc TSRMLS_DC) } } -/* Destructor for snapshot resource */ -static void php_libvirt_snapshot_dtor(virt_resource *rsrc TSRMLS_DC) -{ -php_libvirt_snapshot *snapshot = (php_libvirt_snapshot *)rsrc->ptr; -int rv = 0; - -if (snapshot != NULL) { -if (snapshot->snapshot != NULL) { -if (!check_resource_allocation(NULL, INT_RESOURCE_SNAPSHOT, snapshot->snapshot TSRMLS_CC)) { -snapshot->snapshot = NULL; -efree(snapshot); -return; -} -rv = virDomainSnapshotFree(snapshot->snapshot); -if (rv != 0) { -DPRINTF("%s: virDomainSnapshotFree(%p) returned %d\n", __FUNCTION__, snapshot->snapshot, rv); -php_error_docref(NULL TSRMLS_CC, E_WARNING, "virDomainSnapshotFree failed with %i on destructor: %s", rv, LIBVIRT_G(last_error)); -} else { -DPRINTF("%s: virDomainSnapshotFree(%p) completed successfully\n", __FUNCTION__, snapshot->snapshot); -resource_change_counter(INT_RESOURCE_SNAPSHOT, snapshot->domain->conn->conn, snapshot->snapshot, 0 TSRMLS_CC); -} -snapshot->snapshot = NULL; -} -efree(snapshot); -} -} - /* Destructor for nwfilter resource */ static void php_libvirt_nwfilter_dtor(virt_resource *rsrc TSRMLS_DC) { @@ -1605,19 +1571,6 @@ PHP_MSHUTDOWN_FUNCTION(libvirt) RETURN_FALSE; \ } while (0) -#define GET_SNAPSHOT_FROM_ARGS(args, ...) \ -do { \ -reset_error(TSRMLS_C); \ -if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, args, __VA_ARGS__) == FAILURE) { \ -set_error("Invalid arguments" TSRMLS_CC); \ -RETURN_FALSE;
[libvirt] [libvirt-php PATCH v2 10/11] Split up the bindings for libvirt NWFilter API
--- src/Makefile.am| 3 +- src/libvirt-nwfilter.c | 415 + src/libvirt-nwfilter.h | 66 src/libvirt-php.c | 445 + src/libvirt-php.h | 28 5 files changed, 487 insertions(+), 470 deletions(-) create mode 100644 src/libvirt-nwfilter.c create mode 100644 src/libvirt-nwfilter.h diff --git a/src/Makefile.am b/src/Makefile.am index 30bebad..707a1e8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -29,7 +29,8 @@ libvirt_php_la_SOURCES = \ libvirt-snapshot.c libvirt-snapshot.h \ libvirt-storage.c libvirt-storage.h \ libvirt-network.c libvirt-network.h \ - libvirt-nodedev.c libvirt-nodedev.h + libvirt-nodedev.c libvirt-nodedev.h \ + libvirt-nwfilter.c libvirt-nwfilter.h libvirt_php_la_CFLAGS = \ $(AM_CFLAGS) \ -DCOMPILE_DL_LIBVIRT=1 diff --git a/src/libvirt-nwfilter.c b/src/libvirt-nwfilter.c new file mode 100644 index 000..87dbb0b --- /dev/null +++ b/src/libvirt-nwfilter.c @@ -0,0 +1,415 @@ +/* + * libvirt-nwfilter.c: The PHP bindings to libvirt NWFilter API + * + * See COPYING for the license of this software + */ + +#include + +#include "libvirt-php.h" +#include "libvirt-nwfilter.h" + +DEBUG_INIT("nwfilter"); + +void +php_libvirt_nwfilter_dtor(virt_resource *rsrc TSRMLS_DC) +{ +php_libvirt_nwfilter *nwfilter = (php_libvirt_nwfilter *) rsrc->ptr; +int rv = 0; + +if (nwfilter != NULL) { +if (nwfilter->nwfilter != NULL) { +if (!check_resource_allocation(NULL, INT_RESOURCE_NWFILTER, nwfilter->nwfilter TSRMLS_CC)) { +nwfilter->nwfilter = NULL; +efree(nwfilter); + +return; +} +rv = virNWFilterFree(nwfilter->nwfilter); +if (rv != 0) { +DPRINTF("%s: virNWFilterFree(%p) returned %d\n", __FUNCTION__, nwfilter->nwfilter, rv); +php_error_docref(NULL TSRMLS_CC, E_WARNING, "virNWFilterFree failed with %i on destructor: %s", rv, LIBVIRT_G(last_error)); +} else { +DPRINTF("%s: virNWFilterFee(%p) completed successfully\n", __FUNCTION__, nwfilter->nwfilter); +resource_change_counter(INT_RESOURCE_NWFILTER, nwfilter->conn->conn, nwfilter->nwfilter, 0 TSRMLS_CC); +} +nwfilter->nwfilter = NULL; +} +efree(nwfilter); +} +} + +/* + * Function name: libvirt_nwfilter_define_xml + * Since version: 0.5.4 + * Description: Function is used to define a new nwfilter based on the XML description + * Arguments: @res [resource]: libvirt connection resource + * @xml [string]: XML string definition of nwfilter to be defined + * Returns: libvirt nwfilter resource of newly defined nwfilter + */ +PHP_FUNCTION(libvirt_nwfilter_define_xml) +{ +php_libvirt_connection *conn = NULL; +php_libvirt_nwfilter *res_nwfilter = NULL; +virNWFilter *nwfilter; +zval *zconn; +char *xml = NULL; +strsize_t xml_len; + +GET_CONNECTION_FROM_ARGS("rs", , , _len); + +if ((nwfilter = virNWFilterDefineXML(conn->conn, xml)) == NULL) { +set_error_if_unset("Cannot define a new NWFilter" TSRMLS_CC); +RETURN_FALSE; +} + +res_nwfilter = (php_libvirt_nwfilter *) emalloc(sizeof(php_libvirt_nwfilter)); +res_nwfilter->nwfilter = nwfilter; +res_nwfilter->conn = conn; + +resource_change_counter(INT_RESOURCE_NWFILTER, conn->conn, +res_nwfilter->nwfilter, 1 TSRMLS_CC); + +VIRT_REGISTER_RESOURCE(res_nwfilter, le_libvirt_nwfilter); +} + +/* + * Function name: libvirt_nwfilter_undefine + * Since version: 0.5.4 + * Description: Function is used to undefine already defined nwfilter + * Arguments: @res [resource]: libvirt nwfilter resource + * Returns: TRUE for success, FALSE on error + */ +PHP_FUNCTION(libvirt_nwfilter_undefine) +{ +php_libvirt_nwfilter *nwfilter = NULL; +zval *znwfilter; + +GET_NWFILTER_FROM_ARGS("r", ); + +if (virNWFilterUndefine(nwfilter->nwfilter) != 0) +RETURN_FALSE; + +RETURN_TRUE; +} + +/* + * Function name: libvirt_nwfilter_get_xml_desc + * Since version: 0.5.4 + * Description: Function is used to get the XML description for the nwfilter + * Arguments: @res [resource]: libvirt nwfilter resource + * @xpath [string]: optional xPath expression string to get just this entry, can be NULL + * Returns: nwfilter XML string or result of xPath expression + */ +PHP_FUNCTION(libvirt_nwfilter_get_xml_desc) +{ +php_libvirt_nwfilter *nwfilter = NULL; +zval *znwfilter; +char *xml = NULL; +char *xpath = NULL; +char *tmp; +strsize_t xpath_len; +int retval = -1; + +GET_NWFILTER_FROM_ARGS("r|s", , , _len); + +if (xpath_len < 1) +xpath = NULL; + +xml =
[libvirt] [libvirt-php PATCH v2 03/11] Split up the bindings for libvirt node API
--- src/Makefile.am | 3 +- src/libvirt-connection.c | 1 + src/libvirt-connection.h | 2 - src/libvirt-node.c | 305 src/libvirt-node.h | 23 src/libvirt-php.c| 322 +-- src/libvirt-php.h| 6 - src/util.h | 25 8 files changed, 358 insertions(+), 329 deletions(-) create mode 100644 src/libvirt-node.c create mode 100644 src/libvirt-node.h diff --git a/src/Makefile.am b/src/Makefile.am index 0819dc6..ba2be62 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -22,7 +22,8 @@ libvirt_php_la_SOURCES = \ vncfunc.c vncfunc.h \ sockets.c sockets.h \ libvirt-php.c libvirt-php.h \ - libvirt-connection.c libvirt-connection.h + libvirt-connection.c libvirt-connection.h \ + libvirt-node.c libvirt-node.h libvirt_php_la_CFLAGS = \ $(AM_CFLAGS) \ -DCOMPILE_DL_LIBVIRT=1 diff --git a/src/libvirt-connection.c b/src/libvirt-connection.c index bcebd44..7e72333 100644 --- a/src/libvirt-connection.c +++ b/src/libvirt-connection.c @@ -6,6 +6,7 @@ #include +#include "libvirt-php.h" #include "libvirt-connection.h" DEBUG_INIT("connection"); diff --git a/src/libvirt-connection.h b/src/libvirt-connection.h index 2c50ec9..0cae5ec 100644 --- a/src/libvirt-connection.h +++ b/src/libvirt-connection.h @@ -7,8 +7,6 @@ #ifndef __LIBVIRT_CONNECTION_H__ # define __LIBVIRT_CONNECTION_H__ -# include "util.h" - # define PHP_LIBVIRT_CONNECTION_RES_NAME "Libvirt connection" # define INT_RESOURCE_CONNECTION 0x01 # define CONNECT_FLAG_SOUNDHW_GET_NAMES 0x01 diff --git a/src/libvirt-node.c b/src/libvirt-node.c new file mode 100644 index 000..e578802 --- /dev/null +++ b/src/libvirt-node.c @@ -0,0 +1,305 @@ +/* + * libvirt-node.c: The PHP bindings to libvirt connection API + * + * See COPYING for the license of this software + */ + +#include + +#include "libvirt-php.h" +#include "libvirt-connection.h" +#include "libvirt-node.h" + +DEBUG_INIT("node"); + +/* + * Function name: libvirt_node_get_info + * Since version: 0.4.1(-1) + * Description: Function is used to get the information about host node, mainly total memory installed, total CPUs installed and model information are useful + * Arguments: @conn [resource]: resource for connection + * Returns: array of node information or FALSE for error + */ +PHP_FUNCTION(libvirt_node_get_info) +{ +virNodeInfo info; +php_libvirt_connection *conn = NULL; +zval *zconn; +int retval; + +GET_CONNECTION_FROM_ARGS("r", ); + +retval = virNodeGetInfo (conn->conn, ); +DPRINTF("%s: virNodeGetInfo returned %d\n", PHPFUNC, retval); +if (retval == -1) +RETURN_FALSE; + +array_init(return_value); +VIRT_ADD_ASSOC_STRING(return_value, "model", info.model); +add_assoc_long(return_value, "memory", (long)info.memory); +add_assoc_long(return_value, "cpus", (long)info.cpus); +add_assoc_long(return_value, "nodes", (long)info.nodes); +add_assoc_long(return_value, "sockets", (long)info.sockets); +add_assoc_long(return_value, "cores", (long)info.cores); +add_assoc_long(return_value, "threads", (long)info.threads); +add_assoc_long(return_value, "mhz", (long)info.mhz); +} + +/* + * Function name: libvirt_node_get_cpu_stats + * Since version: 0.4.6 + * Description: Function is used to get the CPU stats per nodes + * Arguments: @conn [resource]: resource for connection + * @cpunr [int]: CPU number to get information about, defaults to VIR_NODE_CPU_STATS_ALL_CPUS to get information about all CPUs + * Returns: array of node CPU statistics including time (in seconds since UNIX epoch), cpu number and total number of CPUs on node or FALSE for error + */ +PHP_FUNCTION(libvirt_node_get_cpu_stats) +{ +php_libvirt_connection *conn = NULL; +zval *zconn; +int cpuNum = VIR_NODE_CPU_STATS_ALL_CPUS; +virNodeCPUStatsPtr params; +virNodeInfo info; +zend_long cpunr = -1; +int nparams = 0; +int i, j, numCpus; + +GET_CONNECTION_FROM_ARGS("r|l", , ); + +if (virNodeGetInfo(conn->conn, ) != 0) { +set_error("Cannot get number of CPUs" TSRMLS_CC); +RETURN_FALSE; +} + +numCpus = info.cpus; +if (cpunr > numCpus - 1) { +char tmp[256] = { 0 }; +snprintf(tmp, sizeof(tmp), "Invalid CPU number, valid numbers in range 0 to %d or VIR_NODE_CPU_STATS_ALL_CPUS", + numCpus - 1); +set_error(tmp TSRMLS_CC); + +RETURN_FALSE; +} + +cpuNum = (int)cpunr; + +if (virNodeGetCPUStats(conn->conn, cpuNum, NULL, , 0) != 0) { +set_error("Cannot get number of CPU stats" TSRMLS_CC); +RETURN_FALSE; +} + +if (nparams == 0) +RETURN_TRUE; + +DPRINTF("%s: Number of parameters got from virNodeGetCPUStats is %d\n", __FUNCTION__, nparams); + +
[libvirt] [libvirt-php PATCH v2 07/11] Split up the bindings for libvirt storage API
--- src/Makefile.am |3 +- src/libvirt-php.c | 1188 + src/libvirt-php.h | 49 -- src/libvirt-storage.c | 1130 ++ src/libvirt-storage.h | 137 ++ 5 files changed, 1271 insertions(+), 1236 deletions(-) create mode 100644 src/libvirt-storage.c create mode 100644 src/libvirt-storage.h diff --git a/src/Makefile.am b/src/Makefile.am index 4ae01db..32b23cf 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -26,7 +26,8 @@ libvirt_php_la_SOURCES = \ libvirt-node.c libvirt-node.h \ libvirt-stream.c libvirt-stream.h \ libvirt-domain.c libvirt-domain.h \ - libvirt-network.c libvirt-network.h + libvirt-network.c libvirt-network.h \ + libvirt-storage.c libvirt-storage.h libvirt_php_la_CFLAGS = \ $(AM_CFLAGS) \ -DCOMPILE_DL_LIBVIRT=1 diff --git a/src/libvirt-php.c b/src/libvirt-php.c index e3e5554..a4108a6 100644 --- a/src/libvirt-php.c +++ b/src/libvirt-php.c @@ -24,6 +24,7 @@ #include "libvirt-stream.h" #include "libvirt-domain.h" #include "libvirt-network.h" +#include "libvirt-storage.h" DEBUG_INIT("core"); @@ -37,8 +38,6 @@ const char *features_binaries[] = { NULL }; #endif /* ZEND thread safe per request globals definition */ -int le_libvirt_storagepool; -int le_libvirt_volume; int le_libvirt_nodedev; int le_libvirt_snapshot; int le_libvirt_nwfilter; @@ -484,38 +483,7 @@ static zend_function_entry libvirt_functions[] = { PHP_FE(libvirt_domain_snapshot_revert, arginfo_libvirt_conn_optflags) PHP_FE(libvirt_domain_snapshot_delete, arginfo_libvirt_conn_optflags) PHP_FE(libvirt_domain_snapshot_lookup_by_name, arginfo_libvirt_domain_snapshot_lookup_by_name) -/* Storagepool functions */ -PHP_FE(libvirt_storagepool_lookup_by_name, arginfo_libvirt_conn_name) -PHP_FE(libvirt_storagepool_lookup_by_volume, arginfo_libvirt_conn) -PHP_FE(libvirt_storagepool_get_info, arginfo_libvirt_conn) -PHP_FE(libvirt_storagevolume_lookup_by_name, arginfo_libvirt_conn_name) -PHP_FE(libvirt_storagevolume_lookup_by_path, arginfo_libvirt_storagevolume_lookup_by_path) -PHP_FE(libvirt_storagevolume_get_name, arginfo_libvirt_conn) -PHP_FE(libvirt_storagevolume_get_path, arginfo_libvirt_conn) -PHP_FE(libvirt_storagevolume_get_info, arginfo_libvirt_conn) -PHP_FE(libvirt_storagevolume_get_xml_desc, arginfo_libvirt_storagevolume_get_xml_desc) -PHP_FE(libvirt_storagevolume_create_xml, arginfo_libvirt_conn_xml) - PHP_FE(libvirt_storagevolume_create_xml_from,arginfo_libvirt_storagevolume_create_xml_from) -PHP_FE(libvirt_storagevolume_delete, arginfo_libvirt_conn_optflags) -PHP_FE(libvirt_storagevolume_download, arginfo_libvirt_storagevolume_download) -PHP_FE(libvirt_storagevolume_upload, arginfo_libvirt_storagevolume_download) -PHP_FE(libvirt_storagevolume_resize, arginfo_libvirt_storagevolume_resize) -PHP_FE(libvirt_storagepool_get_uuid_string, arginfo_libvirt_conn) -PHP_FE(libvirt_storagepool_get_name, arginfo_libvirt_conn) -PHP_FE(libvirt_storagepool_lookup_by_uuid_string, arginfo_libvirt_conn_uuid) -PHP_FE(libvirt_storagepool_get_xml_desc, arginfo_libvirt_conn_xpath) -PHP_FE(libvirt_storagepool_define_xml, arginfo_libvirt_storagepool_define_xml) -PHP_FE(libvirt_storagepool_undefine, arginfo_libvirt_conn) -PHP_FE(libvirt_storagepool_create, arginfo_libvirt_conn) -PHP_FE(libvirt_storagepool_destroy, arginfo_libvirt_conn) -PHP_FE(libvirt_storagepool_is_active,arginfo_libvirt_conn) -PHP_FE(libvirt_storagepool_get_volume_count, arginfo_libvirt_conn) -PHP_FE(libvirt_storagepool_refresh, arginfo_libvirt_conn_optflags) -PHP_FE(libvirt_storagepool_set_autostart,arginfo_libvirt_conn_flags) -PHP_FE(libvirt_storagepool_get_autostart,arginfo_libvirt_conn) -PHP_FE(libvirt_storagepool_build,arginfo_libvirt_conn) -PHP_FE(libvirt_storagepool_delete, arginfo_libvirt_conn) -/* Network functions */ +PHP_FE_LIBVIRT_STORAGE PHP_FE_LIBVIRT_NETWORK PHP_FE_LIBVIRT_NODE /* Nodedev functions */ @@ -536,10 +504,6 @@ static zend_function_entry libvirt_functions[] = { /* List functions */ PHP_FE(libvirt_list_domain_snapshots,arginfo_libvirt_conn_optflags) PHP_FE(libvirt_list_nodedevs,arginfo_libvirt_conn_optcap) -PHP_FE(libvirt_list_storagepools,arginfo_libvirt_conn) -PHP_FE(libvirt_list_active_storagepools, arginfo_libvirt_conn) -PHP_FE(libvirt_list_inactive_storagepools, arginfo_libvirt_conn) -PHP_FE(libvirt_storagepool_list_volumes, arginfo_libvirt_conn) PHP_FE(libvirt_list_all_nwfilters, arginfo_libvirt_conn) PHP_FE(libvirt_list_nwfilters,
[libvirt] [libvirt-php PATCH v2 01/11] Move PHP version compat macros to utils.h
Also util now includes all the PHP headers. --- src/libvirt-php.c | 1 - src/libvirt-php.h | 157 +--- src/util.h| 174 ++ 3 files changed, 175 insertions(+), 157 deletions(-) diff --git a/src/libvirt-php.c b/src/libvirt-php.c index 0e0c620..504a8f2 100644 --- a/src/libvirt-php.c +++ b/src/libvirt-php.c @@ -17,7 +17,6 @@ #endif #include "libvirt-php.h" -#include "util.h" #include "vncfunc.h" #include "sockets.h" diff --git a/src/libvirt-php.h b/src/libvirt-php.h index bfc1934..aa3fbf3 100644 --- a/src/libvirt-php.h +++ b/src/libvirt-php.h @@ -7,7 +7,6 @@ #ifndef PHP_LIBVIRT_H #define PHP_LIBVIRT_H 1 - /* Network constants */ #define VIR_NETWORKS_ACTIVE 1 #define VIR_NETWORKS_INACTIVE 2 @@ -28,27 +27,6 @@ #include "config.h" #endif -#ifdef COMPILE_DL_LIBVIRT -#undef PACKAGE_BUGREPORT -#undef PACKAGE_NAME -#undef PACKAGE_STRING -#undef PACKAGE_TARNAME -#undef PACKAGE_URL -#undef PACKAGE_VERSION -#include "php.h" - -#ifdef ZTS -#include "TSRM.h" -#endif - -#include "php_ini.h" -#ifdef EXTWIN -#include "ext/standard/info.h" -#else -#include "standard/info.h" -#endif -#endif - #ifndef VERSION #define VERSION "0.5.1" #define VERSION_MAJOR 0 @@ -63,6 +41,7 @@ #include #include #include +#include "util.h" #ifndef EXTWIN #include @@ -109,139 +88,6 @@ typedef uint64_t arch_uint; #define UINTx PRIx64 #endif -#if PHP_MAJOR_VERSION >= 7 -typedef size_t strsize_t; -typedef zend_resource virt_resource; -typedef virt_resource *virt_resource_handle; - -#define VIRT_RETURN_RESOURCE(_resource) \ -RETVAL_RES(_resource) - -#define VIRT_REGISTER_RESOURCE(_resource, _le_resource) \ -VIRT_RETURN_RESOURCE(zend_register_resource(_resource, _le_resource)) - -#define VIRT_REGISTER_LIST_RESOURCE(_name) do { \ -zval zret; \ -ZVAL_RES(, zend_register_resource(res_##_name, le_libvirt_##_name)); \ -add_next_index_zval(return_value, ); \ -} while(0) - -#define VIRT_RESOURCE_HANDLE(_resource) \ -Z_RES_P(_resource) - -#define VIRT_FETCH_RESOURCE(_state, _type, _zval, _name, _le) \ -if ((_state = (_type)zend_fetch_resource(Z_RES_P(*_zval), _name, _le)) == NULL) { \ -RETURN_FALSE; \ -} - -#define VIRT_RETVAL_STRING(_str)\ -RETVAL_STRING(_str) -#define VIRT_RETVAL_STRINGL(_str, _len) \ -RETVAL_STRINGL(_str, _len) -#define VIRT_RETURN_STRING(_str)\ -RETURN_STRING(_str) -#define VIRT_RETURN_STRINGL(_str, _len) \ -RETURN_STRINGL(_str, _len) -#define VIRT_ZVAL_STRINGL(_zv, _str, _len) \ -ZVAL_STRINGL(_zv, _str, _len) -#define VIRT_ADD_INDEX_STRING(_arg, _idx, _str) \ -add_index_string(_arg, _idx, _str) -#define VIRT_ADD_NEXT_INDEX_STRING(_arg, _str) \ -add_next_index_string(_arg, _str) -#define VIRT_ADD_ASSOC_STRING(_arg, _key, _str) \ -add_assoc_string(_arg, _key, _str) -#define VIRT_ADD_ASSOC_STRING_EX(_arg, _key, _key_len, _value) \ -add_assoc_string_ex(_arg, _key, _key_len, _value) - -#define VIRT_FOREACH(_ht, _pos, _zv) \ -for (zend_hash_internal_pointer_reset_ex(_ht, &_pos); \ - (_zv = zend_hash_get_current_data_ex(_ht, &_pos)) != NULL; \ - zend_hash_move_forward_ex(_ht, &_pos)) \ - -#define VIRT_FOREACH_END(_dummy) - -#define VIRT_HASH_CURRENT_KEY_INFO(_ht, _pos, _idx, _info) \ -do { \ -zend_string *tmp_key_info; \ -_info.type = zend_hash_get_current_key_ex(_ht, _key_info, &_idx, &_pos); \ -_info.name = ZSTR_VAL(tmp_key_info); \ -_info.length = ZSTR_LEN(tmp_key_info); \ -} while(0) - -#define VIRT_ARRAY_INIT(_name) do { \ -zval z##_name; \ -_name = ##_name; \ -array_init(_name); \ -} while(0) - -#else /* PHP_MAJOR_VERSION < 7 */ -typedef int strsize_t; -typedef long zend_long; -typedef unsigned long zend_ulong; -typedef zend_rsrc_list_entry virt_resource; -typedef long virt_resource_handle; - -#define VIRT_RETURN_RESOURCE(_resource) \ -RETVAL_RESOURCE((long) _resource) - -#define VIRT_REGISTER_RESOURCE(_resource, _le_resource) \ -ZEND_REGISTER_RESOURCE(return_value, _resource, _le_resource) - -#define VIRT_REGISTER_LIST_RESOURCE(_name) do { \ -zval *zret; \ -ALLOC_INIT_ZVAL(zret); \ -ZEND_REGISTER_RESOURCE(zret, res_##_name, le_libvirt_##_name); \ -add_next_index_zval(return_value, zret); \ -} while(0) - -#define VIRT_RESOURCE_HANDLE(_resource) \ -Z_LVAL_P(_resource) - -#define VIRT_FETCH_RESOURCE(_state, _type, _zval, _name, _le) \ -ZEND_FETCH_RESOURCE(_state, _type, _zval, -1, _name, _le); - -#define VIRT_RETVAL_STRING(_str)\ -RETVAL_STRING(_str, 1) -#define VIRT_RETVAL_STRINGL(_str, _len) \ -RETVAL_STRINGL(_str, _len, 1) -#define VIRT_RETURN_STRING(_str)\ -RETURN_STRING(_str, 1) -#define VIRT_RETURN_STRINGL(_str, _len) \ -RETURN_STRINGL(_str, _len, 1) -#define VIRT_ZVAL_STRINGL(_zv, _str, _len) \ -ZVAL_STRINGL(_zv, _str, _len, 1) -#define
[libvirt] [libvirt-php PATCH v2 06/11] Split up the bindings for libvirt network API
--- src/Makefile.am | 3 +- src/libvirt-network.c | 587 src/libvirt-network.h | 73 ++ src/libvirt-php.c | 610 +- src/libvirt-php.h | 24 +- 5 files changed, 665 insertions(+), 632 deletions(-) create mode 100644 src/libvirt-network.c create mode 100644 src/libvirt-network.h diff --git a/src/Makefile.am b/src/Makefile.am index b8eae3a..4ae01db 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -25,7 +25,8 @@ libvirt_php_la_SOURCES = \ libvirt-connection.c libvirt-connection.h \ libvirt-node.c libvirt-node.h \ libvirt-stream.c libvirt-stream.h \ - libvirt-domain.c libvirt-domain.h + libvirt-domain.c libvirt-domain.h \ + libvirt-network.c libvirt-network.h libvirt_php_la_CFLAGS = \ $(AM_CFLAGS) \ -DCOMPILE_DL_LIBVIRT=1 diff --git a/src/libvirt-network.c b/src/libvirt-network.c new file mode 100644 index 000..464b060 --- /dev/null +++ b/src/libvirt-network.c @@ -0,0 +1,587 @@ +/* + * libvirt-network.c: The PHP bindings to libvirt network API + * + * See COPYING for the license of this software + */ + +#include + +#include "libvirt-php.h" +#include "libvirt-network.h" + +DEBUG_INIT("network"); + +void +php_libvirt_network_dtor(virt_resource *rsrc TSRMLS_DC) +{ +php_libvirt_network *network = (php_libvirt_network *)rsrc->ptr; +int rv = 0; + +if (network != NULL) { +if (network->network != NULL) { +if (!check_resource_allocation(network->conn->conn, INT_RESOURCE_NETWORK, network->network TSRMLS_CC)) { +network->network = NULL; +efree(network); +return; +} +rv = virNetworkFree(network->network); +if (rv != 0) { +DPRINTF("%s: virNetworkFree(%p) returned %d (%s)\n", __FUNCTION__, network->network, rv, LIBVIRT_G(last_error)); +php_error_docref(NULL TSRMLS_CC, E_WARNING, "virStorageVolFree failed with %i on destructor: %s", rv, LIBVIRT_G(last_error)); +} else { +DPRINTF("%s: virNetworkFree(%p) completed successfully\n", __FUNCTION__, network->network); +resource_change_counter(INT_RESOURCE_NETWORK, NULL, network->network, 0 TSRMLS_CC); +} +network->network = NULL; +} +efree(network); +} +} + +/* + * Function name: libvirt_network_define_xml + * Since version: 0.4.2 + * Description: Function is used to define a new virtual network based on the XML description + * Arguments: @res [resource]: libvirt connection resource + * @xml [string]: XML string definition of network to be defined + * Returns: libvirt network resource of newly defined network + */ +PHP_FUNCTION(libvirt_network_define_xml) +{ +php_libvirt_connection *conn = NULL; +php_libvirt_network *res_net = NULL; +virNetwork *net; +zval *zconn; +char *xml = NULL; +strsize_t xml_len; + +GET_CONNECTION_FROM_ARGS("rs", , , _len); + +if ((net = virNetworkDefineXML(conn->conn, xml)) == NULL) { +set_error_if_unset("Cannot define a new network" TSRMLS_CC); +RETURN_FALSE; +} + +res_net = (php_libvirt_network *)emalloc(sizeof(php_libvirt_network)); +res_net->network = net; +res_net->conn = conn; + +DPRINTF("%s: returning %p\n", PHPFUNC, res_net->network); +resource_change_counter(INT_RESOURCE_NETWORK, conn->conn, res_net->network, 1 TSRMLS_CC); + +VIRT_REGISTER_RESOURCE(res_net, le_libvirt_network); +} + +/* + * Function name: libvirt_network_get_xml_desc + * Since version: 0.4.1(-1) + * Description: Function is used to get the XML description for the network + * Arguments: @res [resource]: libvirt network resource + * @xpath [string]: optional xPath expression string to get just this entry, can be NULL + * Returns: network XML string or result of xPath expression + */ +PHP_FUNCTION(libvirt_network_get_xml_desc) +{ +php_libvirt_network *network; +zval *znetwork; +char *xml = NULL; +char *xpath = NULL; +char *tmp; +strsize_t xpath_len; +int retval = -1; + +GET_NETWORK_FROM_ARGS("r|s", , , _len); +if (xpath_len < 1) +xpath = NULL; + +xml = virNetworkGetXMLDesc(network->network, 0); + +if (xml == NULL) { +set_error_if_unset("Cannot get network XML" TSRMLS_CC); +RETURN_FALSE; +} + +tmp = get_string_from_xpath(xml, xpath, NULL, ); +if ((tmp == NULL) || (retval < 0)) { +VIRT_RETVAL_STRING(xml); +} else { +VIRT_RETVAL_STRING(tmp); +} + +free(xml); +free(tmp); +} + +/* + * Function name: libvirt_network_undefine + * Since version: 0.4.2 + * Description: Function is used to undefine already defined network + * Arguments: @res [resource]: libvirt network resource + * Returns:
[libvirt] [libvirt-php PATCH v2 04/11] Split up the bindings for libvirt stream API
--- src/Makefile.am | 3 +- src/libvirt-php.c| 231 +-- src/libvirt-php.h| 15 +--- src/libvirt-stream.c | 230 ++ src/libvirt-stream.h | 39 + 5 files changed, 274 insertions(+), 244 deletions(-) create mode 100644 src/libvirt-stream.c create mode 100644 src/libvirt-stream.h diff --git a/src/Makefile.am b/src/Makefile.am index ba2be62..ddfad41 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -23,7 +23,8 @@ libvirt_php_la_SOURCES = \ sockets.c sockets.h \ libvirt-php.c libvirt-php.h \ libvirt-connection.c libvirt-connection.h \ - libvirt-node.c libvirt-node.h + libvirt-node.c libvirt-node.h \ + libvirt-stream.c libvirt-stream.h libvirt_php_la_CFLAGS = \ $(AM_CFLAGS) \ -DCOMPILE_DL_LIBVIRT=1 diff --git a/src/libvirt-php.c b/src/libvirt-php.c index 6315ec4..c84aaef 100644 --- a/src/libvirt-php.c +++ b/src/libvirt-php.c @@ -21,11 +21,10 @@ #include "sockets.h" #include "libvirt-connection.h" #include "libvirt-node.h" +#include "libvirt-stream.h" DEBUG_INIT("core"); - - #ifndef EXTWIN /* Additional binaries */ const char *features[] = { "screenshot", "create-image", "screenshot-convert", NULL }; @@ -41,7 +40,6 @@ int le_libvirt_storagepool; int le_libvirt_volume; int le_libvirt_network; int le_libvirt_nodedev; -int le_libvirt_stream; int le_libvirt_snapshot; int le_libvirt_nwfilter; @@ -476,15 +474,8 @@ ZEND_END_ARG_INFO() static zend_function_entry libvirt_functions[] = { /* Common functions */ PHP_FE(libvirt_get_last_error, arginfo_libvirt_void) -/* Connect functions */ PHP_FE_LIBVIRT_CONNECTION -/* Stream functions */ -PHP_FE(libvirt_stream_create,arginfo_libvirt_conn) -PHP_FE(libvirt_stream_close, arginfo_libvirt_conn) -PHP_FE(libvirt_stream_abort, arginfo_libvirt_conn) -PHP_FE(libvirt_stream_finish,arginfo_libvirt_conn) -PHP_FE(libvirt_stream_send, arginfo_libvirt_stream_send) -PHP_FE(libvirt_stream_recv, arginfo_libvirt_stream_recv) +PHP_FE_LIBVIRT_STREAM /* Domain functions */ PHP_FE(libvirt_domain_new, arginfo_libvirt_domain_new) PHP_FE(libvirt_domain_new_get_vnc, arginfo_libvirt_void) @@ -1357,33 +1348,6 @@ static void php_libvirt_domain_dtor(virt_resource *rsrc TSRMLS_DC) } } -/* Destructor for stream resource */ -static void php_libvirt_stream_dtor(virt_resource *rsrc TSRMLS_DC) -{ -php_libvirt_stream *stream = (php_libvirt_stream *)rsrc->ptr; -int rv = 0; - -if (stream != NULL) { -if (stream->stream != NULL) { -if (!check_resource_allocation(NULL, INT_RESOURCE_STREAM, stream->stream TSRMLS_CC)) { -stream->stream = NULL; -efree(stream); -return; -} -rv = virStreamFree(stream->stream); -if (rv != 0) { -DPRINTF("%s: virStreamFree(%p) returned %d (%s)\n", __FUNCTION__, stream->stream, rv, LIBVIRT_G(last_error)); -php_error_docref(NULL TSRMLS_CC, E_WARNING, "virStreamFree failed with %i on destructor: %s", rv, LIBVIRT_G(last_error)); -} else { -DPRINTF("%s: virStreamFree(%p) completed successfully\n", __FUNCTION__, stream->stream); -resource_change_counter(INT_RESOURCE_STREAM, NULL, stream->stream, 0 TSRMLS_CC); -} -stream->stream = NULL; -} -efree(stream); -} -} - /* Destructor for storagepool resource */ static void php_libvirt_storagepool_dtor(virt_resource *rsrc TSRMLS_DC) { @@ -3251,197 +3215,6 @@ PHP_FUNCTION(libvirt_domain_lookup_by_uuid_string) } /* - * Function name: libvirt_stream_create - * Since version: 0.5.0 - * Description: Function is used to create new stream from libvirt conn - * Arguments: @res [resource]: libvirt connection resource from libvirt_connect() - * Returns: resource libvirt stream resource - */ -PHP_FUNCTION(libvirt_stream_create) -{ -php_libvirt_connection *conn = NULL; -zval *zconn; -virStreamPtr stream = NULL; -php_libvirt_stream *res_stream; - -if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", ) == FAILURE) -RETURN_FALSE; -VIRT_FETCH_RESOURCE(conn, php_libvirt_connection*, , PHP_LIBVIRT_CONNECTION_RES_NAME, le_libvirt_connection); -if ((conn == NULL) || (conn->conn == NULL)) -RETURN_FALSE; - -stream = virStreamNew(conn->conn, 0); -if (stream == NULL) { -set_error("Cannot create new stream" TSRMLS_CC); -RETURN_FALSE; -} - -res_stream = (php_libvirt_stream *)emalloc(sizeof(php_libvirt_stream)); -res_stream->stream = stream; -res_stream->conn = conn; - -
[libvirt] [libvirt-php PATCH v2 09/11] Split up the bindings for libvirt nodedev API
--- src/Makefile.am | 3 +- src/libvirt-nodedev.c | 340 src/libvirt-nodedev.h | 54 src/libvirt-php.c | 353 +- src/libvirt-php.h | 13 -- 5 files changed, 399 insertions(+), 364 deletions(-) create mode 100644 src/libvirt-nodedev.c create mode 100644 src/libvirt-nodedev.h diff --git a/src/Makefile.am b/src/Makefile.am index 1b78011..30bebad 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -27,8 +27,9 @@ libvirt_php_la_SOURCES = \ libvirt-stream.c libvirt-stream.h \ libvirt-domain.c libvirt-domain.h \ libvirt-snapshot.c libvirt-snapshot.h \ + libvirt-storage.c libvirt-storage.h \ libvirt-network.c libvirt-network.h \ - libvirt-storage.c libvirt-storage.h + libvirt-nodedev.c libvirt-nodedev.h libvirt_php_la_CFLAGS = \ $(AM_CFLAGS) \ -DCOMPILE_DL_LIBVIRT=1 diff --git a/src/libvirt-nodedev.c b/src/libvirt-nodedev.c new file mode 100644 index 000..03f7257 --- /dev/null +++ b/src/libvirt-nodedev.c @@ -0,0 +1,340 @@ +/* + * libvirt-nodedev.c: The PHP bindings to libvirt nodedev API + * + * See COPYING for the license of this software + */ + +#include + +#include "libvirt-php.h" +#include "libvirt-nodedev.h" + +DEBUG_INIT("nodedev"); + +void +php_libvirt_nodedev_dtor(virt_resource *rsrc TSRMLS_DC) +{ +php_libvirt_nodedev *nodedev = (php_libvirt_nodedev *)rsrc->ptr; +int rv = 0; + +if (nodedev != NULL) { +if (nodedev->device != NULL) { +if (!check_resource_allocation(nodedev->conn->conn, INT_RESOURCE_NODEDEV, nodedev->device TSRMLS_CC)) { +nodedev->device = NULL; +efree(nodedev); +return; +} +rv = virNodeDeviceFree(nodedev->device); +if (rv != 0) { +DPRINTF("%s: virNodeDeviceFree(%p) returned %d (%s)\n", __FUNCTION__, nodedev->device, rv, LIBVIRT_G(last_error)); +php_error_docref(NULL TSRMLS_CC, E_WARNING, "virStorageVolFree failed with %i on destructor: %s", rv, LIBVIRT_G(last_error)); +} else { +DPRINTF("%s: virNodeDeviceFree(%p) completed successfully\n", __FUNCTION__, nodedev->device); +resource_change_counter(INT_RESOURCE_NODEDEV, nodedev->conn->conn, nodedev->device, 0 TSRMLS_CC); +} +nodedev->device = NULL; +} +efree(nodedev); +} +} + +/* + * Function name: libvirt_nodedev_get + * Since version: 0.4.1(-1) + * Description: Function is used to get the node device by it's name + * Arguments: @res [resource]: libvirt connection resource + * @name [string]: name of the nodedev to get resource + * Returns: libvirt nodedev resource + */ +PHP_FUNCTION(libvirt_nodedev_get) +{ +php_libvirt_connection *conn = NULL; +php_libvirt_nodedev *res_dev = NULL; +virNodeDevice *dev; +zval *zconn; +char *name; +strsize_t name_len; + +GET_CONNECTION_FROM_ARGS("rs", , , _len); + +if ((dev = virNodeDeviceLookupByName(conn->conn, name)) == NULL) { +set_error("Cannot get find requested node device" TSRMLS_CC); +RETURN_FALSE; +} + +res_dev = (php_libvirt_nodedev *)emalloc(sizeof(php_libvirt_nodedev)); +res_dev->device = dev; +res_dev->conn = conn; + +DPRINTF("%s: returning %p\n", PHPFUNC, res_dev->device); +resource_change_counter(INT_RESOURCE_NODEDEV, conn->conn, res_dev->device, 1 TSRMLS_CC); + +VIRT_REGISTER_RESOURCE(res_dev, le_libvirt_nodedev); +} + +/* + * Function name: libvirt_nodedev_capabilities + * Since version: 0.4.1(-1) + * Description: Function is used to list node devices by capabilities + * Arguments: @res [resource]: libvirt nodedev resource + * Returns: nodedev capabilities array + */ +PHP_FUNCTION(libvirt_nodedev_capabilities) +{ +php_libvirt_nodedev *nodedev = NULL; +zval *znodedev; +int count = -1; +int expectedcount = -1; +char **names; +int i; + +GET_NODEDEV_FROM_ARGS("r", ); + +if ((expectedcount = virNodeDeviceNumOfCaps(nodedev->device)) < 0) +RETURN_FALSE; +names = (char **)emalloc(expectedcount*sizeof(char *)); +count = virNodeDeviceListCaps(nodedev->device, names, expectedcount); +if ((count != expectedcount) || (count < 0)) +RETURN_FALSE; + +array_init(return_value); +for (i = 0; i < count; i++) { +VIRT_ADD_NEXT_INDEX_STRING(return_value, names[i]); +free(names[i]); +} + +efree(names); +} + +/* + * Function name: libvirt_nodedev_get_xml_desc + * Since version: 0.4.1(-1), changed 0.4.2 + * Description: Function is used to get the node device's XML description + * Arguments: @res [resource]: libvirt nodedev resource + * @xpath [string]: optional xPath expression string to get just this entry, can be NULL + *
[libvirt] [libvirt-php PATCH v2 11/11] Fix is_local_connection implementation.
As it was failing when local host is using FQDN for hostnames. The logic to do so follows libvirt's implementation for the same thing. This fixes an issue where unit tests would falsely fail on workstations that have FQDN hostnames. --- src/libvirt-php.c | 38 ++ 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/src/libvirt-php.c b/src/libvirt-php.c index b20d839..ec73034 100644 --- a/src/libvirt-php.c +++ b/src/libvirt-php.c @@ -1145,13 +1145,43 @@ int is_local_connection(virConnectPtr conn) { #ifndef EXTWIN int ret; -char *hostname; +char *lv_hostname = NULL, *result = NULL; char name[1024]; +struct addrinfo hints, *info = NULL; -hostname = virConnectGetHostname(conn); +name[1023] = '\0'; gethostname(name, 1024); -ret = strcmp(name, hostname) == 0; -free(hostname); + +if (strcmp(name, "localhost") == 0) +return 1; + +lv_hostname = virConnectGetHostname(conn); + +/* gethostname gave us FQDN, compare */ +if (strchr(name, '.') && strcmp(name, lv_hostname) == 0) +return 1; + +/* need to get FQDN of the local name */ +memset(, 0, sizeof(hints)); +hints.ai_flags = AI_CANONNAME|AI_CANONIDN; +hints.ai_family = AF_UNSPEC; + +/* could not get FQDN or got localhost, use whatever gethostname gave us */ +if (getaddrinfo(name, NULL, , ) != 0 || +info->ai_canonname == NULL || +strcmp(info->ai_canonname, "localhost") == 0) +result = strdup(name); +else +result = strdup(info->ai_canonname); + +ret = strcmp(result, lv_hostname) == 0; + +freeaddrinfo(info); +if (lv_hostname) +free(lv_hostname); +if (result) +free(result); + return ret; #else // Libvirt daemon doesn't work on Windows systems so always return 0 (FALSE) -- 2.13.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-php PATCH v2 02/11] Split up the bindings for libvirt connection API
* add libvirt-connection.h and libvirt-connection.c * move all libvirt_connect_* function declarations and definitions to above files * other minor adjusments to libvirt-php.h and util.h to keep the code compilable while the code is being moved around. --- src/Makefile.am | 3 +- src/libvirt-connection.c | 885 + src/libvirt-connection.h | 83 + src/libvirt-php.c| 919 +-- src/libvirt-php.h| 95 ++--- src/util.h | 7 - 6 files changed, 1025 insertions(+), 967 deletions(-) create mode 100644 src/libvirt-connection.c create mode 100644 src/libvirt-connection.h diff --git a/src/Makefile.am b/src/Makefile.am index bbee667..0819dc6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -21,7 +21,8 @@ libvirt_php_la_SOURCES = \ util.c util.h \ vncfunc.c vncfunc.h \ sockets.c sockets.h \ - libvirt-php.c libvirt-php.h + libvirt-php.c libvirt-php.h \ + libvirt-connection.c libvirt-connection.h libvirt_php_la_CFLAGS = \ $(AM_CFLAGS) \ -DCOMPILE_DL_LIBVIRT=1 diff --git a/src/libvirt-connection.c b/src/libvirt-connection.c new file mode 100644 index 000..bcebd44 --- /dev/null +++ b/src/libvirt-connection.c @@ -0,0 +1,885 @@ +/* + * libvirt-connection.c: The PHP bindings to libvirt connection API + * + * See COPYING for the license of this software + */ + +#include + +#include "libvirt-connection.h" + +DEBUG_INIT("connection"); + +/* + * Private function name: free_resources_on_connection + * Since version: 0.4.2 + * Description: Function is used to free all the resources assigned to the connection identified by conn + * Arguments: @conn [virConnectPtr]: libvirt connection pointer + * Returns: None + */ +static void +free_resources_on_connection(virConnectPtr conn TSRMLS_DC) +{ +int binding_resources_count = 0; +resource_info *binding_resources; +int i; + +binding_resources_count = LIBVIRT_G(binding_resources_count); +binding_resources = LIBVIRT_G(binding_resources); + +for (i = 0; i < binding_resources_count; i++) { +if ((binding_resources[i].overwrite == 0) && (binding_resources[i].conn == conn)) +free_resource(binding_resources[i].type, binding_resources[i].mem TSRMLS_CC); +} +} + +/* Destructor for connection resource */ +void +php_libvirt_connection_dtor(virt_resource *rsrc TSRMLS_DC) +{ +php_libvirt_connection *conn = (php_libvirt_connection *) rsrc->ptr; +int rv = 0; + +if (conn != NULL) { +if (conn->conn != NULL) { +free_resources_on_connection(conn->conn TSRMLS_CC); + +rv = virConnectClose(conn->conn); +if (rv == -1) { +DPRINTF("%s: virConnectClose(%p) returned %d (%s)\n", __FUNCTION__, conn->conn, rv, LIBVIRT_G(last_error)); +php_error_docref(NULL TSRMLS_CC, E_WARNING, "virConnectClose failed with %i on destructor: %s", rv, LIBVIRT_G(last_error)); +} else { +DPRINTF("%s: virConnectClose(%p) completed successfully\n", __FUNCTION__, conn->conn); +resource_change_counter(INT_RESOURCE_CONNECTION, NULL, conn->conn, 0 TSRMLS_CC); +} +conn->conn = NULL; +} +efree(conn); +} +} + +/* Authentication callback function. + * + * Should receive list of credentials via cbdata and pass the requested one to + * libvirt + */ +static int libvirt_virConnectAuthCallback(virConnectCredentialPtr cred, + unsigned int ncred, void *cbdata) +{ +TSRMLS_FETCH(); + +unsigned int i, j; +php_libvirt_cred_value *creds = (php_libvirt_cred_value *) cbdata; +for (i = 0; i < (unsigned int)ncred; i++) { +DPRINTF("%s: cred %d, type %d, prompt %s challenge %s\n ", __FUNCTION__, i, cred[i].type, cred[i].prompt, cred[i].challenge); +if (creds != NULL) +for (j = 0; j < (unsigned int)creds[0].count; j++) { +if (creds[j].type == cred[i].type) { +cred[i].resultlen = creds[j].resultlen; +cred[i].result = (char *)malloc(creds[j].resultlen + 1); +memset(cred[i].result, 0, creds[j].resultlen + 1); +strncpy(cred[i].result, creds[j].result, creds[j].resultlen); +} +} +DPRINTF("%s: result %s (%d)\n", __FUNCTION__, cred[i].result, cred[i].resultlen); +} + +return 0; +} + +static int libvirt_virConnectCredType[] = { +VIR_CRED_AUTHNAME, +VIR_CRED_ECHOPROMPT, +VIR_CRED_REALM, +VIR_CRED_PASSPHRASE, +VIR_CRED_NOECHOPROMPT, +//VIR_CRED_EXTERNAL, +}; + +/* + * Function name: libvirt_connect + * Since version: 0.4.1(-1) + * Description: libvirt_connect() is used to connect to the specified libvirt daemon using the specified
[libvirt] [libvirt-php PATCH v2 00/11] Refactor into smaller components
As per [1], this patch series splits up the large libvirt-php.c into components that (attempts) to resemble the structure of the libvirt project. Each patch successive patch was compile-tested while the whole series was verified with "make check" and a simple custom written PHP script. Changes from v1 [2]: * rebase on master * include PHP headers in util.h instead of libvirt-php.h this makes header inter-dependencies easier to manage/understand * also test each patch on PHP 5 [1] https://www.redhat.com/archives/libvir-list/2017-June/msg00991.html [2] https://www.redhat.com/archives/libvir-list/2017-August/msg00046.html Dawid Zamirski (11): Move PHP version compat macros to utils.h Split up the bindings for libvirt connection API Split up the bindings for libvirt node API Split up the bindings for libvirt stream API Split up the bindings for libvirt domain API Split up the bindings for libvirt network API Split up the bindings for libvirt storage API Split up the bindings for libvirt snapshot API Split up the bindings for libvirt nodedev API Split up the bindings for libvirt NWFilter API Fix is_local_connection implementation. src/Makefile.am | 11 +- src/libvirt-connection.c | 886 + src/libvirt-connection.h | 81 + src/libvirt-domain.c | 3344 + src/libvirt-domain.h | 208 ++ src/libvirt-network.c| 587 +++ src/libvirt-network.h| 73 + src/libvirt-node.c | 305 ++ src/libvirt-node.h | 23 + src/libvirt-nodedev.c| 340 ++ src/libvirt-nodedev.h| 54 + src/libvirt-nwfilter.c | 415 +++ src/libvirt-nwfilter.h | 66 + src/libvirt-php.c| 9277 -- src/libvirt-php.h| 496 +-- src/libvirt-snapshot.c | 244 ++ src/libvirt-snapshot.h | 58 + src/libvirt-storage.c| 1130 ++ src/libvirt-storage.h| 137 + src/libvirt-stream.c | 230 ++ src/libvirt-stream.h | 39 + src/util.h | 200 +- 22 files changed, 9282 insertions(+), 8922 deletions(-) create mode 100644 src/libvirt-connection.c create mode 100644 src/libvirt-connection.h create mode 100644 src/libvirt-domain.c create mode 100644 src/libvirt-domain.h create mode 100644 src/libvirt-network.c create mode 100644 src/libvirt-network.h create mode 100644 src/libvirt-node.c create mode 100644 src/libvirt-node.h create mode 100644 src/libvirt-nodedev.c create mode 100644 src/libvirt-nodedev.h create mode 100644 src/libvirt-nwfilter.c create mode 100644 src/libvirt-nwfilter.h create mode 100644 src/libvirt-snapshot.c create mode 100644 src/libvirt-snapshot.h create mode 100644 src/libvirt-storage.c create mode 100644 src/libvirt-storage.h create mode 100644 src/libvirt-stream.c create mode 100644 src/libvirt-stream.h -- 2.13.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [libvirt-php PATCH 04/13] Split up the bindings for libvirt connection API
On Thu, 2017-08-03 at 17:02 +0200, Michal Privoznik wrote: > On 08/03/2017 04:58 PM, Dawid Zamirski wrote: > > > > On Thu, 2017-08-03 at 14:27 +0200, Michal Privoznik wrote: > > > On 08/01/2017 11:46 PM, Dawid Zamirski wrote: > > > > * add libvirt-connection.h and libvirt-connection.c > > > > * move all libvirt_connect_* function declarations and > > > > definitions > > > > to > > > > above files > > > > * other minor adjusments to libvirt-php.h and util.h to keep > > > > the > > > > code > > > > compilable while the code is being moved around. > > > > --- > > > > src/Makefile.am | 3 +- > > > > src/libvirt-connection.c | 885 > > > > + > > > > src/libvirt-connection.h | 83 + > > > > src/libvirt-php.c| 919 + > > > > > > > > -- > > > > src/libvirt-php.h| 104 +++--- > > > > src/util.h | 7 - > > > > 6 files changed, 1024 insertions(+), 977 deletions(-) > > > > create mode 100644 src/libvirt-connection.c > > > > create mode 100644 src/libvirt-connection.h > > > > > > Unfortunately, this breaks the build for me. I'm compiling with > > > php5.6. > > > Moreover, as I try to fix the build I wonder if we can put all > > > the > > > php > > > differentiating code into util.h - it'd need to include php.h > > > then > > > (for > > > all those ZEND_* macros and zend_* types). > > > > > > I'm pushing patches 02 and 03 meanwhile. > > > > > > Michal > > > > Sure, I'll do that - it will get rid of the circular dependency > > between > > libvirt-php.h and util.h which I didn't like too much anyway. I'll > > also > > re-test everything on PHP 5 before sending v2. > > Oh cool. I didn't expect you to care that much :-) Feel free to > arrange > headers whatever you like and whatever works. It's more important to > split the libvirt-php.c than anything. Thanks! > > Michal Yep ;-) ... and that's precisely why PHP 5.x does not compile util.h typdefs long to zend_long for PHP < 7, libvirt-php.h uses zend_long but does not include util.h - so yeah it wasn't quite circular dependency but still a mess. Dawid -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [libvirt-php PATCH 04/13] Split up the bindings for libvirt connection API
On Thu, 2017-08-03 at 14:27 +0200, Michal Privoznik wrote: > On 08/01/2017 11:46 PM, Dawid Zamirski wrote: > > * add libvirt-connection.h and libvirt-connection.c > > * move all libvirt_connect_* function declarations and definitions > > to > > above files > > * other minor adjusments to libvirt-php.h and util.h to keep the > > code > > compilable while the code is being moved around. > > --- > > src/Makefile.am | 3 +- > > src/libvirt-connection.c | 885 > > + > > src/libvirt-connection.h | 83 + > > src/libvirt-php.c| 919 + > > -- > > src/libvirt-php.h| 104 +++--- > > src/util.h | 7 - > > 6 files changed, 1024 insertions(+), 977 deletions(-) > > create mode 100644 src/libvirt-connection.c > > create mode 100644 src/libvirt-connection.h > > Unfortunately, this breaks the build for me. I'm compiling with > php5.6. > Moreover, as I try to fix the build I wonder if we can put all the > php > differentiating code into util.h - it'd need to include php.h then > (for > all those ZEND_* macros and zend_* types). > > I'm pushing patches 02 and 03 meanwhile. > > Michal Sure, I'll do that - it will get rid of the circular dependency between libvirt-php.h and util.h which I didn't like too much anyway. I'll also re-test everything on PHP 5 before sending v2. Dawid -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-php PATCH 08/13] Split up the bindings for libvirt network API
--- src/Makefile.am | 3 +- src/libvirt-network.c | 586 src/libvirt-network.h | 73 ++ src/libvirt-php.c | 610 +- src/libvirt-php.h | 24 +- 5 files changed, 664 insertions(+), 632 deletions(-) create mode 100644 src/libvirt-network.c create mode 100644 src/libvirt-network.h diff --git a/src/Makefile.am b/src/Makefile.am index b8eae3a..4ae01db 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -25,7 +25,8 @@ libvirt_php_la_SOURCES = \ libvirt-connection.c libvirt-connection.h \ libvirt-node.c libvirt-node.h \ libvirt-stream.c libvirt-stream.h \ - libvirt-domain.c libvirt-domain.h + libvirt-domain.c libvirt-domain.h \ + libvirt-network.c libvirt-network.h libvirt_php_la_CFLAGS = \ $(AM_CFLAGS) \ -DCOMPILE_DL_LIBVIRT=1 diff --git a/src/libvirt-network.c b/src/libvirt-network.c new file mode 100644 index 000..4316ee2 --- /dev/null +++ b/src/libvirt-network.c @@ -0,0 +1,586 @@ +/* + * libvirt-network.c: The PHP bindings to libvirt network API + * + * See COPYING for the license of this software + */ + +#include + +#include "libvirt-network.h" + +DEBUG_INIT("network"); + +void +php_libvirt_network_dtor(virt_resource *rsrc TSRMLS_DC) +{ +php_libvirt_network *network = (php_libvirt_network *)rsrc->ptr; +int rv = 0; + +if (network != NULL) { +if (network->network != NULL) { +if (!check_resource_allocation(network->conn->conn, INT_RESOURCE_NETWORK, network->network TSRMLS_CC)) { +network->network = NULL; +efree(network); +return; +} +rv = virNetworkFree(network->network); +if (rv != 0) { +DPRINTF("%s: virNetworkFree(%p) returned %d (%s)\n", __FUNCTION__, network->network, rv, LIBVIRT_G(last_error)); +php_error_docref(NULL TSRMLS_CC, E_WARNING, "virStorageVolFree failed with %i on destructor: %s", rv, LIBVIRT_G(last_error)); +} else { +DPRINTF("%s: virNetworkFree(%p) completed successfully\n", __FUNCTION__, network->network); +resource_change_counter(INT_RESOURCE_NETWORK, NULL, network->network, 0 TSRMLS_CC); +} +network->network = NULL; +} +efree(network); +} +} + +/* + * Function name: libvirt_network_define_xml + * Since version: 0.4.2 + * Description: Function is used to define a new virtual network based on the XML description + * Arguments: @res [resource]: libvirt connection resource + * @xml [string]: XML string definition of network to be defined + * Returns: libvirt network resource of newly defined network + */ +PHP_FUNCTION(libvirt_network_define_xml) +{ +php_libvirt_connection *conn = NULL; +php_libvirt_network *res_net = NULL; +virNetwork *net; +zval *zconn; +char *xml = NULL; +strsize_t xml_len; + +GET_CONNECTION_FROM_ARGS("rs", , , _len); + +if ((net = virNetworkDefineXML(conn->conn, xml)) == NULL) { +set_error_if_unset("Cannot define a new network" TSRMLS_CC); +RETURN_FALSE; +} + +res_net = (php_libvirt_network *)emalloc(sizeof(php_libvirt_network)); +res_net->network = net; +res_net->conn = conn; + +DPRINTF("%s: returning %p\n", PHPFUNC, res_net->network); +resource_change_counter(INT_RESOURCE_NETWORK, conn->conn, res_net->network, 1 TSRMLS_CC); + +VIRT_REGISTER_RESOURCE(res_net, le_libvirt_network); +} + +/* + * Function name: libvirt_network_get_xml_desc + * Since version: 0.4.1(-1) + * Description: Function is used to get the XML description for the network + * Arguments: @res [resource]: libvirt network resource + * @xpath [string]: optional xPath expression string to get just this entry, can be NULL + * Returns: network XML string or result of xPath expression + */ +PHP_FUNCTION(libvirt_network_get_xml_desc) +{ +php_libvirt_network *network; +zval *znetwork; +char *xml = NULL; +char *xpath = NULL; +char *tmp; +strsize_t xpath_len; +int retval = -1; + +GET_NETWORK_FROM_ARGS("r|s", , , _len); +if (xpath_len < 1) +xpath = NULL; + +xml = virNetworkGetXMLDesc(network->network, 0); + +if (xml == NULL) { +set_error_if_unset("Cannot get network XML" TSRMLS_CC); +RETURN_FALSE; +} + +tmp = get_string_from_xpath(xml, xpath, NULL, ); +if ((tmp == NULL) || (retval < 0)) { +VIRT_RETVAL_STRING(xml); +} else { +VIRT_RETVAL_STRING(tmp); +} + +free(xml); +free(tmp); +} + +/* + * Function name: libvirt_network_undefine + * Since version: 0.4.2 + * Description: Function is used to undefine already defined network + * Arguments: @res [resource]: libvirt network resource + * Returns: TRUE for success,
[libvirt] [libvirt-php PATCH 03/13] Do not reuse PHPFUNC macro definition
The sockets.c and vncfunc.c should have their own function macros as they are "helper" functions not directly related to PHP bindings themselves. This is simple s/PHPFUNC/SOCKETFUNC/ and s/PHPFUNC/VNCFUNC/ --- src/sockets.c | 44 +-- src/vncfunc.c | 138 +- 2 files changed, 91 insertions(+), 91 deletions(-) diff --git a/src/sockets.c b/src/sockets.c index 9c66257..ef9d154 100644 --- a/src/sockets.c +++ b/src/sockets.c @@ -26,7 +26,7 @@ DEBUG_INIT("sockets"); /* Function macro */ -#define PHPFUNC __FUNCTION__ +#define SOCKETFUNC __FUNCTION__ /* * Private function name: connect_socket @@ -59,7 +59,7 @@ int connect_socket(char *server, char *port, int keepalive, int nodelay, int all server = strdup("localhost"); } -DPRINTF("%s: Connecting to %s:%s\n", PHPFUNC, server, port); +DPRINTF("%s: Connecting to %s:%s\n", SOCKETFUNC, server, port); s = getaddrinfo(server, port, , ); if (s != 0) @@ -80,18 +80,18 @@ int connect_socket(char *server, char *port, int keepalive, int nodelay, int all return -errno; freeaddrinfo(result); -DPRINTF("%s: Socket descriptor #%d opened\n", PHPFUNC, sfd); +DPRINTF("%s: Socket descriptor #%d opened\n", SOCKETFUNC, sfd); if (keepalive) { int on = 1; if (setsockopt(sfd, SOL_SOCKET, SO_KEEPALIVE, , sizeof(on)) < 0) { int err = errno; close(sfd); -DPRINTF("%s: Cannot set keep alive option on socket\n", PHPFUNC); +DPRINTF("%s: Cannot set keep alive option on socket\n", SOCKETFUNC); return -err; } -DPRINTF("%s: Socket #%d set as keepalive socket\n", PHPFUNC, sfd); +DPRINTF("%s: Socket #%d set as keepalive socket\n", SOCKETFUNC, sfd); } if (nodelay) { @@ -99,11 +99,11 @@ int connect_socket(char *server, char *port, int keepalive, int nodelay, int all if (setsockopt(sfd, IPPROTO_TCP, TCP_NODELAY, , sizeof(on)) < 0) { int err = errno; close(sfd); -DPRINTF("%s: Cannot set no delay option on socket\n", PHPFUNC); +DPRINTF("%s: Cannot set no delay option on socket\n", SOCKETFUNC); return -err; } -DPRINTF("%s: Socket #%d set as no delay socket\n", PHPFUNC, sfd); +DPRINTF("%s: Socket #%d set as no delay socket\n", SOCKETFUNC, sfd); } return sfd; @@ -130,7 +130,7 @@ int socket_has_data(int sfd, long maxtime, int ignoremsg) } if (!ignoremsg) -DPRINTF("%s: Checking data on socket %d, timeout = { %ld, %ld }\n", PHPFUNC, sfd, +DPRINTF("%s: Checking data on socket %d, timeout = { %ld, %ld }\n", SOCKETFUNC, sfd, (long)timeout.tv_sec, (long)timeout.tv_usec); FD_ZERO(); @@ -141,12 +141,12 @@ int socket_has_data(int sfd, long maxtime, int ignoremsg) rc = select( sizeof(fds), , NULL, NULL, NULL); if (rc==-1) { -DPRINTF("%s: Select with error %d (%s)\n", PHPFUNC, errno, strerror(-errno)); +DPRINTF("%s: Select with error %d (%s)\n", SOCKETFUNC, errno, strerror(-errno)); return -errno; } if (!ignoremsg) -DPRINTF("%s: Select returned %d\n", PHPFUNC, rc); +DPRINTF("%s: Select returned %d\n", SOCKETFUNC, rc); return (rc == 1); } @@ -165,19 +165,19 @@ void socket_read(int sfd, long length) unsigned char bigbuf[1048576]; if (socket_has_data(sfd, 5, 0) != 1) { -DPRINTF("%s: No data appears to be available\n", PHPFUNC); +DPRINTF("%s: No data appears to be available\n", SOCKETFUNC); return; } if (length == -1) { -DPRINTF("%s: Reading all the data from socket\n", PHPFUNC); +DPRINTF("%s: Reading all the data from socket\n", SOCKETFUNC); while (socket_has_data(sfd, 5, 1) == 1) while ((len = read(sfd, bigbuf, sizeof(bigbuf))) == sizeof(bigbuf)) ; -DPRINTF("%s: Read done ...\n", PHPFUNC); +DPRINTF("%s: Read done ...\n", SOCKETFUNC); return; } -DPRINTF("%s: Reading %ld bytes\n", PHPFUNC, length); +DPRINTF("%s: Reading %ld bytes\n", SOCKETFUNC, length); while (length > 0) { len = read(sfd, bigbuf, sizeof(bigbuf)); @@ -188,9 +188,9 @@ void socket_read(int sfd, long length) if (length && read(sfd, bigbuf, length) != length) -DPRINTF("%s: not all byes read\n", PHPFUNC); +DPRINTF("%s: not all byes read\n", SOCKETFUNC); else -DPRINTF("%s: All bytes read\n", PHPFUNC); +DPRINTF("%s: All bytes read\n", SOCKETFUNC); } /* @@ -218,11 +218,11 @@ int socket_read_and_save(int sfd, char *fn, long length) return -EPERM; if (socket_has_data(sfd, 5, 0) != 1) { -DPRINTF("%s: No data appears to be available\n", PHPFUNC); +DPRINTF("%s: No data appears to be available\n", SOCKETFUNC);
Re: [libvirt] [libvirt-php PATCH 0/7] add bindings for NWFilter APIs
On Mon, 2017-07-31 at 11:31 -0400, Dawid Zamirski wrote: > On Mon, 2017-07-31 at 12:35 +0200, Michal Privoznik wrote: > > Hi Michal, > > I've been busy at work lately with little or no spare time for my OSS > work :-( I've started on this last week but have been dragged away. > I'll try to send the patches by tomorrow morning, which I should > manage > given I won't run into any difficulties. > > Regards, > Dawid Hi Michal, I've finally posted the patches here: https://www.redhat.com/archives/libvir-list/2017-August/msg00046.html Regards, Dawid -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-php PATCH 12/13] Split up the bindings for libvirt NWFilter API
--- src/Makefile.am| 3 +- src/libvirt-nwfilter.c | 414 + src/libvirt-nwfilter.h | 66 src/libvirt-php.c | 445 + src/libvirt-php.h | 28 5 files changed, 486 insertions(+), 470 deletions(-) create mode 100644 src/libvirt-nwfilter.c create mode 100644 src/libvirt-nwfilter.h diff --git a/src/Makefile.am b/src/Makefile.am index 30bebad..707a1e8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -29,7 +29,8 @@ libvirt_php_la_SOURCES = \ libvirt-snapshot.c libvirt-snapshot.h \ libvirt-storage.c libvirt-storage.h \ libvirt-network.c libvirt-network.h \ - libvirt-nodedev.c libvirt-nodedev.h + libvirt-nodedev.c libvirt-nodedev.h \ + libvirt-nwfilter.c libvirt-nwfilter.h libvirt_php_la_CFLAGS = \ $(AM_CFLAGS) \ -DCOMPILE_DL_LIBVIRT=1 diff --git a/src/libvirt-nwfilter.c b/src/libvirt-nwfilter.c new file mode 100644 index 000..f610f40 --- /dev/null +++ b/src/libvirt-nwfilter.c @@ -0,0 +1,414 @@ +/* + * libvirt-nwfilter.c: The PHP bindings to libvirt NWFilter API + * + * See COPYING for the license of this software + */ + +#include + +#include "libvirt-nwfilter.h" + +DEBUG_INIT("nwfilter"); + +void +php_libvirt_nwfilter_dtor(virt_resource *rsrc TSRMLS_DC) +{ +php_libvirt_nwfilter *nwfilter = (php_libvirt_nwfilter *) rsrc->ptr; +int rv = 0; + +if (nwfilter != NULL) { +if (nwfilter->nwfilter != NULL) { +if (!check_resource_allocation(NULL, INT_RESOURCE_NWFILTER, nwfilter->nwfilter TSRMLS_CC)) { +nwfilter->nwfilter = NULL; +efree(nwfilter); + +return; +} +rv = virNWFilterFree(nwfilter->nwfilter); +if (rv != 0) { +DPRINTF("%s: virNWFilterFree(%p) returned %d\n", __FUNCTION__, nwfilter->nwfilter, rv); +php_error_docref(NULL TSRMLS_CC, E_WARNING, "virNWFilterFree failed with %i on destructor: %s", rv, LIBVIRT_G(last_error)); +} else { +DPRINTF("%s: virNWFilterFee(%p) completed successfully\n", __FUNCTION__, nwfilter->nwfilter); +resource_change_counter(INT_RESOURCE_NWFILTER, nwfilter->conn->conn, nwfilter->nwfilter, 0 TSRMLS_CC); +} +nwfilter->nwfilter = NULL; +} +efree(nwfilter); +} +} + +/* + * Function name: libvirt_nwfilter_define_xml + * Since version: 0.5.4 + * Description: Function is used to define a new nwfilter based on the XML description + * Arguments: @res [resource]: libvirt connection resource + * @xml [string]: XML string definition of nwfilter to be defined + * Returns: libvirt nwfilter resource of newly defined nwfilter + */ +PHP_FUNCTION(libvirt_nwfilter_define_xml) +{ +php_libvirt_connection *conn = NULL; +php_libvirt_nwfilter *res_nwfilter = NULL; +virNWFilter *nwfilter; +zval *zconn; +char *xml = NULL; +strsize_t xml_len; + +GET_CONNECTION_FROM_ARGS("rs", , , _len); + +if ((nwfilter = virNWFilterDefineXML(conn->conn, xml)) == NULL) { +set_error_if_unset("Cannot define a new NWFilter" TSRMLS_CC); +RETURN_FALSE; +} + +res_nwfilter = (php_libvirt_nwfilter *) emalloc(sizeof(php_libvirt_nwfilter)); +res_nwfilter->nwfilter = nwfilter; +res_nwfilter->conn = conn; + +resource_change_counter(INT_RESOURCE_NWFILTER, conn->conn, +res_nwfilter->nwfilter, 1 TSRMLS_CC); + +VIRT_REGISTER_RESOURCE(res_nwfilter, le_libvirt_nwfilter); +} + +/* + * Function name: libvirt_nwfilter_undefine + * Since version: 0.5.4 + * Description: Function is used to undefine already defined nwfilter + * Arguments: @res [resource]: libvirt nwfilter resource + * Returns: TRUE for success, FALSE on error + */ +PHP_FUNCTION(libvirt_nwfilter_undefine) +{ +php_libvirt_nwfilter *nwfilter = NULL; +zval *znwfilter; + +GET_NWFILTER_FROM_ARGS("r", ); + +if (virNWFilterUndefine(nwfilter->nwfilter) != 0) +RETURN_FALSE; + +RETURN_TRUE; +} + +/* + * Function name: libvirt_nwfilter_get_xml_desc + * Since version: 0.5.4 + * Description: Function is used to get the XML description for the nwfilter + * Arguments: @res [resource]: libvirt nwfilter resource + * @xpath [string]: optional xPath expression string to get just this entry, can be NULL + * Returns: nwfilter XML string or result of xPath expression + */ +PHP_FUNCTION(libvirt_nwfilter_get_xml_desc) +{ +php_libvirt_nwfilter *nwfilter = NULL; +zval *znwfilter; +char *xml = NULL; +char *xpath = NULL; +char *tmp; +strsize_t xpath_len; +int retval = -1; + +GET_NWFILTER_FROM_ARGS("r|s", , , _len); + +if (xpath_len < 1) +xpath = NULL; + +xml = virNWFilterGetXMLDesc(nwfilter->nwfilter, 0); + +if
[libvirt] [libvirt-php PATCH 10/13] Split up the bindings for libvirt snapshot API
--- src/Makefile.am| 1 + src/libvirt-php.c | 257 + src/libvirt-php.h | 18 +--- src/libvirt-snapshot.c | 243 ++ src/libvirt-snapshot.h | 58 +++ 5 files changed, 305 insertions(+), 272 deletions(-) create mode 100644 src/libvirt-snapshot.c create mode 100644 src/libvirt-snapshot.h diff --git a/src/Makefile.am b/src/Makefile.am index 32b23cf..1b78011 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -26,6 +26,7 @@ libvirt_php_la_SOURCES = \ libvirt-node.c libvirt-node.h \ libvirt-stream.c libvirt-stream.h \ libvirt-domain.c libvirt-domain.h \ + libvirt-snapshot.c libvirt-snapshot.h \ libvirt-network.c libvirt-network.h \ libvirt-storage.c libvirt-storage.h libvirt_php_la_CFLAGS = \ diff --git a/src/libvirt-php.c b/src/libvirt-php.c index 1f0d058..8814e54 100644 --- a/src/libvirt-php.c +++ b/src/libvirt-php.c @@ -24,6 +24,7 @@ #include "libvirt-node.h" #include "libvirt-stream.h" #include "libvirt-domain.h" +#include "libvirt-snapshot.h" #include "libvirt-network.h" #include "libvirt-storage.h" @@ -40,7 +41,6 @@ const char *features_binaries[] = { NULL }; /* ZEND thread safe per request globals definition */ int le_libvirt_nodedev; -int le_libvirt_snapshot; int le_libvirt_nwfilter; ZEND_BEGIN_ARG_INFO_EX(arginfo_libvirt_connect, 0, 0, 0) @@ -477,13 +477,7 @@ static zend_function_entry libvirt_functions[] = { PHP_FE_LIBVIRT_CONNECTION PHP_FE_LIBVIRT_STREAM PHP_FE_LIBVIRT_DOMAIN -/* Domain snapshot functions */ -PHP_FE(libvirt_domain_has_current_snapshot, arginfo_libvirt_conn_optflags) -PHP_FE(libvirt_domain_snapshot_create, arginfo_libvirt_conn_optflags) -PHP_FE(libvirt_domain_snapshot_get_xml, arginfo_libvirt_conn_optflags) -PHP_FE(libvirt_domain_snapshot_revert, arginfo_libvirt_conn_optflags) -PHP_FE(libvirt_domain_snapshot_delete, arginfo_libvirt_conn_optflags) -PHP_FE(libvirt_domain_snapshot_lookup_by_name, arginfo_libvirt_domain_snapshot_lookup_by_name) +PHP_FE_LIBVIRT_SNAPSHOT PHP_FE_LIBVIRT_STORAGE PHP_FE_LIBVIRT_NETWORK PHP_FE_LIBVIRT_NODE @@ -503,7 +497,6 @@ static zend_function_entry libvirt_functions[] = { PHP_FE(libvirt_nwfilter_lookup_by_uuid_string, arginfo_libvirt_conn_uuid) PHP_FE(libvirt_nwfilter_lookup_by_uuid, arginfo_libvirt_conn_uuid) /* List functions */ -PHP_FE(libvirt_list_domain_snapshots,arginfo_libvirt_conn_optflags) PHP_FE(libvirt_list_nodedevs,arginfo_libvirt_conn_optcap) PHP_FE(libvirt_list_all_nwfilters, arginfo_libvirt_conn) PHP_FE(libvirt_list_nwfilters, arginfo_libvirt_conn) @@ -1213,33 +1206,6 @@ static void php_libvirt_nodedev_dtor(virt_resource *rsrc TSRMLS_DC) } } -/* Destructor for snapshot resource */ -static void php_libvirt_snapshot_dtor(virt_resource *rsrc TSRMLS_DC) -{ -php_libvirt_snapshot *snapshot = (php_libvirt_snapshot *)rsrc->ptr; -int rv = 0; - -if (snapshot != NULL) { -if (snapshot->snapshot != NULL) { -if (!check_resource_allocation(NULL, INT_RESOURCE_SNAPSHOT, snapshot->snapshot TSRMLS_CC)) { -snapshot->snapshot = NULL; -efree(snapshot); -return; -} -rv = virDomainSnapshotFree(snapshot->snapshot); -if (rv != 0) { -DPRINTF("%s: virDomainSnapshotFree(%p) returned %d\n", __FUNCTION__, snapshot->snapshot, rv); -php_error_docref(NULL TSRMLS_CC, E_WARNING, "virDomainSnapshotFree failed with %i on destructor: %s", rv, LIBVIRT_G(last_error)); -} else { -DPRINTF("%s: virDomainSnapshotFree(%p) completed successfully\n", __FUNCTION__, snapshot->snapshot); -resource_change_counter(INT_RESOURCE_SNAPSHOT, snapshot->domain->conn->conn, snapshot->snapshot, 0 TSRMLS_CC); -} -snapshot->snapshot = NULL; -} -efree(snapshot); -} -} - /* Destructor for nwfilter resource */ static void php_libvirt_nwfilter_dtor(virt_resource *rsrc TSRMLS_DC) { @@ -1606,19 +1572,6 @@ PHP_MSHUTDOWN_FUNCTION(libvirt) RETURN_FALSE; \ } while (0) -#define GET_SNAPSHOT_FROM_ARGS(args, ...) \ -do { \ -reset_error(TSRMLS_C); \ -if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, args, __VA_ARGS__) == FAILURE) { \ -set_error("Invalid arguments" TSRMLS_CC); \ -RETURN_FALSE;
[libvirt] [libvirt-php PATCH 04/13] Split up the bindings for libvirt connection API
* add libvirt-connection.h and libvirt-connection.c * move all libvirt_connect_* function declarations and definitions to above files * other minor adjusments to libvirt-php.h and util.h to keep the code compilable while the code is being moved around. --- src/Makefile.am | 3 +- src/libvirt-connection.c | 885 + src/libvirt-connection.h | 83 + src/libvirt-php.c| 919 +-- src/libvirt-php.h| 104 +++--- src/util.h | 7 - 6 files changed, 1024 insertions(+), 977 deletions(-) create mode 100644 src/libvirt-connection.c create mode 100644 src/libvirt-connection.h diff --git a/src/Makefile.am b/src/Makefile.am index bbee667..0819dc6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -21,7 +21,8 @@ libvirt_php_la_SOURCES = \ util.c util.h \ vncfunc.c vncfunc.h \ sockets.c sockets.h \ - libvirt-php.c libvirt-php.h + libvirt-php.c libvirt-php.h \ + libvirt-connection.c libvirt-connection.h libvirt_php_la_CFLAGS = \ $(AM_CFLAGS) \ -DCOMPILE_DL_LIBVIRT=1 diff --git a/src/libvirt-connection.c b/src/libvirt-connection.c new file mode 100644 index 000..bcebd44 --- /dev/null +++ b/src/libvirt-connection.c @@ -0,0 +1,885 @@ +/* + * libvirt-connection.c: The PHP bindings to libvirt connection API + * + * See COPYING for the license of this software + */ + +#include + +#include "libvirt-connection.h" + +DEBUG_INIT("connection"); + +/* + * Private function name: free_resources_on_connection + * Since version: 0.4.2 + * Description: Function is used to free all the resources assigned to the connection identified by conn + * Arguments: @conn [virConnectPtr]: libvirt connection pointer + * Returns: None + */ +static void +free_resources_on_connection(virConnectPtr conn TSRMLS_DC) +{ +int binding_resources_count = 0; +resource_info *binding_resources; +int i; + +binding_resources_count = LIBVIRT_G(binding_resources_count); +binding_resources = LIBVIRT_G(binding_resources); + +for (i = 0; i < binding_resources_count; i++) { +if ((binding_resources[i].overwrite == 0) && (binding_resources[i].conn == conn)) +free_resource(binding_resources[i].type, binding_resources[i].mem TSRMLS_CC); +} +} + +/* Destructor for connection resource */ +void +php_libvirt_connection_dtor(virt_resource *rsrc TSRMLS_DC) +{ +php_libvirt_connection *conn = (php_libvirt_connection *) rsrc->ptr; +int rv = 0; + +if (conn != NULL) { +if (conn->conn != NULL) { +free_resources_on_connection(conn->conn TSRMLS_CC); + +rv = virConnectClose(conn->conn); +if (rv == -1) { +DPRINTF("%s: virConnectClose(%p) returned %d (%s)\n", __FUNCTION__, conn->conn, rv, LIBVIRT_G(last_error)); +php_error_docref(NULL TSRMLS_CC, E_WARNING, "virConnectClose failed with %i on destructor: %s", rv, LIBVIRT_G(last_error)); +} else { +DPRINTF("%s: virConnectClose(%p) completed successfully\n", __FUNCTION__, conn->conn); +resource_change_counter(INT_RESOURCE_CONNECTION, NULL, conn->conn, 0 TSRMLS_CC); +} +conn->conn = NULL; +} +efree(conn); +} +} + +/* Authentication callback function. + * + * Should receive list of credentials via cbdata and pass the requested one to + * libvirt + */ +static int libvirt_virConnectAuthCallback(virConnectCredentialPtr cred, + unsigned int ncred, void *cbdata) +{ +TSRMLS_FETCH(); + +unsigned int i, j; +php_libvirt_cred_value *creds = (php_libvirt_cred_value *) cbdata; +for (i = 0; i < (unsigned int)ncred; i++) { +DPRINTF("%s: cred %d, type %d, prompt %s challenge %s\n ", __FUNCTION__, i, cred[i].type, cred[i].prompt, cred[i].challenge); +if (creds != NULL) +for (j = 0; j < (unsigned int)creds[0].count; j++) { +if (creds[j].type == cred[i].type) { +cred[i].resultlen = creds[j].resultlen; +cred[i].result = (char *)malloc(creds[j].resultlen + 1); +memset(cred[i].result, 0, creds[j].resultlen + 1); +strncpy(cred[i].result, creds[j].result, creds[j].resultlen); +} +} +DPRINTF("%s: result %s (%d)\n", __FUNCTION__, cred[i].result, cred[i].resultlen); +} + +return 0; +} + +static int libvirt_virConnectCredType[] = { +VIR_CRED_AUTHNAME, +VIR_CRED_ECHOPROMPT, +VIR_CRED_REALM, +VIR_CRED_PASSPHRASE, +VIR_CRED_NOECHOPROMPT, +//VIR_CRED_EXTERNAL, +}; + +/* + * Function name: libvirt_connect + * Since version: 0.4.1(-1) + * Description: libvirt_connect() is used to connect to the specified libvirt daemon using the
[libvirt] [libvirt-php PATCH 05/13] Split up the bindings for libvirt node API
--- src/Makefile.am| 3 +- src/libvirt-node.c | 304 ++ src/libvirt-node.h | 25 + src/libvirt-php.c | 322 + src/libvirt-php.h | 6 - src/util.h | 25 + 6 files changed, 358 insertions(+), 327 deletions(-) create mode 100644 src/libvirt-node.c create mode 100644 src/libvirt-node.h diff --git a/src/Makefile.am b/src/Makefile.am index 0819dc6..ba2be62 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -22,7 +22,8 @@ libvirt_php_la_SOURCES = \ vncfunc.c vncfunc.h \ sockets.c sockets.h \ libvirt-php.c libvirt-php.h \ - libvirt-connection.c libvirt-connection.h + libvirt-connection.c libvirt-connection.h \ + libvirt-node.c libvirt-node.h libvirt_php_la_CFLAGS = \ $(AM_CFLAGS) \ -DCOMPILE_DL_LIBVIRT=1 diff --git a/src/libvirt-node.c b/src/libvirt-node.c new file mode 100644 index 000..a6de1ac --- /dev/null +++ b/src/libvirt-node.c @@ -0,0 +1,304 @@ +/* + * libvirt-node.c: The PHP bindings to libvirt connection API + * + * See COPYING for the license of this software + */ + +#include + +#include "libvirt-node.h" +#include "libvirt-connection.h" + +DEBUG_INIT("node"); + +/* + * Function name: libvirt_node_get_info + * Since version: 0.4.1(-1) + * Description: Function is used to get the information about host node, mainly total memory installed, total CPUs installed and model information are useful + * Arguments: @conn [resource]: resource for connection + * Returns: array of node information or FALSE for error + */ +PHP_FUNCTION(libvirt_node_get_info) +{ +virNodeInfo info; +php_libvirt_connection *conn = NULL; +zval *zconn; +int retval; + +GET_CONNECTION_FROM_ARGS("r", ); + +retval = virNodeGetInfo (conn->conn, ); +DPRINTF("%s: virNodeGetInfo returned %d\n", PHPFUNC, retval); +if (retval == -1) +RETURN_FALSE; + +array_init(return_value); +VIRT_ADD_ASSOC_STRING(return_value, "model", info.model); +add_assoc_long(return_value, "memory", (long)info.memory); +add_assoc_long(return_value, "cpus", (long)info.cpus); +add_assoc_long(return_value, "nodes", (long)info.nodes); +add_assoc_long(return_value, "sockets", (long)info.sockets); +add_assoc_long(return_value, "cores", (long)info.cores); +add_assoc_long(return_value, "threads", (long)info.threads); +add_assoc_long(return_value, "mhz", (long)info.mhz); +} + +/* + * Function name: libvirt_node_get_cpu_stats + * Since version: 0.4.6 + * Description: Function is used to get the CPU stats per nodes + * Arguments: @conn [resource]: resource for connection + * @cpunr [int]: CPU number to get information about, defaults to VIR_NODE_CPU_STATS_ALL_CPUS to get information about all CPUs + * Returns: array of node CPU statistics including time (in seconds since UNIX epoch), cpu number and total number of CPUs on node or FALSE for error + */ +PHP_FUNCTION(libvirt_node_get_cpu_stats) +{ +php_libvirt_connection *conn = NULL; +zval *zconn; +int cpuNum = VIR_NODE_CPU_STATS_ALL_CPUS; +virNodeCPUStatsPtr params; +virNodeInfo info; +zend_long cpunr = -1; +int nparams = 0; +int i, j, numCpus; + +GET_CONNECTION_FROM_ARGS("r|l", , ); + +if (virNodeGetInfo(conn->conn, ) != 0) { +set_error("Cannot get number of CPUs" TSRMLS_CC); +RETURN_FALSE; +} + +numCpus = info.cpus; +if (cpunr > numCpus - 1) { +char tmp[256] = { 0 }; +snprintf(tmp, sizeof(tmp), "Invalid CPU number, valid numbers in range 0 to %d or VIR_NODE_CPU_STATS_ALL_CPUS", + numCpus - 1); +set_error(tmp TSRMLS_CC); + +RETURN_FALSE; +} + +cpuNum = (int)cpunr; + +if (virNodeGetCPUStats(conn->conn, cpuNum, NULL, , 0) != 0) { +set_error("Cannot get number of CPU stats" TSRMLS_CC); +RETURN_FALSE; +} + +if (nparams == 0) +RETURN_TRUE; + +DPRINTF("%s: Number of parameters got from virNodeGetCPUStats is %d\n", __FUNCTION__, nparams); + +params = (virNodeCPUStatsPtr)calloc(nparams, nparams * sizeof(*params)); + +array_init(return_value); +for (i = 0; i < 2; i++) { +zval *arr; + +if (i > 0) +#ifdef EXTWIN +Sleep(1000); +#else +sleep(1); +#endif + +if (virNodeGetCPUStats(conn->conn, cpuNum, params, , 0) != 0) { +set_error("Unable to get node cpu stats" TSRMLS_CC); +RETURN_FALSE; +} + +VIRT_ARRAY_INIT(arr); + +for (j = 0; j < nparams; j++) { +DPRINTF("%s: Field %s has value of %llu\n", __FUNCTION__, params[j].field, params[j].value); + +add_assoc_long(arr, params[j].field, params[j].value); +} + +add_assoc_long(arr, "time", time(NULL)); + +add_index_zval(return_value, i, arr); +} + +
[libvirt] [libvirt-php PATCH 00/13] Refactor into smaller components
As per [1], this patch series splits up the large libvirt-php.c into components that (attempts) to resemble the structure of the libvirt project. Each patch successive patch was compile-tested while the whole series was verified with "make check" and a simple custom written PHP script. Dawid Zamirski (13): Move PHP version compat macros to utils.h Update AUTHORS file Do not reuse PHPFUNC macro definition Split up the bindings for libvirt connection API Split up the bindings for libvirt node API Split up the bindings for libvirt stream API Split up the bindings for libvirt domain API Split up the bindings for libvirt network API Split up the bindings for libvirt storage API Split up the bindings for libvirt snapshot API Split up the bindings for libvirt nodedev API Split up the bindings for libvirt NWFilter API Fix is_local_connection implementation. AUTHORS | 29 +- src/Makefile.am | 11 +- src/libvirt-connection.c | 885 + src/libvirt-connection.h | 83 + src/libvirt-domain.c | 3339 + src/libvirt-domain.h | 208 ++ src/libvirt-network.c| 586 +++ src/libvirt-network.h| 73 + src/libvirt-node.c | 304 ++ src/libvirt-node.h | 25 + src/libvirt-nodedev.c| 339 ++ src/libvirt-nodedev.h| 54 + src/libvirt-nwfilter.c | 414 +++ src/libvirt-nwfilter.h | 66 + src/libvirt-php.c| 9282 -- src/libvirt-php.h| 492 +-- src/libvirt-snapshot.c | 243 ++ src/libvirt-snapshot.h | 58 + src/libvirt-storage.c| 1129 ++ src/libvirt-storage.h| 138 + src/libvirt-stream.c | 229 ++ src/libvirt-stream.h | 39 + src/sockets.c| 47 +- src/sockets.h|4 - src/util.c |3 - src/util.h | 189 +- src/vncfunc.c| 141 +- src/vncfunc.h|4 - 28 files changed, 9366 insertions(+), 9048 deletions(-) create mode 100644 src/libvirt-connection.c create mode 100644 src/libvirt-connection.h create mode 100644 src/libvirt-domain.c create mode 100644 src/libvirt-domain.h create mode 100644 src/libvirt-network.c create mode 100644 src/libvirt-network.h create mode 100644 src/libvirt-node.c create mode 100644 src/libvirt-node.h create mode 100644 src/libvirt-nodedev.c create mode 100644 src/libvirt-nodedev.h create mode 100644 src/libvirt-nwfilter.c create mode 100644 src/libvirt-nwfilter.h create mode 100644 src/libvirt-snapshot.c create mode 100644 src/libvirt-snapshot.h create mode 100644 src/libvirt-storage.c create mode 100644 src/libvirt-storage.h create mode 100644 src/libvirt-stream.c create mode 100644 src/libvirt-stream.h -- 2.13.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-php PATCH 01/13] Move PHP version compat macros to utils.h
--- src/libvirt-php.h | 144 -- src/util.h| 154 ++ 2 files changed, 164 insertions(+), 134 deletions(-) diff --git a/src/libvirt-php.h b/src/libvirt-php.h index 7962e33..867eb60 100644 --- a/src/libvirt-php.h +++ b/src/libvirt-php.h @@ -119,139 +119,6 @@ typedef uint64_t arch_uint; #define UINTx PRIx64 #endif -#if PHP_MAJOR_VERSION >= 7 -typedef size_t strsize_t; -typedef zend_resource virt_resource; -typedef virt_resource *virt_resource_handle; - -#define VIRT_RETURN_RESOURCE(_resource) \ -RETVAL_RES(_resource) - -#define VIRT_REGISTER_RESOURCE(_resource, _le_resource) \ -VIRT_RETURN_RESOURCE(zend_register_resource(_resource, _le_resource)) - -#define VIRT_REGISTER_LIST_RESOURCE(_name) do { \ -zval zret; \ -ZVAL_RES(, zend_register_resource(res_##_name, le_libvirt_##_name)); \ -add_next_index_zval(return_value, ); \ -} while(0) - -#define VIRT_RESOURCE_HANDLE(_resource) \ -Z_RES_P(_resource) - -#define VIRT_FETCH_RESOURCE(_state, _type, _zval, _name, _le) \ -if ((_state = (_type)zend_fetch_resource(Z_RES_P(*_zval), _name, _le)) == NULL) { \ -RETURN_FALSE; \ -} - -#define VIRT_RETVAL_STRING(_str)\ -RETVAL_STRING(_str) -#define VIRT_RETVAL_STRINGL(_str, _len) \ -RETVAL_STRINGL(_str, _len) -#define VIRT_RETURN_STRING(_str)\ -RETURN_STRING(_str) -#define VIRT_RETURN_STRINGL(_str, _len) \ -RETURN_STRINGL(_str, _len) -#define VIRT_ZVAL_STRINGL(_zv, _str, _len) \ -ZVAL_STRINGL(_zv, _str, _len) -#define VIRT_ADD_INDEX_STRING(_arg, _idx, _str) \ -add_index_string(_arg, _idx, _str) -#define VIRT_ADD_NEXT_INDEX_STRING(_arg, _str) \ -add_next_index_string(_arg, _str) -#define VIRT_ADD_ASSOC_STRING(_arg, _key, _str) \ -add_assoc_string(_arg, _key, _str) -#define VIRT_ADD_ASSOC_STRING_EX(_arg, _key, _key_len, _value) \ -add_assoc_string_ex(_arg, _key, _key_len, _value) - -#define VIRT_FOREACH(_ht, _pos, _zv) \ -for (zend_hash_internal_pointer_reset_ex(_ht, &_pos); \ - (_zv = zend_hash_get_current_data_ex(_ht, &_pos)) != NULL; \ - zend_hash_move_forward_ex(_ht, &_pos)) \ - -#define VIRT_FOREACH_END(_dummy) - -#define VIRT_HASH_CURRENT_KEY_INFO(_ht, _pos, _idx, _info) \ -do { \ -zend_string *tmp_key_info; \ -_info.type = zend_hash_get_current_key_ex(_ht, _key_info, &_idx, &_pos); \ -_info.name = ZSTR_VAL(tmp_key_info); \ -_info.length = ZSTR_LEN(tmp_key_info); \ -} while(0) - -#define VIRT_ARRAY_INIT(_name) do { \ -zval z##_name; \ -_name = ##_name; \ -array_init(_name); \ -} while(0) - -#else /* PHP_MAJOR_VERSION < 7 */ -typedef int strsize_t; -typedef long zend_long; -typedef unsigned long zend_ulong; -typedef zend_rsrc_list_entry virt_resource; -typedef long virt_resource_handle; - -#define VIRT_RETURN_RESOURCE(_resource) \ -RETVAL_RESOURCE((long) _resource) - -#define VIRT_REGISTER_RESOURCE(_resource, _le_resource) \ -ZEND_REGISTER_RESOURCE(return_value, _resource, _le_resource) - -#define VIRT_REGISTER_LIST_RESOURCE(_name) do { \ -zval *zret; \ -ALLOC_INIT_ZVAL(zret); \ -ZEND_REGISTER_RESOURCE(zret, res_##_name, le_libvirt_##_name); \ -add_next_index_zval(return_value, zret); \ -} while(0) - -#define VIRT_RESOURCE_HANDLE(_resource) \ -Z_LVAL_P(_resource) - -#define VIRT_FETCH_RESOURCE(_state, _type, _zval, _name, _le) \ -ZEND_FETCH_RESOURCE(_state, _type, _zval, -1, _name, _le); - -#define VIRT_RETVAL_STRING(_str)\ -RETVAL_STRING(_str, 1) -#define VIRT_RETVAL_STRINGL(_str, _len) \ -RETVAL_STRINGL(_str, _len, 1) -#define VIRT_RETURN_STRING(_str)\ -RETURN_STRING(_str, 1) -#define VIRT_RETURN_STRINGL(_str, _len) \ -RETURN_STRINGL(_str, _len, 1) -#define VIRT_ZVAL_STRINGL(_zv, _str, _len) \ -ZVAL_STRINGL(_zv, _str, _len, 1) -#define VIRT_ADD_INDEX_STRING(_arg, _idx, _str) \ -add_index_string(_arg, _idx, _str, 1) -#define VIRT_ADD_NEXT_INDEX_STRING(_arg, _str) \ -add_next_index_string(_arg, _str, 1) -#define VIRT_ADD_ASSOC_STRING(_arg, _key, _str) \ -add_assoc_string(_arg, _key, _str, 1) -#define VIRT_ADD_ASSOC_STRING_EX(_arg, _key, _key_len, _value) \ -add_assoc_string_ex(_arg, _key, _key_len, _value, 1) - -#define VIRT_FOREACH(_ht, _pos, _zv) \ -{ \ -zval **pzv = &_zv; \ -for (zend_hash_internal_pointer_reset_ex(_ht, &_pos); \ - zend_hash_get_current_data_ex(_ht, (void **) , &_pos) == SUCCESS; \ - zend_hash_move_forward_ex(_ht, &_pos)) { \ -_zv = *pzv; - -#define VIRT_FOREACH_END(_dummy) \ -}} - -#define VIRT_HASH_CURRENT_KEY_INFO(_ht, _pos, _idx, _info) \ -do { \ -_info.type = zend_hash_get_current_key_ex(_ht, &_info.name, &_info.length, &_idx, 0, &_pos); \ -} while(0) - -#define VIRT_ARRAY_INIT(_name) do {\ -ALLOC_INIT_ZVAL(_name); \ -array_init(_name); \ -} while(0) - -#endif /* PHP_MAJOR_VERSION
[libvirt] [libvirt-php PATCH 02/13] Update AUTHORS file
Since the project is about to get a bunch of new header files, it's much easier to maintain just the AUTHORS file. --- AUTHORS | 29 +++-- src/libvirt-php.c | 10 -- src/libvirt-php.h | 10 -- src/sockets.c | 3 --- src/sockets.h | 4 src/util.c| 3 --- src/util.h| 3 --- src/vncfunc.c | 3 --- src/vncfunc.h | 4 9 files changed, 15 insertions(+), 54 deletions(-) diff --git a/AUTHORS b/AUTHORS index 9899c00..52c074d 100644 --- a/AUTHORS +++ b/AUTHORS @@ -3,28 +3,29 @@ Libvirt-php extension Libvirt-php extension is currently maintained and developed by: - Michal Novotny <minov...@redhat.com> (or <mig...@gmail.com>) +Michal Novotny <minov...@redhat.com> (or <mig...@gmail.com>) The original project, called php-libvirt, has been originally developed and maintained by: - Radek Hladik <r.hla...@cybersales.cz> +Radek Hladik <r.hla...@cybersales.cz> who is still contributing to the project with his patches. There are also other people that have contributed to the project: - David King <e-m...@unknown.tld> - Jan-Paul van Burgsteden <e-m...@unknown.tld> - Lyre <liy...@skybility.com> (or <417...@gmail.com>) - Daniel P. Berrange <berra...@redhat.com> - Tiziano Mueller <dev-z...@gentoo.org> - Yukihiro Kawada <warp.kaw...@gmail.com> -Remi Collet <r...@famillecollet.com> -Ivo van den Abeelen <ivovandenabee...@gmail.com> -Tiziano Müller <dev-z...@gentoo.org> -Pavel Odintsov <pavel.odint...@gmail.com> -Tugdual Saunier <tugdual.saun...@gmail.com> - Stefan Kuhn <stefan.k...@foss-group.ch> +David King <e-m...@unknown.tld> +Jan-Paul van Burgsteden <e-m...@unknown.tld> +Lyre <liy...@skybility.com> (or <417...@gmail.com>) +Daniel P. Berrange <berra...@redhat.com> +Tiziano Mueller <dev-z...@gentoo.org> +Yukihiro Kawada <warp.kaw...@gmail.com> +Remi Collet <r...@famillecollet.com> +Ivo van den Abeelen <ivovandenabee...@gmail.com> +Tiziano Müller <dev-z...@gentoo.org> +Pavel Odintsov <pavel.odint...@gmail.com> +Tugdual Saunier <tugdual.saun...@gmail.com> +Stefan Kuhn <stefan.k...@foss-group.ch> +Dawid Zamirski <dzr...@gmail.com> Thanks goes to all of them with big thanks to Tugdual Saunier for various fixes and OS-X compilation support. diff --git a/src/libvirt-php.c b/src/libvirt-php.c index 6734e3b..aea69e7 100644 --- a/src/libvirt-php.c +++ b/src/libvirt-php.c @@ -2,16 +2,6 @@ * libvirt-php.c: Core of the PHP bindings library/module * * See COPYING for the license of this software - * - * Written by: - * Radek Hladik <r.hla...@cybersales.cz> - * Michal Novotny <mig...@gmail.com> - * David King - * Jan-Paul van Burgsteden - * Lyre <liy...@skybility.com> (or <417...@gmail.com>) - * Daniel P. Berrange <berra...@redhat.com> - * Tiziano Mueller <dev-z...@gentoo.org> - * Yukihiro Kawada <warp.kaw...@gmail.com> */ #ifdef _MSC_VER diff --git a/src/libvirt-php.h b/src/libvirt-php.h index 867eb60..66be53a 100644 --- a/src/libvirt-php.h +++ b/src/libvirt-php.h @@ -2,16 +2,6 @@ * libvirt-php.h: libvirt PHP bindings header file * * See COPYING for the license of this software - * - * Written by: - * Radek Hladik <r.hla...@cybersales.cz> - * Michal Novotny <minov...@redhat.com> - * David King - * Jan-Paul van Burgsteden - * Lyre <liy...@skybility.com> (or <417...@gmail.com>) - * Daniel P. Berrange <berra...@redhat.com> - * Tiziano Mueller <dev-z...@gentoo.org> - * Yukihiro Kawada <warp.kaw...@gmail.com> */ #ifndef PHP_LIBVIRT_H diff --git a/src/sockets.c b/src/sockets.c index 0a3e3c2..9c66257 100644 --- a/src/sockets.c +++ b/src/sockets.c @@ -2,9 +2,6 @@ * sockets.c: Socket functions for libvirt-php * * See COPYING for the license of this software - * - * Written by: - * Michal Novotny <minov...@redhat.com> */ #include diff --git a/src/sockets.h b/src/sockets.h index ce7a668..a9645a9 100644 --- a/src/sockets.h +++ b/src/sockets.h @@ -2,10 +2,6 @@ * sockets.h: Socket functions for libvirt-php * * See COPYING for the license of this software - * - * Written by: - * Michal Novotny <minov...@redhat.com> - * Michal Privoznik <mpriv...@redhat.com> */ #ifndef __SOCKETS_H__ diff --git a/src/util.c b/src/util.c index 53096ae..cb8ccbe 100644 --- a/src/util.c +++ b/src/util.c @@ -2,9 +2,6 @@ * util.c: common, generic utility functions * * See COPYING for the license of this software - * - * Written by: - * Michal Privoznik <mpriv...@redhat.com> */ #include diff --git a/src/util
Re: [libvirt] [libvirt-php PATCH 00/13] Refactor into smaller components
On Tue, 2017-08-01 at 17:46 -0400, Dawid Zamirski wrote: > As per [1], this patch series splits up the large libvirt-php.c into > components that (attempts) to resemble the structure of the libvirt > project. Each patch successive patch was compile-tested while the > whole > series was verified with "make check" and a simple custom written PHP > script. Missed the link for [1] in cover letter: [1] https://www.redhat.com/archives/libvir-list/2017-June/msg00991.html -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-php PATCH 11/13] Split up the bindings for libvirt nodedev API
--- src/Makefile.am | 3 +- src/libvirt-nodedev.c | 339 src/libvirt-nodedev.h | 54 src/libvirt-php.c | 353 +- src/libvirt-php.h | 13 -- 5 files changed, 398 insertions(+), 364 deletions(-) create mode 100644 src/libvirt-nodedev.c create mode 100644 src/libvirt-nodedev.h diff --git a/src/Makefile.am b/src/Makefile.am index 1b78011..30bebad 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -27,8 +27,9 @@ libvirt_php_la_SOURCES = \ libvirt-stream.c libvirt-stream.h \ libvirt-domain.c libvirt-domain.h \ libvirt-snapshot.c libvirt-snapshot.h \ + libvirt-storage.c libvirt-storage.h \ libvirt-network.c libvirt-network.h \ - libvirt-storage.c libvirt-storage.h + libvirt-nodedev.c libvirt-nodedev.h libvirt_php_la_CFLAGS = \ $(AM_CFLAGS) \ -DCOMPILE_DL_LIBVIRT=1 diff --git a/src/libvirt-nodedev.c b/src/libvirt-nodedev.c new file mode 100644 index 000..06a420d --- /dev/null +++ b/src/libvirt-nodedev.c @@ -0,0 +1,339 @@ +/* + * libvirt-nodedev.c: The PHP bindings to libvirt nodedev API + * + * See COPYING for the license of this software + */ + +#include + +#include "libvirt-nodedev.h" + +DEBUG_INIT("nodedev"); + +void +php_libvirt_nodedev_dtor(virt_resource *rsrc TSRMLS_DC) +{ +php_libvirt_nodedev *nodedev = (php_libvirt_nodedev *)rsrc->ptr; +int rv = 0; + +if (nodedev != NULL) { +if (nodedev->device != NULL) { +if (!check_resource_allocation(nodedev->conn->conn, INT_RESOURCE_NODEDEV, nodedev->device TSRMLS_CC)) { +nodedev->device = NULL; +efree(nodedev); +return; +} +rv = virNodeDeviceFree(nodedev->device); +if (rv != 0) { +DPRINTF("%s: virNodeDeviceFree(%p) returned %d (%s)\n", __FUNCTION__, nodedev->device, rv, LIBVIRT_G(last_error)); +php_error_docref(NULL TSRMLS_CC, E_WARNING, "virStorageVolFree failed with %i on destructor: %s", rv, LIBVIRT_G(last_error)); +} else { +DPRINTF("%s: virNodeDeviceFree(%p) completed successfully\n", __FUNCTION__, nodedev->device); +resource_change_counter(INT_RESOURCE_NODEDEV, nodedev->conn->conn, nodedev->device, 0 TSRMLS_CC); +} +nodedev->device = NULL; +} +efree(nodedev); +} +} + +/* + * Function name: libvirt_nodedev_get + * Since version: 0.4.1(-1) + * Description: Function is used to get the node device by it's name + * Arguments: @res [resource]: libvirt connection resource + * @name [string]: name of the nodedev to get resource + * Returns: libvirt nodedev resource + */ +PHP_FUNCTION(libvirt_nodedev_get) +{ +php_libvirt_connection *conn = NULL; +php_libvirt_nodedev *res_dev = NULL; +virNodeDevice *dev; +zval *zconn; +char *name; +strsize_t name_len; + +GET_CONNECTION_FROM_ARGS("rs", , , _len); + +if ((dev = virNodeDeviceLookupByName(conn->conn, name)) == NULL) { +set_error("Cannot get find requested node device" TSRMLS_CC); +RETURN_FALSE; +} + +res_dev = (php_libvirt_nodedev *)emalloc(sizeof(php_libvirt_nodedev)); +res_dev->device = dev; +res_dev->conn = conn; + +DPRINTF("%s: returning %p\n", PHPFUNC, res_dev->device); +resource_change_counter(INT_RESOURCE_NODEDEV, conn->conn, res_dev->device, 1 TSRMLS_CC); + +VIRT_REGISTER_RESOURCE(res_dev, le_libvirt_nodedev); +} + +/* + * Function name: libvirt_nodedev_capabilities + * Since version: 0.4.1(-1) + * Description: Function is used to list node devices by capabilities + * Arguments: @res [resource]: libvirt nodedev resource + * Returns: nodedev capabilities array + */ +PHP_FUNCTION(libvirt_nodedev_capabilities) +{ +php_libvirt_nodedev *nodedev = NULL; +zval *znodedev; +int count = -1; +int expectedcount = -1; +char **names; +int i; + +GET_NODEDEV_FROM_ARGS("r", ); + +if ((expectedcount = virNodeDeviceNumOfCaps(nodedev->device)) < 0) +RETURN_FALSE; +names = (char **)emalloc(expectedcount*sizeof(char *)); +count = virNodeDeviceListCaps(nodedev->device, names, expectedcount); +if ((count != expectedcount) || (count < 0)) +RETURN_FALSE; + +array_init(return_value); +for (i = 0; i < count; i++) { +VIRT_ADD_NEXT_INDEX_STRING(return_value, names[i]); +free(names[i]); +} + +efree(names); +} + +/* + * Function name: libvirt_nodedev_get_xml_desc + * Since version: 0.4.1(-1), changed 0.4.2 + * Description: Function is used to get the node device's XML description + * Arguments: @res [resource]: libvirt nodedev resource + * @xpath [string]: optional xPath expression string to get just this entry, can be NULL + * Returns: nodedev XML
[libvirt] [libvirt-php PATCH 09/13] Split up the bindings for libvirt storage API
--- src/Makefile.am |3 +- src/libvirt-php.c | 1188 + src/libvirt-php.h | 49 -- src/libvirt-storage.c | 1129 ++ src/libvirt-storage.h | 138 ++ 5 files changed, 1271 insertions(+), 1236 deletions(-) create mode 100644 src/libvirt-storage.c create mode 100644 src/libvirt-storage.h diff --git a/src/Makefile.am b/src/Makefile.am index 4ae01db..32b23cf 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -26,7 +26,8 @@ libvirt_php_la_SOURCES = \ libvirt-node.c libvirt-node.h \ libvirt-stream.c libvirt-stream.h \ libvirt-domain.c libvirt-domain.h \ - libvirt-network.c libvirt-network.h + libvirt-network.c libvirt-network.h \ + libvirt-storage.c libvirt-storage.h libvirt_php_la_CFLAGS = \ $(AM_CFLAGS) \ -DCOMPILE_DL_LIBVIRT=1 diff --git a/src/libvirt-php.c b/src/libvirt-php.c index 9e43a71..1f0d058 100644 --- a/src/libvirt-php.c +++ b/src/libvirt-php.c @@ -25,6 +25,7 @@ #include "libvirt-stream.h" #include "libvirt-domain.h" #include "libvirt-network.h" +#include "libvirt-storage.h" DEBUG_INIT("core"); @@ -38,8 +39,6 @@ const char *features_binaries[] = { NULL }; #endif /* ZEND thread safe per request globals definition */ -int le_libvirt_storagepool; -int le_libvirt_volume; int le_libvirt_nodedev; int le_libvirt_snapshot; int le_libvirt_nwfilter; @@ -485,38 +484,7 @@ static zend_function_entry libvirt_functions[] = { PHP_FE(libvirt_domain_snapshot_revert, arginfo_libvirt_conn_optflags) PHP_FE(libvirt_domain_snapshot_delete, arginfo_libvirt_conn_optflags) PHP_FE(libvirt_domain_snapshot_lookup_by_name, arginfo_libvirt_domain_snapshot_lookup_by_name) -/* Storagepool functions */ -PHP_FE(libvirt_storagepool_lookup_by_name, arginfo_libvirt_conn_name) -PHP_FE(libvirt_storagepool_lookup_by_volume, arginfo_libvirt_conn) -PHP_FE(libvirt_storagepool_get_info, arginfo_libvirt_conn) -PHP_FE(libvirt_storagevolume_lookup_by_name, arginfo_libvirt_conn_name) -PHP_FE(libvirt_storagevolume_lookup_by_path, arginfo_libvirt_storagevolume_lookup_by_path) -PHP_FE(libvirt_storagevolume_get_name, arginfo_libvirt_conn) -PHP_FE(libvirt_storagevolume_get_path, arginfo_libvirt_conn) -PHP_FE(libvirt_storagevolume_get_info, arginfo_libvirt_conn) -PHP_FE(libvirt_storagevolume_get_xml_desc, arginfo_libvirt_storagevolume_get_xml_desc) -PHP_FE(libvirt_storagevolume_create_xml, arginfo_libvirt_conn_xml) - PHP_FE(libvirt_storagevolume_create_xml_from,arginfo_libvirt_storagevolume_create_xml_from) -PHP_FE(libvirt_storagevolume_delete, arginfo_libvirt_conn_optflags) -PHP_FE(libvirt_storagevolume_download, arginfo_libvirt_storagevolume_download) -PHP_FE(libvirt_storagevolume_upload, arginfo_libvirt_storagevolume_download) -PHP_FE(libvirt_storagevolume_resize, arginfo_libvirt_storagevolume_resize) -PHP_FE(libvirt_storagepool_get_uuid_string, arginfo_libvirt_conn) -PHP_FE(libvirt_storagepool_get_name, arginfo_libvirt_conn) -PHP_FE(libvirt_storagepool_lookup_by_uuid_string, arginfo_libvirt_conn_uuid) -PHP_FE(libvirt_storagepool_get_xml_desc, arginfo_libvirt_conn_xpath) -PHP_FE(libvirt_storagepool_define_xml, arginfo_libvirt_storagepool_define_xml) -PHP_FE(libvirt_storagepool_undefine, arginfo_libvirt_conn) -PHP_FE(libvirt_storagepool_create, arginfo_libvirt_conn) -PHP_FE(libvirt_storagepool_destroy, arginfo_libvirt_conn) -PHP_FE(libvirt_storagepool_is_active,arginfo_libvirt_conn) -PHP_FE(libvirt_storagepool_get_volume_count, arginfo_libvirt_conn) -PHP_FE(libvirt_storagepool_refresh, arginfo_libvirt_conn_optflags) -PHP_FE(libvirt_storagepool_set_autostart,arginfo_libvirt_conn_flags) -PHP_FE(libvirt_storagepool_get_autostart,arginfo_libvirt_conn) -PHP_FE(libvirt_storagepool_build,arginfo_libvirt_conn) -PHP_FE(libvirt_storagepool_delete, arginfo_libvirt_conn) -/* Network functions */ +PHP_FE_LIBVIRT_STORAGE PHP_FE_LIBVIRT_NETWORK PHP_FE_LIBVIRT_NODE /* Nodedev functions */ @@ -537,10 +505,6 @@ static zend_function_entry libvirt_functions[] = { /* List functions */ PHP_FE(libvirt_list_domain_snapshots,arginfo_libvirt_conn_optflags) PHP_FE(libvirt_list_nodedevs,arginfo_libvirt_conn_optcap) -PHP_FE(libvirt_list_storagepools,arginfo_libvirt_conn) -PHP_FE(libvirt_list_active_storagepools, arginfo_libvirt_conn) -PHP_FE(libvirt_list_inactive_storagepools, arginfo_libvirt_conn) -PHP_FE(libvirt_storagepool_list_volumes, arginfo_libvirt_conn) PHP_FE(libvirt_list_all_nwfilters, arginfo_libvirt_conn) PHP_FE(libvirt_list_nwfilters,
[libvirt] [libvirt-php PATCH 13/13] Fix is_local_connection implementation.
As it was failing when local host is using FQDN for hostnames. The logic to do so follows libvirt's implementation for the same thing. This fixes an issue where unit tests would falsely fail on workstations that have FQDN hostnames. --- src/libvirt-php.c | 38 ++ 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/src/libvirt-php.c b/src/libvirt-php.c index 4ef06b2..c019d99 100644 --- a/src/libvirt-php.c +++ b/src/libvirt-php.c @@ -1146,13 +1146,43 @@ int is_local_connection(virConnectPtr conn) { #ifndef EXTWIN int ret; -char *hostname; +char *lv_hostname = NULL, *result = NULL; char name[1024]; +struct addrinfo hints, *info = NULL; -hostname = virConnectGetHostname(conn); +name[1023] = '\0'; gethostname(name, 1024); -ret = strcmp(name, hostname) == 0; -free(hostname); + +if (strcmp(name, "localhost") == 0) +return 1; + +lv_hostname = virConnectGetHostname(conn); + +/* gethostname gave us FQDN, compare */ +if (strchr(name, '.') && strcmp(name, lv_hostname) == 0) +return 1; + +/* need to get FQDN of the local name */ +memset(, 0, sizeof(hints)); +hints.ai_flags = AI_CANONNAME|AI_CANONIDN; +hints.ai_family = AF_UNSPEC; + +/* could not get FQDN or got localhost, use whatever gethostname gave us */ +if (getaddrinfo(name, NULL, , ) != 0 || +info->ai_canonname == NULL || +strcmp(info->ai_canonname, "localhost") == 0) +result = strdup(name); +else +result = strdup(info->ai_canonname); + +ret = strcmp(result, lv_hostname) == 0; + +freeaddrinfo(info); +if (lv_hostname) +free(lv_hostname); +if (result) +free(result); + return ret; #else // Libvirt daemon doesn't work on Windows systems so always return 0 (FALSE) -- 2.13.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list