From nobody Fri May 16 03:59:15 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1501624273022803.7034992005271; Tue, 1 Aug 2017 14:51:13 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 2168616AB07; Tue, 1 Aug 2017 21:51:11 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id C125B6D2A9; Tue, 1 Aug 2017 21:51:10 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 18899180B467; Tue, 1 Aug 2017 21:51:10 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v71LkS8V007865 for ; Tue, 1 Aug 2017 17:46:28 -0400 Received: by smtp.corp.redhat.com (Postfix) id AF3B160462; Tue, 1 Aug 2017 21:46:28 +0000 (UTC) Received: from mx1.redhat.com (ext-mx02.extmail.prod.ext.phx2.redhat.com [10.5.110.26]) by smtp.corp.redhat.com (Postfix) with ESMTPS id A51A818A4F for ; Tue, 1 Aug 2017 21:46:28 +0000 (UTC) Received: from mail-qk0-f174.google.com (mail-qk0-f174.google.com [209.85.220.174]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 7E9D1A4FAD for ; Tue, 1 Aug 2017 21:46:20 +0000 (UTC) Received: by mail-qk0-f174.google.com with SMTP id d136so17050000qkg.3 for ; Tue, 01 Aug 2017 14:46:20 -0700 (PDT) Received: from dawid-fedora.datto.lan ([47.19.105.250]) by smtp.gmail.com with ESMTPSA id f56sm1892090qta.79.2017.08.01.14.46.17 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 01 Aug 2017 14:46:17 -0700 (PDT) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 2168616AB07 Authentication-Results: ext-mx03.extmail.prod.ext.phx2.redhat.com; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ext-mx03.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=libvir-list-bounces@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 2168616AB07 Authentication-Results: mx1.redhat.com; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="KON73yHb" DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 7E9D1A4FAD Authentication-Results: ext-mx02.extmail.prod.ext.phx2.redhat.com; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ext-mx02.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=dzrudy@gmail.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 7E9D1A4FAD DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references; bh=PCrm24RaTkJz7Cu6+e214CMaCwXD7wNTx2vhV/kWlF8=; b=KON73yHb4AfUNiKXMTTVIAsGhC8AVWkEO9Jtzb5Vug1KT8oMl5NpBL36SqZJSck3NH WU4fv2UJ4UpTUI5KWWyNA3eI2zyIwlwUM9LC4da0C95encwwvRCgo6P/aEf5ficKAGoK W8kHwpy9oM+tI5nD9lhOg35BnmfNfYPrkM/x1KnygSP15BoCOAYVnilQzpDOoEP8JiVm J6qtSR7zHqkxPZ4Kq1PpqCwWghzediez/nG1mDU7xqRx8wx054zKB26aQNZ4FeSxnL+Q pwyXLwu2MlYaIPNy44rnNvuwMhWJ5o53wvU8abqVBZsnH/mnh6XSZyeBMdbklReOSmAe nTCg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=PCrm24RaTkJz7Cu6+e214CMaCwXD7wNTx2vhV/kWlF8=; b=ifGBFBJBmzb4dblDQIJXm1vD7tJY6DE4Aa61VXcTDvPZvRDP82JOkAe8fKx06AKmRf pVtRSpIrZ8W9SI8yRd0jOsDH+1XDTdMU3YzMM+7v/f3Dkj+CSeQOC4KQ7wDRcUhbLK3O 2mZn2UtsvvnQ2ilwJ91FKj9vmIvBz9Y0+95Xgex/Q5tGmtCrscU1oz0Z6nU7JX6gXmvO V6ZnXh/QrpTo9B5e1HBxtTvrRhGvb+dP+pH8aTvPsFIjcvUdY5lPVHp+Fz/MUvxySmOV Oq1XN8QV1NWdam1wmQHpk9bjWfbBK06kuYo3boizaOOc4AO3BCzVOfndRDoT1a6ZVSWz jTOg== X-Gm-Message-State: AHYfb5gzWjJo8rMSxzY6doNjNw7A0Sp7+ro1jvr8sRze2JVACIgnD32z ddkEieRjMebAXh69FL8= X-Received: by 10.55.140.196 with SMTP id o187mr2351708qkd.80.1501623978496; Tue, 01 Aug 2017 14:46:18 -0700 (PDT) From: Dawid Zamirski To: libvir-list@redhat.com Date: Tue, 1 Aug 2017 17:46:05 -0400 Message-Id: <20170801214614.8915-5-dzrudy@gmail.com> In-Reply-To: <20170801214614.8915-1-dzrudy@gmail.com> References: <20170801214614.8915-1-dzrudy@gmail.com> X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Tue, 01 Aug 2017 21:46:21 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Tue, 01 Aug 2017 21:46:21 +0000 (UTC) for IP:'209.85.220.174' DOMAIN:'mail-qk0-f174.google.com' HELO:'mail-qk0-f174.google.com' FROM:'dzrudy@gmail.com' RCPT:'' X-RedHat-Spam-Score: -0.43 (DCC_REPUT_00_12, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, RCVD_IN_SORBS_SPAM, SPF_PASS) 209.85.220.174 mail-qk0-f174.google.com 209.85.220.174 mail-qk0-f174.google.com X-Scanned-By: MIMEDefang 2.78 on 10.5.110.26 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-loop: libvir-list@redhat.com Subject: [libvirt] [libvirt-php PATCH 04/13] Split up the bindings for libvirt connection API X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Tue, 01 Aug 2017 21:51:11 +0000 (UTC) X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" * 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 =3D \ 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 =3D \ $(AM_CFLAGS) \ -DCOMPILE_DL_LIBVIRT=3D1 diff --git a/src/libvirt-connection.c b/src/libvirt-connection.c new file mode 100644 index 0000000..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 ass= igned to the connection identified by conn + * Arguments: @conn [virConnectPtr]: libvirt connection poin= ter + * Returns: None + */ +static void +free_resources_on_connection(virConnectPtr conn TSRMLS_DC) +{ + int binding_resources_count =3D 0; + resource_info *binding_resources; + int i; + + binding_resources_count =3D LIBVIRT_G(binding_resources_count); + binding_resources =3D LIBVIRT_G(binding_resources); + + for (i =3D 0; i < binding_resources_count; i++) { + if ((binding_resources[i].overwrite =3D=3D 0) && (binding_resource= s[i].conn =3D=3D 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 =3D (php_libvirt_connection *) rsrc->ptr; + int rv =3D 0; + + if (conn !=3D NULL) { + if (conn->conn !=3D NULL) { + free_resources_on_connection(conn->conn TSRMLS_CC); + + rv =3D virConnectClose(conn->conn); + if (rv =3D=3D -1) { + DPRINTF("%s: virConnectClose(%p) returned %d (%s)\n", __FU= NCTION__, conn->conn, rv, LIBVIRT_G(last_error)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "virConnectClo= se 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, con= n->conn, 0 TSRMLS_CC); + } + conn->conn =3D NULL; + } + efree(conn); + } +} + +/* Authentication callback function. + * + * Should receive list of credentials via cbdata and pass the requested on= e to + * libvirt + */ +static int libvirt_virConnectAuthCallback(virConnectCredentialPtr cred, + unsigned int ncred, void *cbdata) +{ + TSRMLS_FETCH(); + + unsigned int i, j; + php_libvirt_cred_value *creds =3D (php_libvirt_cred_value *) cbdata; + for (i =3D 0; i < (unsigned int)ncred; i++) { + DPRINTF("%s: cred %d, type %d, prompt %s challenge %s\n ", __FUNCT= ION__, i, cred[i].type, cred[i].prompt, cred[i].challenge); + if (creds !=3D NULL) + for (j =3D 0; j < (unsigned int)creds[0].count; j++) { + if (creds[j].type =3D=3D cred[i].type) { + cred[i].resultlen =3D creds[j].resultlen; + cred[i].result =3D (char *)malloc(creds[j].resultlen += 1); + memset(cred[i].result, 0, creds[j].resultlen + 1); + strncpy(cred[i].result, creds[j].result, creds[j].resu= ltlen); + } + } + DPRINTF("%s: result %s (%d)\n", __FUNCTION__, cred[i].result, cred= [i].resultlen); + } + + return 0; +} + +static int libvirt_virConnectCredType[] =3D { + 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 URL, user can also set the readonly flag= and/or set credentials for connection + * Arguments: @url [string]: URI for connection + * @readonly [bool]: flag whether to use read-only connec= tion or not + * @credentials [array]: array of connection credentials + * Returns: libvirt connection resource + */ +PHP_FUNCTION(libvirt_connect) +{ + php_libvirt_connection *conn; + php_libvirt_cred_value *creds =3D NULL; + zval *zcreds =3D NULL; + zval *data; + int i; + int j; + int credscount =3D 0; + + virConnectAuth libvirt_virConnectAuth =3D { + libvirt_virConnectCredType, + sizeof(libvirt_virConnectCredType) / sizeof(int), + libvirt_virConnectAuthCallback, + NULL + }; + + char *url =3D NULL; + strsize_t url_len =3D 0; + zend_bool readonly =3D 1; + + HashTable *arr_hash; + HashPosition pointer; + int array_count; + + zend_ulong index; + + unsigned long libVer; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sba", &url, &ur= l_len, &readonly, &zcreds) =3D=3D FAILURE) { + RETURN_FALSE; + } + + if (virGetVersion(&libVer, NULL, NULL)!=3D 0) + RETURN_FALSE; + + if (libVer < 6002) { + set_error("Only libvirt 0.6.2 and higher supported. Please upgrade= your libvirt" TSRMLS_CC); + RETURN_FALSE; + } + + if ((count_resources(INT_RESOURCE_CONNECTION TSRMLS_CC) + 1) > LIBVIRT= _G(max_connections_ini)) { + DPRINTF("%s: maximum number of connections allowed exceeded (max %= lu)\n", PHPFUNC, (unsigned long)LIBVIRT_G(max_connections_ini)); + set_error("Maximum number of connections allowed exceeded" TSRMLS_= CC); + RETURN_FALSE; + } + + /* If 'null' value has been passed as URL override url to NULL value t= o autodetect the hypervisor */ + if ((url =3D=3D NULL) || (strcasecmp(url, "NULL") =3D=3D 0)) + url =3D NULL; + + conn =3D (php_libvirt_connection *)emalloc(sizeof(php_libvirt_connecti= on)); + if (zcreds =3D=3D NULL) { + /* connecting without providing authentication */ + if (readonly) + conn->conn =3D virConnectOpenReadOnly(url); + else + conn->conn =3D virConnectOpen(url); + } else { + /* connecting with authentication (using callback) */ + arr_hash =3D Z_ARRVAL_P(zcreds); + array_count =3D zend_hash_num_elements(arr_hash); + + credscount =3D array_count; + creds =3D (php_libvirt_cred_value *)emalloc(credscount * sizeof(ph= p_libvirt_cred_value)); + j =3D 0; + /* parse the input Array and create list of credentials. The list = (array) is passed to callback function. */ + VIRT_FOREACH(arr_hash, pointer, data) { + if (Z_TYPE_P(data) =3D=3D IS_STRING) { + php_libvirt_hash_key_info info; + VIRT_HASH_CURRENT_KEY_INFO(arr_hash, pointer, index, info); + + if (info.type =3D=3D HASH_KEY_IS_STRING) { + PHPWRITE(info.name, info.length); + } else { + DPRINTF("%s: credentials index %d\n", PHPFUNC, (int)in= dex); + creds[j].type =3D index; + creds[j].result =3D (char *)emalloc(Z_STRLEN_P(data) += 1); + memset(creds[j].result, 0, Z_STRLEN_P(data) + 1); + creds[j].resultlen =3D Z_STRLEN_P(data); + strncpy(creds[j].result, Z_STRVAL_P(data), Z_STRLEN_P(= data)); + j++; + } + } + } VIRT_FOREACH_END(); + DPRINTF("%s: Found %d elements for credentials\n", PHPFUNC, j); + creds[0].count =3D j; + libvirt_virConnectAuth.cbdata =3D (void *)creds; + conn->conn =3D virConnectOpenAuth(url, &libvirt_virConnectAuth, re= adonly ? VIR_CONNECT_RO : 0); + for (i =3D 0; i < creds[0].count; i++) + efree(creds[i].result); + efree(creds); + } + + if (conn->conn =3D=3D NULL) { + DPRINTF("%s: Cannot establish connection to %s\n", PHPFUNC, url); + efree(conn); + RETURN_FALSE; + } + + resource_change_counter(INT_RESOURCE_CONNECTION, NULL, conn->conn, 1 T= SRMLS_CC); + DPRINTF("%s: Connection to %s established, returning %p\n", PHPFUNC, u= rl, conn->conn); + + VIRT_REGISTER_RESOURCE(conn, le_libvirt_connection); + conn->resource =3D VIRT_RESOURCE_HANDLE(return_value); +} + +/* + * Function name: libvirt_connect_get_uri + * Since version: 0.4.1(-1) + * Description: Function is used to get the connection URI. This is us= eful to check the hypervisor type of host machine when using "null" uri to = libvirt_connect() + * Arguments: @conn [resource]: resource for connection + * Returns: connection URI string or FALSE for error + */ +PHP_FUNCTION(libvirt_connect_get_uri) +{ + zval *zconn; + char *uri; + php_libvirt_connection *conn =3D NULL; + + GET_CONNECTION_FROM_ARGS("r", &zconn); + uri =3D virConnectGetURI(conn->conn); + DPRINTF("%s: virConnectGetURI returned %s\n", PHPFUNC, uri); + if (uri =3D=3D NULL) + RETURN_FALSE; + + VIRT_RETVAL_STRING(uri); + free(uri); +} + +/* + * Function name: libvirt_connect_get_hostname + * Since version: 0.4.1(-1) + * Description: Function is used to get the hostname of the guest asso= ciated with the connection + * Arguments: @conn [resource]: resource for connection + * Returns: hostname of the host node or FALSE for error + */ +PHP_FUNCTION(libvirt_connect_get_hostname) +{ + php_libvirt_connection *conn =3D NULL; + zval *zconn; + char *hostname; + + GET_CONNECTION_FROM_ARGS("r", &zconn); + + hostname =3D virConnectGetHostname(conn->conn); + DPRINTF("%s: virConnectGetHostname returned %s\n", PHPFUNC, hostname); + if (hostname =3D=3D NULL) + RETURN_FALSE; + + VIRT_RETVAL_STRING(hostname); + free(hostname); +} + +/* + * Function name: libvirt_connect_get_hypervisor + * Since version: 0.4.1(-2) + * Description: Function is used to get the information about the hype= rvisor on the connection identified by the connection pointer + * Arguments: @conn [resource]: resource for connection + * Returns: array of hypervisor information if available + */ +PHP_FUNCTION(libvirt_connect_get_hypervisor) +{ + php_libvirt_connection *conn =3D NULL; + zval *zconn; + unsigned long hvVer =3D 0; + const char *type =3D NULL; + char hvStr[64] =3D { 0 }; + + GET_CONNECTION_FROM_ARGS("r", &zconn); + + if (virConnectGetVersion(conn->conn, &hvVer) !=3D 0) + RETURN_FALSE; + + type =3D virConnectGetType(conn->conn); + if (type =3D=3D NULL) + RETURN_FALSE; + + DPRINTF("%s: virConnectGetType returned %s\n", PHPFUNC, type); + + array_init(return_value); + VIRT_ADD_ASSOC_STRING(return_value, "hypervisor", (char *)type); + add_assoc_long(return_value, "major", (long)((hvVer/1000000) % 1000)); + add_assoc_long(return_value, "minor", (long)((hvVer/1000) % 1000)); + add_assoc_long(return_value, "release", (long)(hvVer % 1000)); + + snprintf(hvStr, sizeof(hvStr), "%s %d.%d.%d", type, + (long)((hvVer/1000000) % 1000), (long)((hvVer/1000) % 1000), = (long)(hvVer % 1000)); + VIRT_ADD_ASSOC_STRING(return_value, "hypervisor_string", hvStr); +} + +/* + * Function name: libvirt_connect_get_capabilities + * Since version: 0.4.1(-2) + * Description: Function is used to get the capabilities information f= rom the connection + * Arguments: @conn [resource]: resource for connection + * @xpath [string]: optional xPath query to be applied on= the result + * Returns: capabilities XML from the connection or FALSE for error + */ +PHP_FUNCTION(libvirt_connect_get_capabilities) +{ + php_libvirt_connection *conn =3D NULL; + zval *zconn; + char *caps; + char *xpath =3D NULL; + strsize_t xpath_len; + char *tmp =3D NULL; + int retval =3D -1; + + GET_CONNECTION_FROM_ARGS("r|s", &zconn, &xpath, &xpath_len); + + caps =3D virConnectGetCapabilities(conn->conn); + if (caps =3D=3D NULL) + RETURN_FALSE; + + tmp =3D get_string_from_xpath(caps, xpath, NULL, &retval); + if ((tmp =3D=3D NULL) || (retval < 0)) { + VIRT_RETVAL_STRING(caps); + } else { + VIRT_RETVAL_STRING(tmp); + } + + free(caps); + free(tmp); +} + +/* + * Function name: libvirt_connect_get_emulator + * Since version: 0.4.5 + * Description: Function is used to get the emulator for requested con= nection/architecture + * Arguments: @conn [resource]: libvirt connection resource + * @arch [string]: optional architecture string, can be N= ULL to get default + * Returns: path to the emulator + */ +PHP_FUNCTION(libvirt_connect_get_emulator) +{ + php_libvirt_connection *conn =3D NULL; + zval *zconn; + char *arch =3D NULL; + strsize_t arch_len; + char *tmp; + + GET_CONNECTION_FROM_ARGS("r|s", &zconn, &arch, &arch_len); + + if ((arch =3D=3D NULL) || (arch_len =3D=3D 0)) + arch =3D NULL; + + tmp =3D connection_get_emulator(conn->conn, arch TSRMLS_CC); + if (tmp =3D=3D NULL) { + set_error("Cannot get emulator" TSRMLS_CC); + RETURN_FALSE; + } + + VIRT_RETVAL_STRING(tmp); + free(tmp); +} + +/* + * Function name: libvirt_connect_get_nic_models + * Since version: 0.4.9 + * Description: Function is used to get NIC models for requested conne= ction/architecture + * Arguments: @conn [resource]: libvirt connection resource + * @arch [string]: optional architecture string, can be N= ULL to get default + * Returns: array of models + */ +PHP_FUNCTION(libvirt_connect_get_nic_models) +{ + php_libvirt_connection *conn =3D NULL; + zval *zconn; + char *arch =3D NULL; + strsize_t arch_len; + char *tmp; + + GET_CONNECTION_FROM_ARGS("r|s", &zconn, &arch, &arch_len); + + /* Disable getting it on remote connections */ + if (!is_local_connection(conn->conn)) { + set_error("This function works only on local connections" TSRMLS_C= C); + RETURN_FALSE; + } + + /* This approach is working only for QEMU driver so bails if not curre= ntly using it */ + if (strcmp(virConnectGetType(conn->conn), "QEMU") !=3D 0) { + set_error("This function can be used only for QEMU driver" TSRMLS_= CC); + RETURN_FALSE; + } + +#ifndef EXTWIN + if ((arch =3D=3D NULL) || (arch_len =3D=3D 0)) + arch =3D NULL; + + tmp =3D connection_get_emulator(conn->conn, arch TSRMLS_CC); + if (tmp =3D=3D NULL) { + set_error("Cannot get emulator" TSRMLS_CC); + RETURN_FALSE; + } + + char cmd[4096] =3D { 0 }; + char tmp2[16] =3D { 0 }; + snprintf(cmd, sizeof(cmd), "%s -net nic,model=3D? 2>&1", tmp); + + FILE *fp =3D popen(cmd, "r"); + if (fp =3D=3D NULL) + RETURN_FALSE; + + array_init(return_value); + while (!feof(fp)) { + memset(cmd, 0, sizeof(cmd)); + if (!fgets(cmd, sizeof(cmd), fp)) + break; + + if ((tmp =3D strstr(cmd, "Supported NIC models:")) !=3D NULL) { + tmp =3D strstr(tmp, ":") + 2; + + int i; + tTokenizer t =3D tokenize(tmp, ","); + for (i =3D 0; i < t.numTokens; i++) { + snprintf(tmp2, sizeof(tmp2), "%d", i); + VIRT_ADD_ASSOC_STRING(return_value, tmp2, t.tokens[i]); + } + free_tokens(t); + } + } + fclose(fp); +#endif +} + +/* + * Function name: libvirt_connect_get_soundhw_models + * Since version: 0.4.9 + * Description: Function is used to get sound hardware models for requ= ested connection/architecture + * Arguments: @conn [resource]: libvirt connection resource + * @arch [string]: optional architecture string, can be N= ULL to get default + * @flags [int]: flags for getting sound hardware. Can be= either 0 or VIR_CONNECT_SOUNDHW_GET_NAMES + * Returns: array of models + */ +PHP_FUNCTION(libvirt_connect_get_soundhw_models) +{ + php_libvirt_connection *conn =3D NULL; + zval *zconn; + char *arch =3D NULL; + strsize_t arch_len; + char *tmp; + zend_long flags =3D 0; + + GET_CONNECTION_FROM_ARGS("r|sl", &zconn, &arch, &arch_len, &flags); + + if ((arch =3D=3D NULL) || (arch_len =3D=3D 0)) + arch =3D NULL; + + /* Disable getting it on remote connections */ + if (!is_local_connection(conn->conn)) { + set_error("This function works only on local connections" TSRMLS_C= C); + RETURN_FALSE; + } + +#ifndef EXTWIN + /* This approach is working only for QEMU driver so bails if not curre= ntly using it */ + if (strcmp(virConnectGetType(conn->conn), "QEMU") !=3D 0) { + set_error("This function can be used only for QEMU driver" TSRMLS_= CC); + RETURN_FALSE; + } + + tmp =3D connection_get_emulator(conn->conn, arch TSRMLS_CC); + if (tmp =3D=3D NULL) { + set_error("Cannot get emulator" TSRMLS_CC); + RETURN_FALSE; + } + + char cmd[4096] =3D { 0 }; + snprintf(cmd, sizeof(cmd), "%s -soundhw help 2>&1", tmp); + + FILE *fp =3D popen(cmd, "r"); + if (fp =3D=3D NULL) + RETURN_FALSE; + + short inFunc =3D 0; + + int n =3D 0; + array_init(return_value); + while (!feof(fp)) { + memset(cmd, 0, sizeof(cmd)); + if (!fgets(cmd, sizeof(cmd), fp)) + break; + + if (strncmp(cmd, "Valid ", 6) =3D=3D 0) { + inFunc =3D 1; + continue; + } else + if (strlen(cmd) < 2) + inFunc =3D 0; + + if (inFunc) { + int i =3D 0; + char desc[1024] =3D { 0 }; + tTokenizer t =3D tokenize(cmd, " "); + if (t.numTokens =3D=3D 0) + continue; + + if ((i > 0) && (flags & CONNECT_FLAG_SOUNDHW_GET_NAMES)) { + zval *arr; + memset(desc, 0, sizeof(desc)); + for (i =3D 1; i < t.numTokens; i++) { + strcat(desc, t.tokens[i]); + if (i < t.numTokens - 1) + strcat(desc, " "); + } + + VIRT_ARRAY_INIT(arr); + VIRT_ADD_ASSOC_STRING(arr, "name", t.tokens[0]); + VIRT_ADD_ASSOC_STRING(arr, "description", desc); + add_next_index_zval(return_value, arr); + } else { + char tmp2[16] =3D { 0 }; + snprintf(tmp2, sizeof(tmp2), "%d", n++); + VIRT_ADD_ASSOC_STRING(return_value, tmp2, t.tokens[0]); + } + + free_tokens(t); + } + } + fclose(fp); +#endif +} + +/* + * Function name: libvirt_connect_get_maxvcpus + * Since version: 0.4.1(-2) + * Description: Function is used to get maximum number of VCPUs per VM= on the hypervisor connection + * Arguments: @conn [resource]: resource for connection + * Returns: number of VCPUs available per VM on the connection or = FALSE for error + */ +PHP_FUNCTION(libvirt_connect_get_maxvcpus) +{ + php_libvirt_connection *conn =3D NULL; + zval *zconn; + const char *type =3D NULL; + + GET_CONNECTION_FROM_ARGS("r", &zconn); + + type =3D virConnectGetType(conn->conn); + if (type =3D=3D NULL) + RETURN_FALSE; + + RETURN_LONG(virConnectGetMaxVcpus(conn->conn, type)); +} + +/* + * Function name: libvirt_connect_get_sysinfo + * Since version: 0.4.1(-2) + * Description: Function is used to get the system information from co= nnection if available + * Arguments: @conn [resource]: resource for connection + * Returns: XML description of system information from the connect= ion or FALSE for error + */ +PHP_FUNCTION(libvirt_connect_get_sysinfo) +{ + php_libvirt_connection *conn =3D NULL; + zval *zconn; + char *sysinfo; + + GET_CONNECTION_FROM_ARGS("r", &zconn); + + sysinfo =3D virConnectGetSysinfo(conn->conn, 0); + if (sysinfo =3D=3D NULL) + RETURN_FALSE; + + VIRT_RETVAL_STRING(sysinfo); + free(sysinfo); +} + +/* + * Function name: libvirt_connect_is_encrypted + * Since version: 0.4.1(-2) + * Description: Function is used to get the information whether the co= nnection is encrypted or not + * Arguments: @conn [resource]: resource for connection + * Returns: 1 if encrypted, 0 if not encrypted, -1 on error + */ +PHP_FUNCTION(libvirt_connect_get_encrypted) +{ + php_libvirt_connection *conn =3D NULL; + zval *zconn; + + GET_CONNECTION_FROM_ARGS("r", &zconn); + + RETURN_LONG(virConnectIsEncrypted(conn->conn)); +} + +/* + * Function name: libvirt_connect_is_secure + * Since version: 0.4.1(-2) + * Description: Function is used to get the information whether the co= nnection is secure or not + * Arguments: @conn [resource]: resource for connection + * Returns: 1 if secure, 0 if not secure, -1 on error + */ +PHP_FUNCTION(libvirt_connect_get_secure) +{ + php_libvirt_connection *conn =3D NULL; + zval *zconn; + + GET_CONNECTION_FROM_ARGS("r", &zconn); + + RETURN_LONG(virConnectIsSecure(conn->conn)); +} + +/* + * Function name: libvirt_connect_get_information + * Since version: 0.4.1(-2) + * Description: Function is used to get the information about the conn= ection + * Arguments: @conn [resource]: resource for connection + * Returns: array of information about the connection + */ +PHP_FUNCTION(libvirt_connect_get_information) +{ + zval *zconn; + char *tmp; + unsigned long hvVer =3D 0; + const char *type =3D NULL; + char hvStr[64] =3D { 0 }; + int iTmp =3D -1, maxvcpus =3D -1; + php_libvirt_connection *conn =3D NULL; + + GET_CONNECTION_FROM_ARGS("r", &zconn); + + tmp =3D virConnectGetURI(conn->conn); + DPRINTF("%s: Got connection URI of %s...\n", PHPFUNC, tmp); + array_init(return_value); + VIRT_ADD_ASSOC_STRING(return_value, "uri", tmp ? tmp : "unknown"); + free(tmp); + tmp =3D virConnectGetHostname(conn->conn); + VIRT_ADD_ASSOC_STRING(return_value, "hostname", tmp ? tmp : "unknown"); + free(tmp); + + if ((virConnectGetVersion(conn->conn, &hvVer) =3D=3D 0) && (type =3D v= irConnectGetType(conn->conn))) { + VIRT_ADD_ASSOC_STRING(return_value, "hypervisor", (char *)type); + add_assoc_long(return_value, "hypervisor_major", (long)((hvVer/100= 0000) % 1000)); + add_assoc_long(return_value, "hypervisor_minor", (long)((hvVer/100= 0) % 1000)); + add_assoc_long(return_value, "hypervisor_release", (long)(hvVer % = 1000)); + snprintf(hvStr, sizeof(hvStr), "%s %d.%d.%d", type, + (long)((hvVer/1000000) % 1000), (long)((hvVer/1000) % 100= 0), (long)(hvVer % 1000)); + VIRT_ADD_ASSOC_STRING(return_value, "hypervisor_string", hvStr); + } + + if (strcmp(type, "QEMU") =3D=3D 0) { + /* For QEMU the value is not reliable so we return -1 instead */ + maxvcpus =3D -1; + } else { + maxvcpus =3D virConnectGetMaxVcpus(conn->conn, type); + } + + add_assoc_long(return_value, "hypervisor_maxvcpus", maxvcpus); + iTmp =3D virConnectIsEncrypted(conn->conn); + if (iTmp =3D=3D 1) + VIRT_ADD_ASSOC_STRING(return_value, "encrypted", "Yes"); + else + if (iTmp =3D=3D 0) + VIRT_ADD_ASSOC_STRING(return_value, "encrypted", "No"); + else + VIRT_ADD_ASSOC_STRING(return_value, "encrypted", "unknown"); + + iTmp =3D virConnectIsSecure(conn->conn); + if (iTmp =3D=3D 1) + VIRT_ADD_ASSOC_STRING(return_value, "secure", "Yes"); + else + if (iTmp =3D=3D 0) + VIRT_ADD_ASSOC_STRING(return_value, "secure", "No"); + else + VIRT_ADD_ASSOC_STRING(return_value, "secure", "unknown"); + + add_assoc_long(return_value, "num_inactive_domains", virConnectNumOfDe= finedDomains(conn->conn)); + add_assoc_long(return_value, "num_inactive_interfaces", virConnectNumO= fDefinedInterfaces(conn->conn)); + add_assoc_long(return_value, "num_inactive_networks", virConnectNumOfD= efinedNetworks(conn->conn)); + add_assoc_long(return_value, "num_inactive_storagepools", virConnectNu= mOfDefinedStoragePools(conn->conn)); + + add_assoc_long(return_value, "num_active_domains", virConnectNumOfDoma= ins(conn->conn)); + add_assoc_long(return_value, "num_active_interfaces", virConnectNumOfI= nterfaces(conn->conn)); + add_assoc_long(return_value, "num_active_networks", virConnectNumOfNet= works(conn->conn)); + add_assoc_long(return_value, "num_active_storagepools", virConnectNumO= fStoragePools(conn->conn)); + + add_assoc_long(return_value, "num_total_domains", virConnectNumOfDomai= ns(conn->conn) + virConnectNumOfDefinedDomains(conn->conn)); + add_assoc_long(return_value, "num_total_interfaces", virConnectNumOfIn= terfaces(conn->conn) + virConnectNumOfDefinedInterfaces(conn->conn)); + add_assoc_long(return_value, "num_total_networks", virConnectNumOfNetw= orks(conn->conn) + virConnectNumOfDefinedNetworks(conn->conn)); + add_assoc_long(return_value, "num_total_storagepools", virConnectNumOf= StoragePools(conn->conn) + virConnectNumOfDefinedStoragePools(conn->conn)); + + add_assoc_long(return_value, "num_secrets", virConnectNumOfSecrets(con= n->conn)); + add_assoc_long(return_value, "num_nwfilters", virConnectNumOfNWFilters= (conn->conn)); +} + +/* + * Function name: libvirt_connect_get_machine_types + * Since version: 0.4.9 + * Description: Function is used to get machine types supported by hyp= ervisor on the conneciton + * Arguments: @conn [resource]: resource for connection + * Returns: array of machine types for the connection incl. maxCpu= s if appropriate + */ +PHP_FUNCTION(libvirt_connect_get_machine_types) +{ + zval *zconn; + php_libvirt_connection *conn =3D NULL; + char *caps =3D NULL; + char **ret =3D NULL; + int i, num =3D -1; + + GET_CONNECTION_FROM_ARGS("r", &zconn); + + caps =3D virConnectGetCapabilities(conn->conn); + if (caps =3D=3D NULL) + RETURN_FALSE; + + array_init(return_value); + + ret =3D get_array_from_xpath(caps, "//capabilities/guest/arch/@name", = &num); + if (ret !=3D NULL) { + for (i =3D 0; i < num; i++) { + int num2, j; + char tmp[1024] =3D { 0 }; + + snprintf(tmp, sizeof(tmp), "//capabilities/guest/arch[@name=3D= \"%s\"]/domain/@type", ret[i]); + char **ret2 =3D get_array_from_xpath(caps, tmp, &num2); + if (ret2 !=3D NULL) { + zval *arr2; + VIRT_ARRAY_INIT(arr2); + + for (j =3D 0; j < num2; j++) { + int num3, k; + char tmp2[1024] =3D { 0 }; + zval *arr3; + + VIRT_ARRAY_INIT(arr3); + + snprintf(tmp2, sizeof(tmp2), "//capabilities/guest/arc= h[@name=3D\"%s\"]/machine", + ret[i]); + + char **ret3 =3D get_array_from_xpath(caps, tmp2, &num3= ); + if (ret3 !=3D NULL) { + for (k =3D 0; k < num3; k++) { + char *numTmp =3D NULL; + char key[8] =3D { 0 }; + char tmp3[2048] =3D { 0 }; + + snprintf(key, sizeof(key), "%d", k); + //VIRT_ADD_ASSOC_STRING(arr2, key, ret3[k]); + + snprintf(tmp3, sizeof(tmp3), "//capabilities/g= uest/arch[@name=3D\"%s\"]/machine[text()=3D\"%s\"]/@maxCpus", + ret[i], ret3[k]); + + numTmp =3D get_string_from_xpath(caps, tmp3, N= ULL, NULL); + if (numTmp =3D=3D NULL) { + VIRT_ADD_ASSOC_STRING(arr2, key, ret3[k]); + } else { + zval *arr4; + VIRT_ARRAY_INIT(arr4); + VIRT_ADD_ASSOC_STRING(arr4, "name", ret3[k= ]); + VIRT_ADD_ASSOC_STRING(arr4, "maxCpus", num= Tmp); + + add_assoc_zval_ex(arr2, key, strlen(key) += 1, arr4); + free(numTmp); + } + + free(ret3[k]); + } + } + + /* Domain type specific */ + snprintf(tmp2, sizeof(tmp2), "//capabilities/guest/arc= h[@name=3D\"%s\"]/domain[@type=3D\"%s\"]/machine", + ret[i], ret2[j]); + + ret3 =3D get_array_from_xpath(caps, tmp2, &num3); + if (ret3 !=3D NULL) { + for (k =3D 0; k < num3; k++) { + char key[8] =3D { 0 }; + char tmp3[2048] =3D { 0 }; + char *numTmp =3D NULL; + + snprintf(key, sizeof(key), "%d", k); + snprintf(tmp3, sizeof(tmp3), + "//capabilities/guest/arch[@name=3D\"= %s\"]/domain[@type=3D\"%s\"]/machine[text()=3D\"%s\"]/@maxCpus", + ret[i], ret2[j], ret3[k]); + + numTmp =3D get_string_from_xpath(caps, tmp3, N= ULL, NULL); + if (numTmp =3D=3D NULL) { + VIRT_ADD_ASSOC_STRING(arr3, key, ret3[k]); + } else { + zval *arr4; + VIRT_ARRAY_INIT(arr4); + + VIRT_ADD_ASSOC_STRING(arr4, "name", ret3[k= ]); + VIRT_ADD_ASSOC_STRING(arr4, "maxCpus", num= Tmp); + + add_assoc_zval_ex(arr3, key, strlen(key) += 1, arr4); + free(numTmp); + } + + free(ret3[k]); + } + + add_assoc_zval_ex(arr2, ret2[j], strlen(ret2[j]) += 1, arr3); + } + } + //free(ret2[j]); + + add_assoc_zval_ex(return_value, ret[i], strlen(ret[i]) + 1= , arr2); + } + free(ret[i]); + } + } +} + +/* + * Function name: libvirt_connect_get_all_domain_stats + * Since version: 0.5.1(-1) + * Description: Query statistics for all domains on a given connection + * Arguments: @conn [resource]: resource for connection + * @stats [int]: the statistic groups from VIR_DOMAIN_STA= TS_* + * @flags [int]: the filter flags from VIR_CONNECT_GET_AL= L_DOMAINS_STATS_* + * Returns: assoc array with statistics or false on error + */ +PHP_FUNCTION(libvirt_connect_get_all_domain_stats) +{ + php_libvirt_connection *conn =3D NULL; + zval *zconn; + int retval =3D -1; + zend_long flags =3D 0; + zend_long stats =3D 0; + const char *name =3D NULL; + int i; + int j; + virTypedParameter params; + virDomainStatsRecordPtr *retstats =3D NULL; + + GET_CONNECTION_FROM_ARGS("r|l|l", &zconn, &stats, &flags); + + retval =3D virConnectGetAllDomainStats(conn->conn, stats, &retstats, f= lags); + + array_init(return_value); + if (retval < 0) + RETURN_FALSE; + + for (i =3D 0; i < retval; i++) { + zval *arr2; + VIRT_ARRAY_INIT(arr2); + + for (j =3D 0; j < retstats[i]->nparams; j++) { + params =3D retstats[i]->params[j]; + switch (params.type) { + case VIR_TYPED_PARAM_INT: + add_assoc_long(arr2, params.field, params.value.i); + break; + case VIR_TYPED_PARAM_UINT: + add_assoc_long(arr2, params.field, params.value.ui); + break; + case VIR_TYPED_PARAM_LLONG: + add_assoc_long(arr2, params.field, params.value.l); + break; + case VIR_TYPED_PARAM_ULLONG: + add_assoc_long(arr2, params.field, params.value.ul); + break; + case VIR_TYPED_PARAM_DOUBLE: + add_assoc_double(arr2, params.field, params.value.d); + break; + case VIR_TYPED_PARAM_BOOLEAN: + add_assoc_bool(arr2, params.field, params.value.b); + break; + case VIR_TYPED_PARAM_STRING: + VIRT_ADD_ASSOC_STRING(arr2, params.field, params.value.s); + break; + } + } + name =3D virDomainGetName(retstats[i]->dom); +#if PHP_MAJOR_VERSION >=3D 7 + zend_hash_update(Z_ARRVAL_P(return_value), zend_string_init(name, = strlen(name), 0), arr2); +#else + zend_hash_update(Z_ARRVAL_P(return_value), name, strlen(name)+1, &= arr2, sizeof(arr2), NULL); +#endif + } + + virDomainStatsRecordListFree(retstats); +} + diff --git a/src/libvirt-connection.h b/src/libvirt-connection.h new file mode 100644 index 0000000..2c50ec9 --- /dev/null +++ b/src/libvirt-connection.h @@ -0,0 +1,83 @@ +/* + * libvirt-connection.h: The PHP bindings to libvirt connection API + * + * See COPYING for the license of this software + */ + +#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 + +# define PHP_FE_LIBVIRT_CONNECTION = \ + PHP_FE(libvirt_connect, arginfo_libvirt_connect) = \ + PHP_FE(libvirt_connect_get_uri, arginfo_libvirt_conn) = \ + PHP_FE(libvirt_connect_get_hostname, arginfo_libvirt_conn) = \ + PHP_FE(libvirt_connect_get_hypervisor, arginfo_libvirt_conn) = \ + PHP_FE(libvirt_connect_get_capabilities, arginfo_libvirt_conn_xpat= h) \ + PHP_FE(libvirt_connect_get_emulator, arginfo_libvirt_connect_g= et_emulator) \ + PHP_FE(libvirt_connect_get_nic_models, arginfo_libvirt_connect_g= et_emulator) \ + PHP_FE(libvirt_connect_get_soundhw_models, arginfo_libvirt_connect_g= et_soundhw_models) \ + PHP_FE(libvirt_connect_get_maxvcpus, arginfo_libvirt_conn) = \ + PHP_FE(libvirt_connect_get_sysinfo, arginfo_libvirt_conn) = \ + PHP_FE(libvirt_connect_get_encrypted, arginfo_libvirt_conn) = \ + PHP_FE(libvirt_connect_get_secure, arginfo_libvirt_conn) = \ + PHP_FE(libvirt_connect_get_information, arginfo_libvirt_conn) = \ + PHP_FE(libvirt_connect_get_machine_types, arginfo_libvirt_conn) = \ + PHP_FE(libvirt_connect_get_all_domain_stats, arginfo_libvirt_connect_g= et_all_domain_stats) + +# define GET_CONNECTION_FROM_ARGS(args, ...) = \ + do { = \ + reset_error(TSRMLS_C); = \ + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, = \ + args, = \ + __VA_ARGS__) =3D=3D FAILURE) { = \ + set_error("Invalid arguments" TSRMLS_CC); = \ + RETURN_FALSE; = \ + } = \ + = \ + VIRT_FETCH_RESOURCE(conn, php_libvirt_connection*, &zconn, = \ + PHP_LIBVIRT_CONNECTION_RES_NAME, = \ + le_libvirt_connection); = \ + = \ + if (conn =3D=3D NULL || conn->conn =3D=3D NULL) = \ + RETURN_FALSE; = \ + } while (0) + +int le_libvirt_connection; + +typedef struct _php_libvirt_connection { + virConnectPtr conn; + virt_resource_handle resource; +} php_libvirt_connection; + +typedef struct _php_libvirt_cred_value { + int count; + int type; + char *result; + unsigned int resultlen; +} php_libvirt_cred_value; + +void php_libvirt_connection_dtor(virt_resource *rsrc TSRMLS_DC); + +PHP_FUNCTION(libvirt_connect); +PHP_FUNCTION(libvirt_connect_get_uri); +PHP_FUNCTION(libvirt_connect_get_hostname); +PHP_FUNCTION(libvirt_connect_get_hypervisor); +PHP_FUNCTION(libvirt_connect_get_capabilities); +PHP_FUNCTION(libvirt_connect_get_emulator); +PHP_FUNCTION(libvirt_connect_get_nic_models); +PHP_FUNCTION(libvirt_connect_get_soundhw_models); +PHP_FUNCTION(libvirt_connect_get_maxvcpus); +PHP_FUNCTION(libvirt_connect_get_sysinfo); +PHP_FUNCTION(libvirt_connect_get_encrypted); +PHP_FUNCTION(libvirt_connect_get_secure); +PHP_FUNCTION(libvirt_connect_get_information); +PHP_FUNCTION(libvirt_connect_get_machine_types); +PHP_FUNCTION(libvirt_connect_get_all_domain_stats); + +#endif diff --git a/src/libvirt-php.c b/src/libvirt-php.c index aea69e7..3e11e9d 100644 --- a/src/libvirt-php.c +++ b/src/libvirt-php.c @@ -20,11 +20,11 @@ #include "util.h" #include "vncfunc.h" #include "sockets.h" +#include "libvirt-connection.h" =20 DEBUG_INIT("core"); =20 -/* PHP functions are prefixed with `zif_` so strip it */ -#define PHPFUNC (__FUNCTION__ + 4) + =20 #ifndef EXTWIN /* Additional binaries */ @@ -36,7 +36,6 @@ const char *features_binaries[] =3D { NULL }; #endif =20 /* ZEND thread safe per request globals definition */ -int le_libvirt_connection; int le_libvirt_domain; int le_libvirt_storagepool; int le_libvirt_volume; @@ -478,21 +477,7 @@ static zend_function_entry libvirt_functions[] =3D { /* Common functions */ PHP_FE(libvirt_get_last_error, arginfo_libvirt_void) /* Connect functions */ - PHP_FE(libvirt_connect, arginfo_libvirt_connect) - PHP_FE(libvirt_connect_get_uri, arginfo_libvirt_conn) - PHP_FE(libvirt_connect_get_hostname, arginfo_libvirt_conn) - PHP_FE(libvirt_connect_get_capabilities, arginfo_libvirt_conn_xpat= h) - PHP_FE(libvirt_connect_get_emulator, arginfo_libvirt_connect_g= et_emulator) - PHP_FE(libvirt_connect_get_nic_models, arginfo_libvirt_connect_g= et_emulator) - PHP_FE(libvirt_connect_get_soundhw_models, arginfo_libvirt_connect_g= et_soundhw_models) - PHP_FE(libvirt_connect_get_information, arginfo_libvirt_conn) - PHP_FE(libvirt_connect_get_machine_types, arginfo_libvirt_conn) - PHP_FE(libvirt_connect_get_hypervisor, arginfo_libvirt_conn) - PHP_FE(libvirt_connect_get_sysinfo, arginfo_libvirt_conn) - PHP_FE(libvirt_connect_get_maxvcpus, arginfo_libvirt_conn) - PHP_FE(libvirt_connect_get_encrypted, arginfo_libvirt_conn) - PHP_FE(libvirt_connect_get_secure, arginfo_libvirt_conn) - PHP_FE(libvirt_connect_get_all_domain_stats, arginfo_libvirt_connect_g= et_all_domain_stats) + PHP_FE_LIBVIRT_CONNECTION /* Stream functions */ PHP_FE(libvirt_stream_create, arginfo_libvirt_conn) PHP_FE(libvirt_stream_close, arginfo_libvirt_conn) @@ -703,21 +688,6 @@ zend_module_entry libvirt_module_entry =3D { ZEND_GET_MODULE(libvirt) #endif =20 -ZEND_BEGIN_MODULE_GLOBALS(libvirt) - char *last_error; - char *vnc_location; - zend_bool longlong_to_string_ini; - char *iso_path_ini; - char *image_path_ini; - zend_long max_connections_ini; -#ifdef DEBUG_SUPPORT - int debug; -#endif - resource_info *binding_resources; - int binding_resources_count; -ZEND_END_MODULE_GLOBALS(libvirt) - -ZEND_DECLARE_MODULE_GLOBALS(libvirt) =20 /* PHP init options */ PHP_INI_BEGIN() @@ -729,7 +699,9 @@ PHP_INI_END() =20 void change_debug(int val TSRMLS_DC) { +#ifdef DEBUG_SUPPORT LIBVIRT_G(debug) =3D val; +#endif setDebug(val); } =20 @@ -1245,28 +1217,6 @@ void free_resource(int type, void *mem TSRMLS_DC) } =20 /* - * Private function name: free_resources_on_connection - * Since version: 0.4.2 - * Description: Function is used to free all the resources ass= igned to the connection identified by conn - * Arguments: @conn [virConnectPtr]: libvirt connection poin= ter - * Returns: None - */ -void free_resources_on_connection(virConnectPtr conn TSRMLS_DC) -{ - int binding_resources_count =3D 0; - resource_info *binding_resources; - int i; - - binding_resources_count =3D LIBVIRT_G(binding_resources_count); - binding_resources =3D LIBVIRT_G(binding_resources); - - for (i =3D 0; i < binding_resources_count; i++) { - if ((binding_resources[i].overwrite =3D=3D 0) && (binding_resource= s[i].conn =3D=3D conn)) - free_resource(binding_resources[i].type, binding_resources[i].= mem TSRMLS_CC); - } -} - -/* * Private function name: check_resource_allocation * Since version: 0.4.2 * Description: Function is used to check whether the resource= identified by type and memory is allocated for connection conn or not @@ -1383,30 +1333,6 @@ int is_local_connection(virConnectPtr conn) #endif } =20 -/* Destructor for connection resource */ -static void php_libvirt_connection_dtor(virt_resource *rsrc TSRMLS_DC) -{ - php_libvirt_connection *conn =3D (php_libvirt_connection *)rsrc->ptr; - int rv =3D 0; - - if (conn !=3D NULL) { - if (conn->conn !=3D NULL) { - free_resources_on_connection(conn->conn TSRMLS_CC); - - rv =3D virConnectClose(conn->conn); - if (rv =3D=3D -1) { - DPRINTF("%s: virConnectClose(%p) returned %d (%s)\n", __FU= NCTION__, conn->conn, rv, LIBVIRT_G(last_error)); - php_error_docref(NULL TSRMLS_CC, E_WARNING, "virConnectClo= se 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, con= n->conn, 0 TSRMLS_CC); - } - conn->conn =3D NULL; - } - efree(conn); - } -} - /* Destructor for domain resource */ static void php_libvirt_domain_dtor(virt_resource *rsrc TSRMLS_DC) { @@ -1950,19 +1876,6 @@ PHP_MSHUTDOWN_FUNCTION(libvirt) } =20 /* Macros for obtaining resources from arguments */ -#define GET_CONNECTION_FROM_ARGS(args, ...) = \ - do { = \ - reset_error(TSRMLS_C); = \ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, args, __VA_AR= GS__) =3D=3D FAILURE) { \ - set_error("Invalid arguments" TSRMLS_CC); = \ - RETURN_FALSE; = \ - } = \ - = \ - VIRT_FETCH_RESOURCE(conn, php_libvirt_connection*, &zconn, PHP_LIB= VIRT_CONNECTION_RES_NAME, le_libvirt_connection);\ - if ((conn =3D=3D NULL) || (conn->conn =3D=3D NULL)) = \ - RETURN_FALSE; = \ - } while (0) = \ - #define GET_DOMAIN_FROM_ARGS(args, ...) = \ do { = \ reset_error(TSRMLS_C); = \ @@ -2080,40 +1993,6 @@ PHP_MSHUTDOWN_FUNCTION(libvirt) VIRT_RETURN_STRING(tmpnumber); \ } while (0) =20 - -/* Authentication callback function. Should receive list of credentials vi= a cbdata and pass the requested one to libvirt */ -static int libvirt_virConnectAuthCallback(virConnectCredentialPtr cred, un= signed int ncred, void *cbdata) -{ - TSRMLS_FETCH(); - - unsigned int i, j; - php_libvirt_cred_value *creds =3D (php_libvirt_cred_value *) cbdata; - for (i =3D 0; i < (unsigned int)ncred; i++) { - DPRINTF("%s: cred %d, type %d, prompt %s challenge %s\n ", __FUNCT= ION__, i, cred[i].type, cred[i].prompt, cred[i].challenge); - if (creds !=3D NULL) - for (j =3D 0; j < (unsigned int)creds[0].count; j++) { - if (creds[j].type =3D=3D cred[i].type) { - cred[i].resultlen =3D creds[j].resultlen; - cred[i].result =3D (char *)malloc(creds[j].resultlen += 1); - memset(cred[i].result, 0, creds[j].resultlen + 1); - strncpy(cred[i].result, creds[j].result, creds[j].resu= ltlen); - } - } - DPRINTF("%s: result %s (%d)\n", __FUNCTION__, cred[i].result, cred= [i].resultlen); - } - - return 0; -} - -static int libvirt_virConnectCredType[] =3D { - VIR_CRED_AUTHNAME, - VIR_CRED_ECHOPROMPT, - VIR_CRED_REALM, - VIR_CRED_PASSPHRASE, - VIR_CRED_NOECHOPROMPT, - //VIR_CRED_EXTERNAL, -}; - /* Common functions */ =20 /* @@ -2130,117 +2009,6 @@ PHP_FUNCTION(libvirt_get_last_error) } =20 /* - * 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 URL, user can also set the readonly flag= and/or set credentials for connection - * Arguments: @url [string]: URI for connection - * @readonly [bool]: flag whether to use read-only connec= tion or not - * @credentials [array]: array of connection credentials - * Returns: libvirt connection resource - */ -PHP_FUNCTION(libvirt_connect) -{ - php_libvirt_connection *conn; - php_libvirt_cred_value *creds =3D NULL; - zval *zcreds =3D NULL; - zval *data; - int i; - int j; - int credscount =3D 0; - - virConnectAuth libvirt_virConnectAuth =3D { libvirt_virConnectCredType= , sizeof(libvirt_virConnectCredType)/sizeof(int), libvirt_virConnectAuthCal= lback, NULL}; - - char *url =3D NULL; - strsize_t url_len =3D 0; - zend_bool readonly =3D 1; - - HashTable *arr_hash; - HashPosition pointer; - int array_count; - - zend_ulong index; - - unsigned long libVer; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sba", &url, &ur= l_len, &readonly, &zcreds) =3D=3D FAILURE) { - RETURN_FALSE; - } - - if (virGetVersion(&libVer, NULL, NULL)!=3D 0) - RETURN_FALSE; - - if (libVer < 6002) { - set_error("Only libvirt 0.6.2 and higher supported. Please upgrade= your libvirt" TSRMLS_CC); - RETURN_FALSE; - } - - if ((count_resources(INT_RESOURCE_CONNECTION TSRMLS_CC) + 1) > LIBVIRT= _G(max_connections_ini)) { - DPRINTF("%s: maximum number of connections allowed exceeded (max %= lu)\n", PHPFUNC, (unsigned long)LIBVIRT_G(max_connections_ini)); - set_error("Maximum number of connections allowed exceeded" TSRMLS_= CC); - RETURN_FALSE; - } - - /* If 'null' value has been passed as URL override url to NULL value t= o autodetect the hypervisor */ - if ((url =3D=3D NULL) || (strcasecmp(url, "NULL") =3D=3D 0)) - url =3D NULL; - - conn =3D (php_libvirt_connection *)emalloc(sizeof(php_libvirt_connecti= on)); - if (zcreds =3D=3D NULL) { - /* connecting without providing authentication */ - if (readonly) - conn->conn =3D virConnectOpenReadOnly(url); - else - conn->conn =3D virConnectOpen(url); - } else { - /* connecting with authentication (using callback) */ - arr_hash =3D Z_ARRVAL_P(zcreds); - array_count =3D zend_hash_num_elements(arr_hash); - - credscount =3D array_count; - creds =3D (php_libvirt_cred_value *)emalloc(credscount * sizeof(ph= p_libvirt_cred_value)); - j =3D 0; - /* parse the input Array and create list of credentials. The list = (array) is passed to callback function. */ - VIRT_FOREACH(arr_hash, pointer, data) { - if (Z_TYPE_P(data) =3D=3D IS_STRING) { - php_libvirt_hash_key_info info; - VIRT_HASH_CURRENT_KEY_INFO(arr_hash, pointer, index, info); - - if (info.type =3D=3D HASH_KEY_IS_STRING) { - PHPWRITE(info.name, info.length); - } else { - DPRINTF("%s: credentials index %d\n", PHPFUNC, (int)in= dex); - creds[j].type =3D index; - creds[j].result =3D (char *)emalloc(Z_STRLEN_P(data) += 1); - memset(creds[j].result, 0, Z_STRLEN_P(data) + 1); - creds[j].resultlen =3D Z_STRLEN_P(data); - strncpy(creds[j].result, Z_STRVAL_P(data), Z_STRLEN_P(= data)); - j++; - } - } - } VIRT_FOREACH_END(); - DPRINTF("%s: Found %d elements for credentials\n", PHPFUNC, j); - creds[0].count =3D j; - libvirt_virConnectAuth.cbdata =3D (void *)creds; - conn->conn =3D virConnectOpenAuth(url, &libvirt_virConnectAuth, re= adonly ? VIR_CONNECT_RO : 0); - for (i =3D 0; i < creds[0].count; i++) - efree(creds[i].result); - efree(creds); - } - - if (conn->conn =3D=3D NULL) { - DPRINTF("%s: Cannot establish connection to %s\n", PHPFUNC, url); - efree(conn); - RETURN_FALSE; - } - - resource_change_counter(INT_RESOURCE_CONNECTION, NULL, conn->conn, 1 T= SRMLS_CC); - DPRINTF("%s: Connection to %s established, returning %p\n", PHPFUNC, u= rl, conn->conn); - - VIRT_REGISTER_RESOURCE(conn, le_libvirt_connection); - conn->resource =3D VIRT_RESOURCE_HANDLE(return_value); -} - -/* * Function name: libvirt_node_get_info * Since version: 0.4.1(-1) * Description: Function is used to get the information about host nod= e, mainly total memory installed, total CPUs installed and model informatio= n are useful @@ -2531,258 +2299,6 @@ PHP_FUNCTION(libvirt_node_get_free_memory) } } =20 -//virsh capabilities | xpath '//capabilities/guest/arch[@name=3D"x86_64"]/= machine[@maxCpus=3D1]' - -/* - * Function name: libvirt_connect_get_machine_types - * Since version: 0.4.9 - * Description: Function is used to get machine types supported by hyp= ervisor on the conneciton - * Arguments: @conn [resource]: resource for connection - * Returns: array of machine types for the connection incl. maxCpu= s if appropriate - */ -PHP_FUNCTION(libvirt_connect_get_machine_types) -{ - zval *zconn; - php_libvirt_connection *conn =3D NULL; - char *caps =3D NULL; - char **ret =3D NULL; - int i, num =3D -1; - - GET_CONNECTION_FROM_ARGS("r", &zconn); - - caps =3D virConnectGetCapabilities(conn->conn); - if (caps =3D=3D NULL) - RETURN_FALSE; - - array_init(return_value); - - ret =3D get_array_from_xpath(caps, "//capabilities/guest/arch/@name", = &num); - if (ret !=3D NULL) { - for (i =3D 0; i < num; i++) { - int num2, j; - char tmp[1024] =3D { 0 }; - - snprintf(tmp, sizeof(tmp), "//capabilities/guest/arch[@name=3D= \"%s\"]/domain/@type", ret[i]); - char **ret2 =3D get_array_from_xpath(caps, tmp, &num2); - if (ret2 !=3D NULL) { - zval *arr2; - VIRT_ARRAY_INIT(arr2); - - for (j =3D 0; j < num2; j++) { - int num3, k; - char tmp2[1024] =3D { 0 }; - zval *arr3; - - VIRT_ARRAY_INIT(arr3); - - snprintf(tmp2, sizeof(tmp2), "//capabilities/guest/arc= h[@name=3D\"%s\"]/machine", - ret[i]); - - char **ret3 =3D get_array_from_xpath(caps, tmp2, &num3= ); - if (ret3 !=3D NULL) { - for (k =3D 0; k < num3; k++) { - char *numTmp =3D NULL; - char key[8] =3D { 0 }; - char tmp3[2048] =3D { 0 }; - - snprintf(key, sizeof(key), "%d", k); - //VIRT_ADD_ASSOC_STRING(arr2, key, ret3[k]); - - snprintf(tmp3, sizeof(tmp3), "//capabilities/g= uest/arch[@name=3D\"%s\"]/machine[text()=3D\"%s\"]/@maxCpus", - ret[i], ret3[k]); - - numTmp =3D get_string_from_xpath(caps, tmp3, N= ULL, NULL); - if (numTmp =3D=3D NULL) { - VIRT_ADD_ASSOC_STRING(arr2, key, ret3[k]); - } else { - zval *arr4; - VIRT_ARRAY_INIT(arr4); - VIRT_ADD_ASSOC_STRING(arr4, "name", ret3[k= ]); - VIRT_ADD_ASSOC_STRING(arr4, "maxCpus", num= Tmp); - - add_assoc_zval_ex(arr2, key, strlen(key) += 1, arr4); - free(numTmp); - } - - free(ret3[k]); - } - } - - /* Domain type specific */ - snprintf(tmp2, sizeof(tmp2), "//capabilities/guest/arc= h[@name=3D\"%s\"]/domain[@type=3D\"%s\"]/machine", - ret[i], ret2[j]); - - ret3 =3D get_array_from_xpath(caps, tmp2, &num3); - if (ret3 !=3D NULL) { - for (k =3D 0; k < num3; k++) { - char key[8] =3D { 0 }; - char tmp3[2048] =3D { 0 }; - char *numTmp =3D NULL; - - snprintf(key, sizeof(key), "%d", k); - snprintf(tmp3, sizeof(tmp3), - "//capabilities/guest/arch[@name=3D\"= %s\"]/domain[@type=3D\"%s\"]/machine[text()=3D\"%s\"]/@maxCpus", - ret[i], ret2[j], ret3[k]); - - numTmp =3D get_string_from_xpath(caps, tmp3, N= ULL, NULL); - if (numTmp =3D=3D NULL) { - VIRT_ADD_ASSOC_STRING(arr3, key, ret3[k]); - } else { - zval *arr4; - VIRT_ARRAY_INIT(arr4); - - VIRT_ADD_ASSOC_STRING(arr4, "name", ret3[k= ]); - VIRT_ADD_ASSOC_STRING(arr4, "maxCpus", num= Tmp); - - add_assoc_zval_ex(arr3, key, strlen(key) += 1, arr4); - free(numTmp); - } - - free(ret3[k]); - } - - add_assoc_zval_ex(arr2, ret2[j], strlen(ret2[j]) += 1, arr3); - } - } - //free(ret2[j]); - - add_assoc_zval_ex(return_value, ret[i], strlen(ret[i]) + 1= , arr2); - } - free(ret[i]); - } - } -} - -/* - * Function name: libvirt_connect_get_information - * Since version: 0.4.1(-2) - * Description: Function is used to get the information about the conn= ection - * Arguments: @conn [resource]: resource for connection - * Returns: array of information about the connection - */ -PHP_FUNCTION(libvirt_connect_get_information) -{ - zval *zconn; - char *tmp; - unsigned long hvVer =3D 0; - const char *type =3D NULL; - char hvStr[64] =3D { 0 }; - int iTmp =3D -1, maxvcpus =3D -1; - php_libvirt_connection *conn =3D NULL; - - GET_CONNECTION_FROM_ARGS("r", &zconn); - - tmp =3D virConnectGetURI(conn->conn); - DPRINTF("%s: Got connection URI of %s...\n", PHPFUNC, tmp); - array_init(return_value); - VIRT_ADD_ASSOC_STRING(return_value, "uri", tmp ? tmp : "unknown"); - free(tmp); - tmp =3D virConnectGetHostname(conn->conn); - VIRT_ADD_ASSOC_STRING(return_value, "hostname", tmp ? tmp : "unknown"); - free(tmp); - - if ((virConnectGetVersion(conn->conn, &hvVer) =3D=3D 0) && (type =3D v= irConnectGetType(conn->conn))) { - VIRT_ADD_ASSOC_STRING(return_value, "hypervisor", (char *)type); - add_assoc_long(return_value, "hypervisor_major", (long)((hvVer/100= 0000) % 1000)); - add_assoc_long(return_value, "hypervisor_minor", (long)((hvVer/100= 0) % 1000)); - add_assoc_long(return_value, "hypervisor_release", (long)(hvVer % = 1000)); - snprintf(hvStr, sizeof(hvStr), "%s %d.%d.%d", type, - (long)((hvVer/1000000) % 1000), (long)((hvVer/1000) % 100= 0), (long)(hvVer % 1000)); - VIRT_ADD_ASSOC_STRING(return_value, "hypervisor_string", hvStr); - } - - if (strcmp(type, "QEMU") =3D=3D 0) { - /* For QEMU the value is not reliable so we return -1 instead */ - maxvcpus =3D -1; - } else { - maxvcpus =3D virConnectGetMaxVcpus(conn->conn, type); - } - - add_assoc_long(return_value, "hypervisor_maxvcpus", maxvcpus); - iTmp =3D virConnectIsEncrypted(conn->conn); - if (iTmp =3D=3D 1) - VIRT_ADD_ASSOC_STRING(return_value, "encrypted", "Yes"); - else - if (iTmp =3D=3D 0) - VIRT_ADD_ASSOC_STRING(return_value, "encrypted", "No"); - else - VIRT_ADD_ASSOC_STRING(return_value, "encrypted", "unknown"); - - iTmp =3D virConnectIsSecure(conn->conn); - if (iTmp =3D=3D 1) - VIRT_ADD_ASSOC_STRING(return_value, "secure", "Yes"); - else - if (iTmp =3D=3D 0) - VIRT_ADD_ASSOC_STRING(return_value, "secure", "No"); - else - VIRT_ADD_ASSOC_STRING(return_value, "secure", "unknown"); - - add_assoc_long(return_value, "num_inactive_domains", virConnectNumOfDe= finedDomains(conn->conn)); - add_assoc_long(return_value, "num_inactive_interfaces", virConnectNumO= fDefinedInterfaces(conn->conn)); - add_assoc_long(return_value, "num_inactive_networks", virConnectNumOfD= efinedNetworks(conn->conn)); - add_assoc_long(return_value, "num_inactive_storagepools", virConnectNu= mOfDefinedStoragePools(conn->conn)); - - add_assoc_long(return_value, "num_active_domains", virConnectNumOfDoma= ins(conn->conn)); - add_assoc_long(return_value, "num_active_interfaces", virConnectNumOfI= nterfaces(conn->conn)); - add_assoc_long(return_value, "num_active_networks", virConnectNumOfNet= works(conn->conn)); - add_assoc_long(return_value, "num_active_storagepools", virConnectNumO= fStoragePools(conn->conn)); - - add_assoc_long(return_value, "num_total_domains", virConnectNumOfDomai= ns(conn->conn) + virConnectNumOfDefinedDomains(conn->conn)); - add_assoc_long(return_value, "num_total_interfaces", virConnectNumOfIn= terfaces(conn->conn) + virConnectNumOfDefinedInterfaces(conn->conn)); - add_assoc_long(return_value, "num_total_networks", virConnectNumOfNetw= orks(conn->conn) + virConnectNumOfDefinedNetworks(conn->conn)); - add_assoc_long(return_value, "num_total_storagepools", virConnectNumOf= StoragePools(conn->conn) + virConnectNumOfDefinedStoragePools(conn->conn)); - - add_assoc_long(return_value, "num_secrets", virConnectNumOfSecrets(con= n->conn)); - add_assoc_long(return_value, "num_nwfilters", virConnectNumOfNWFilters= (conn->conn)); -} - -/* - * Function name: libvirt_connect_get_uri - * Since version: 0.4.1(-1) - * Description: Function is used to get the connection URI. This is us= eful to check the hypervisor type of host machine when using "null" uri to = libvirt_connect() - * Arguments: @conn [resource]: resource for connection - * Returns: connection URI string or FALSE for error - */ -PHP_FUNCTION(libvirt_connect_get_uri) -{ - zval *zconn; - char *uri; - php_libvirt_connection *conn =3D NULL; - - GET_CONNECTION_FROM_ARGS("r", &zconn); - uri =3D virConnectGetURI(conn->conn); - DPRINTF("%s: virConnectGetURI returned %s\n", PHPFUNC, uri); - if (uri =3D=3D NULL) - RETURN_FALSE; - - VIRT_RETVAL_STRING(uri); - free(uri); -} - -/* - * Function name: libvirt_connect_get_hostname - * Since version: 0.4.1(-1) - * Description: Function is used to get the hostname of the guest asso= ciated with the connection - * Arguments: @conn [resource]: resource for connection - * Returns: hostname of the host node or FALSE for error - */ -PHP_FUNCTION(libvirt_connect_get_hostname) -{ - php_libvirt_connection *conn =3D NULL; - zval *zconn; - char *hostname; - - GET_CONNECTION_FROM_ARGS("r", &zconn); - - hostname =3D virConnectGetHostname(conn->conn); - DPRINTF("%s: virConnectGetHostname returned %s\n", PHPFUNC, hostname); - if (hostname =3D=3D NULL) - RETURN_FALSE; - - VIRT_RETVAL_STRING(hostname); - free(hostname); -} - /* * Function name: libvirt_image_create * Since version: 0.4.2 @@ -2904,197 +2420,6 @@ PHP_FUNCTION(libvirt_image_remove) } =20 /* - * Function name: libvirt_connect_get_hypervisor - * Since version: 0.4.1(-2) - * Description: Function is used to get the information about the hype= rvisor on the connection identified by the connection pointer - * Arguments: @conn [resource]: resource for connection - * Returns: array of hypervisor information if available - */ -PHP_FUNCTION(libvirt_connect_get_hypervisor) -{ - php_libvirt_connection *conn =3D NULL; - zval *zconn; - unsigned long hvVer =3D 0; - const char *type =3D NULL; - char hvStr[64] =3D { 0 }; - - GET_CONNECTION_FROM_ARGS("r", &zconn); - - if (virConnectGetVersion(conn->conn, &hvVer) !=3D 0) - RETURN_FALSE; - - type =3D virConnectGetType(conn->conn); - if (type =3D=3D NULL) - RETURN_FALSE; - - DPRINTF("%s: virConnectGetType returned %s\n", PHPFUNC, type); - - array_init(return_value); - VIRT_ADD_ASSOC_STRING(return_value, "hypervisor", (char *)type); - add_assoc_long(return_value, "major", (long)((hvVer/1000000) % 1000)); - add_assoc_long(return_value, "minor", (long)((hvVer/1000) % 1000)); - add_assoc_long(return_value, "release", (long)(hvVer % 1000)); - - snprintf(hvStr, sizeof(hvStr), "%s %d.%d.%d", type, - (long)((hvVer/1000000) % 1000), (long)((hvVer/1000) % 1000), = (long)(hvVer % 1000)); - VIRT_ADD_ASSOC_STRING(return_value, "hypervisor_string", hvStr); -} - -/* - * Function name: libvirt_connect_is_encrypted - * Since version: 0.4.1(-2) - * Description: Function is used to get the information whether the co= nnection is encrypted or not - * Arguments: @conn [resource]: resource for connection - * Returns: 1 if encrypted, 0 if not encrypted, -1 on error - */ -PHP_FUNCTION(libvirt_connect_get_encrypted) -{ - php_libvirt_connection *conn =3D NULL; - zval *zconn; - - GET_CONNECTION_FROM_ARGS("r", &zconn); - - RETURN_LONG(virConnectIsEncrypted(conn->conn)); -} - - -/* - * Function name: libvirt_connect_is_secure - * Since version: 0.4.1(-2) - * Description: Function is used to get the information whether the co= nnection is secure or not - * Arguments: @conn [resource]: resource for connection - * Returns: 1 if secure, 0 if not secure, -1 on error - */ -PHP_FUNCTION(libvirt_connect_get_secure) -{ - php_libvirt_connection *conn =3D NULL; - zval *zconn; - - GET_CONNECTION_FROM_ARGS("r", &zconn); - - RETURN_LONG(virConnectIsSecure(conn->conn)); -} - - -/* - * Function name: libvirt_connect_get_all_domain_stats - * Since version: 0.5.1(-1) - * Description: Query statistics for all domains on a given connection - * Arguments: @conn [resource]: resource for connection - * @stats [int]: the statistic groups from VIR_DOMAIN_STA= TS_* - * @flags [int]: the filter flags from VIR_CONNECT_GET_AL= L_DOMAINS_STATS_* - * Returns: assoc array with statistics or false on error - */ -PHP_FUNCTION(libvirt_connect_get_all_domain_stats) -{ - php_libvirt_connection *conn =3D NULL; - zval *zconn; - int retval =3D -1; - zend_long flags =3D 0; - zend_long stats =3D 0; - const char *name =3D NULL; - int i; - int j; - virTypedParameter params; - virDomainStatsRecordPtr *retstats =3D NULL; - - GET_CONNECTION_FROM_ARGS("r|l|l", &zconn, &stats, &flags); - - retval =3D virConnectGetAllDomainStats(conn->conn, stats, &retstats, f= lags); - - array_init(return_value); - if (retval < 0) - RETURN_FALSE; - - for (i =3D 0; i < retval; i++) { - zval *arr2; - VIRT_ARRAY_INIT(arr2); - - for (j =3D 0; j < retstats[i]->nparams; j++) { - params =3D retstats[i]->params[j]; - switch (params.type) { - case VIR_TYPED_PARAM_INT: - add_assoc_long(arr2, params.field, params.value.i); - break; - case VIR_TYPED_PARAM_UINT: - add_assoc_long(arr2, params.field, params.value.ui); - break; - case VIR_TYPED_PARAM_LLONG: - add_assoc_long(arr2, params.field, params.value.l); - break; - case VIR_TYPED_PARAM_ULLONG: - add_assoc_long(arr2, params.field, params.value.ul); - break; - case VIR_TYPED_PARAM_DOUBLE: - add_assoc_double(arr2, params.field, params.value.d); - break; - case VIR_TYPED_PARAM_BOOLEAN: - add_assoc_bool(arr2, params.field, params.value.b); - break; - case VIR_TYPED_PARAM_STRING: - VIRT_ADD_ASSOC_STRING(arr2, params.field, params.value.s); - break; - } - } - name =3D virDomainGetName(retstats[i]->dom); -#if PHP_MAJOR_VERSION >=3D 7 - zend_hash_update(Z_ARRVAL_P(return_value), zend_string_init(name, = strlen(name), 0), arr2); -#else - zend_hash_update(Z_ARRVAL_P(return_value), name, strlen(name)+1, &= arr2, sizeof(arr2), NULL); -#endif - } - - virDomainStatsRecordListFree(retstats); -} - - - -/* - * Function name: libvirt_connect_get_maxvcpus - * Since version: 0.4.1(-2) - * Description: Function is used to get maximum number of VCPUs per VM= on the hypervisor connection - * Arguments: @conn [resource]: resource for connection - * Returns: number of VCPUs available per VM on the connection or = FALSE for error - */ -PHP_FUNCTION(libvirt_connect_get_maxvcpus) -{ - php_libvirt_connection *conn =3D NULL; - zval *zconn; - const char *type =3D NULL; - - GET_CONNECTION_FROM_ARGS("r", &zconn); - - type =3D virConnectGetType(conn->conn); - if (type =3D=3D NULL) - RETURN_FALSE; - - RETURN_LONG(virConnectGetMaxVcpus(conn->conn, type)); -} - -/* - * Function name: libvirt_connect_get_sysinfo - * Since version: 0.4.1(-2) - * Description: Function is used to get the system information from co= nnection if available - * Arguments: @conn [resource]: resource for connection - * Returns: XML description of system information from the connect= ion or FALSE for error - */ -PHP_FUNCTION(libvirt_connect_get_sysinfo) -{ - php_libvirt_connection *conn =3D NULL; - zval *zconn; - char *sysinfo; - - GET_CONNECTION_FROM_ARGS("r", &zconn); - - sysinfo =3D virConnectGetSysinfo(conn->conn, 0); - if (sysinfo =3D=3D NULL) - RETURN_FALSE; - - VIRT_RETVAL_STRING(sysinfo); - free(sysinfo); -} - -/* * Private function name: get_string_from_xpath * Since version: 0.4.1(-1) * Description: Function is used to get the XML xPath expressi= on from the XML document. This can be added to val array if not NULL. @@ -5102,240 +4427,6 @@ PHP_FUNCTION(libvirt_domain_get_next_dev_ids) add_assoc_long(return_value, "next_func", func); } =20 -/* - * Function name: libvirt_connect_get_capabilities - * Since version: 0.4.1(-2) - * Description: Function is used to get the capabilities information f= rom the connection - * Arguments: @conn [resource]: resource for connection - * @xpath [string]: optional xPath query to be applied on= the result - * Returns: capabilities XML from the connection or FALSE for error - */ -PHP_FUNCTION(libvirt_connect_get_capabilities) -{ - php_libvirt_connection *conn =3D NULL; - zval *zconn; - char *caps; - char *xpath =3D NULL; - strsize_t xpath_len; - char *tmp =3D NULL; - int retval =3D -1; - - GET_CONNECTION_FROM_ARGS("r|s", &zconn, &xpath, &xpath_len); - - caps =3D virConnectGetCapabilities(conn->conn); - if (caps =3D=3D NULL) - RETURN_FALSE; - - tmp =3D get_string_from_xpath(caps, xpath, NULL, &retval); - if ((tmp =3D=3D NULL) || (retval < 0)) { - VIRT_RETVAL_STRING(caps); - } else { - VIRT_RETVAL_STRING(tmp); - } - - free(caps); - free(tmp); -} - -/* - * Function name: libvirt_connect_get_emulator - * Since version: 0.4.5 - * Description: Function is used to get the emulator for requested con= nection/architecture - * Arguments: @conn [resource]: libvirt connection resource - * @arch [string]: optional architecture string, can be N= ULL to get default - * Returns: path to the emulator - */ -PHP_FUNCTION(libvirt_connect_get_emulator) -{ - php_libvirt_connection *conn =3D NULL; - zval *zconn; - char *arch =3D NULL; - strsize_t arch_len; - char *tmp; - - GET_CONNECTION_FROM_ARGS("r|s", &zconn, &arch, &arch_len); - - if ((arch =3D=3D NULL) || (arch_len =3D=3D 0)) - arch =3D NULL; - - tmp =3D connection_get_emulator(conn->conn, arch TSRMLS_CC); - if (tmp =3D=3D NULL) { - set_error("Cannot get emulator" TSRMLS_CC); - RETURN_FALSE; - } - - VIRT_RETVAL_STRING(tmp); - free(tmp); -} - -/* - * Function name: libvirt_connect_get_nic_models - * Since version: 0.4.9 - * Description: Function is used to get NIC models for requested conne= ction/architecture - * Arguments: @conn [resource]: libvirt connection resource - * @arch [string]: optional architecture string, can be N= ULL to get default - * Returns: array of models - */ -PHP_FUNCTION(libvirt_connect_get_nic_models) -{ - php_libvirt_connection *conn =3D NULL; - zval *zconn; - char *arch =3D NULL; - strsize_t arch_len; - char *tmp; - - GET_CONNECTION_FROM_ARGS("r|s", &zconn, &arch, &arch_len); - - /* Disable getting it on remote connections */ - if (!is_local_connection(conn->conn)) { - set_error("This function works only on local connections" TSRMLS_C= C); - RETURN_FALSE; - } - - /* This approach is working only for QEMU driver so bails if not curre= ntly using it */ - if (strcmp(virConnectGetType(conn->conn), "QEMU") !=3D 0) { - set_error("This function can be used only for QEMU driver" TSRMLS_= CC); - RETURN_FALSE; - } - -#ifndef EXTWIN - if ((arch =3D=3D NULL) || (arch_len =3D=3D 0)) - arch =3D NULL; - - tmp =3D connection_get_emulator(conn->conn, arch TSRMLS_CC); - if (tmp =3D=3D NULL) { - set_error("Cannot get emulator" TSRMLS_CC); - RETURN_FALSE; - } - - char cmd[4096] =3D { 0 }; - char tmp2[16] =3D { 0 }; - snprintf(cmd, sizeof(cmd), "%s -net nic,model=3D? 2>&1", tmp); - - FILE *fp =3D popen(cmd, "r"); - if (fp =3D=3D NULL) - RETURN_FALSE; - - array_init(return_value); - while (!feof(fp)) { - memset(cmd, 0, sizeof(cmd)); - if (!fgets(cmd, sizeof(cmd), fp)) - break; - - if ((tmp =3D strstr(cmd, "Supported NIC models:")) !=3D NULL) { - tmp =3D strstr(tmp, ":") + 2; - - int i; - tTokenizer t =3D tokenize(tmp, ","); - for (i =3D 0; i < t.numTokens; i++) { - snprintf(tmp2, sizeof(tmp2), "%d", i); - VIRT_ADD_ASSOC_STRING(return_value, tmp2, t.tokens[i]); - } - free_tokens(t); - } - } - fclose(fp); -#endif -} - -/* - * Function name: libvirt_connect_get_soundhw_models - * Since version: 0.4.9 - * Description: Function is used to get sound hardware models for requ= ested connection/architecture - * Arguments: @conn [resource]: libvirt connection resource - * @arch [string]: optional architecture string, can be N= ULL to get default - * @flags [int]: flags for getting sound hardware. Can be= either 0 or VIR_CONNECT_SOUNDHW_GET_NAMES - * Returns: array of models - */ -PHP_FUNCTION(libvirt_connect_get_soundhw_models) -{ - php_libvirt_connection *conn =3D NULL; - zval *zconn; - char *arch =3D NULL; - strsize_t arch_len; - char *tmp; - zend_long flags =3D 0; - - GET_CONNECTION_FROM_ARGS("r|sl", &zconn, &arch, &arch_len, &flags); - - if ((arch =3D=3D NULL) || (arch_len =3D=3D 0)) - arch =3D NULL; - - /* Disable getting it on remote connections */ - if (!is_local_connection(conn->conn)) { - set_error("This function works only on local connections" TSRMLS_C= C); - RETURN_FALSE; - } - -#ifndef EXTWIN - /* This approach is working only for QEMU driver so bails if not curre= ntly using it */ - if (strcmp(virConnectGetType(conn->conn), "QEMU") !=3D 0) { - set_error("This function can be used only for QEMU driver" TSRMLS_= CC); - RETURN_FALSE; - } - - tmp =3D connection_get_emulator(conn->conn, arch TSRMLS_CC); - if (tmp =3D=3D NULL) { - set_error("Cannot get emulator" TSRMLS_CC); - RETURN_FALSE; - } - - char cmd[4096] =3D { 0 }; - snprintf(cmd, sizeof(cmd), "%s -soundhw help 2>&1", tmp); - - FILE *fp =3D popen(cmd, "r"); - if (fp =3D=3D NULL) - RETURN_FALSE; - - short inFunc =3D 0; - - int n =3D 0; - array_init(return_value); - while (!feof(fp)) { - memset(cmd, 0, sizeof(cmd)); - if (!fgets(cmd, sizeof(cmd), fp)) - break; - - if (strncmp(cmd, "Valid ", 6) =3D=3D 0) { - inFunc =3D 1; - continue; - } else - if (strlen(cmd) < 2) - inFunc =3D 0; - - if (inFunc) { - int i =3D 0; - char desc[1024] =3D { 0 }; - tTokenizer t =3D tokenize(cmd, " "); - if (t.numTokens =3D=3D 0) - continue; - - if ((i > 0) && (flags & CONNECT_FLAG_SOUNDHW_GET_NAMES)) { - zval *arr; - memset(desc, 0, sizeof(desc)); - for (i =3D 1; i < t.numTokens; i++) { - strcat(desc, t.tokens[i]); - if (i < t.numTokens - 1) - strcat(desc, " "); - } - - VIRT_ARRAY_INIT(arr); - VIRT_ADD_ASSOC_STRING(arr, "name", t.tokens[0]); - VIRT_ADD_ASSOC_STRING(arr, "description", desc); - add_next_index_zval(return_value, arr); - } else { - char tmp2[16] =3D { 0 }; - snprintf(tmp2, sizeof(tmp2), "%d", n++); - VIRT_ADD_ASSOC_STRING(return_value, tmp2, t.tokens[0]); - } - - free_tokens(t); - } - } - fclose(fp); -#endif -} - void parse_array(zval *arr, tVMDisk *disk, tVMNetwork *network) { HashTable *arr_hash; diff --git a/src/libvirt-php.h b/src/libvirt-php.h index 66be53a..6cbcd27 100644 --- a/src/libvirt-php.h +++ b/src/libvirt-php.h @@ -7,7 +7,6 @@ #ifndef PHP_LIBVIRT_H #define PHP_LIBVIRT_H 1 =20 - /* Network constants */ #define VIR_NETWORKS_ACTIVE 1 #define VIR_NETWORKS_INACTIVE 2 @@ -50,10 +49,10 @@ #endif =20 #ifndef VERSION -#define VERSION "0.5.1" +#define VERSION "0.5.5" #define VERSION_MAJOR 0 #define VERSION_MINOR 5 -#define VERSION_MICRO 1 +#define VERSION_MICRO 5 #endif =20 #include @@ -109,17 +108,15 @@ typedef uint64_t arch_uint; #define UINTx PRIx64 #endif =20 -typedef struct tTokenizer { - char **tokens; - int numTokens; -} tTokenizer; +# define DEBUG_SUPPORT =20 -typedef struct _resource_info { - int type; - virConnectPtr conn; - void *mem; - int overwrite; -} resource_info; +# ifdef DEBUG_SUPPORT +# define DEBUG_CORE +# define DEBUG_VNC +# endif + +/* PHP functions are prefixed with `zif_` so strip it */ +# define PHPFUNC (__FUNCTION__ + 4) =20 #ifdef ZTS #define LIBVIRT_G(v) TSRMG(libvirt_globals_id, zend_libvirt_globals *, v) @@ -130,9 +127,6 @@ typedef struct _resource_info { #define PHP_LIBVIRT_WORLD_VERSION VERSION #define PHP_LIBVIRT_WORLD_EXTNAME "libvirt" =20 -/* Connect flags */ -#define CONNECT_FLAG_SOUNDHW_GET_NAMES 0x01 - /* Domain flags */ #define DOMAIN_FLAG_FEATURE_ACPI 0x01 #define DOMAIN_FLAG_FEATURE_APIC 0x02 @@ -147,7 +141,6 @@ typedef struct _resource_info { #define DOMAIN_DISK_ACCESS_ALL 0x04 =20 /* Internal resource identifier objects */ -#define INT_RESOURCE_CONNECTION 0x01 #define INT_RESOURCE_DOMAIN 0x02 #define INT_RESOURCE_NETWORK 0x04 #define INT_RESOURCE_NODEDEV 0x08 @@ -157,6 +150,18 @@ typedef struct _resource_info { #define INT_RESOURCE_STREAM 0x50 #define INT_RESOURCE_NWFILTER 0x60 =20 +typedef struct tTokenizer { + char **tokens; + int numTokens; +} tTokenizer; + +typedef struct _resource_info { + int type; + virConnectPtr conn; + void *mem; + int overwrite; +} resource_info; + typedef struct tVMDisk { char *path; char *driver; @@ -172,22 +177,10 @@ typedef struct tVMNetwork { char *model; } tVMNetwork; =20 -/* TODO: Temporary due to code movement to util.h - will be removed when - * libvirt-connection.h is separated out - */ -#if PHP_MAJOR_VERSION >=3D 7 -typedef zend_resource virt_resource; -typedef virt_resource *virt_resource_handle; -#else -typedef long virt_resource_handle; -#endif +/* TODO: temporary forward declaration until other parts are "modularized"= */ +typedef struct _php_libvirt_connection php_libvirt_connection; =20 /* Libvirt-php types */ -typedef struct _php_libvirt_connection { - virConnectPtr conn; - virt_resource_handle resource; -} php_libvirt_connection; - typedef struct _php_libvirt_stream { virStreamPtr stream; php_libvirt_connection* conn; @@ -228,25 +221,42 @@ typedef struct _php_libvirt_nwfilter { php_libvirt_connection* conn; } php_libvirt_nwfilter; =20 -typedef struct _php_libvirt_cred_value { - int count; - int type; - char *result; - unsigned int resultlen; -} php_libvirt_cred_value; - typedef struct _php_libvirt_hash_key_info { char *name; unsigned int length; unsigned int type; } php_libvirt_hash_key_info; =20 +ZEND_BEGIN_MODULE_GLOBALS(libvirt) + char *last_error; + char *vnc_location; + zend_bool longlong_to_string_ini; + char *iso_path_ini; + char *image_path_ini; + zend_long max_connections_ini; +# ifdef DEBUG_SUPPORT + int debug; +# endif + resource_info *binding_resources; + int binding_resources_count; +ZEND_END_MODULE_GLOBALS(libvirt) + +ZEND_DECLARE_MODULE_GLOBALS(libvirt) + /* Private definitions */ +void set_error(char *msg TSRMLS_DC); +void reset_error(TSRMLS_D); +int count_resources(int type TSRMLS_DC); +int resource_change_counter(int type, virConnectPtr conn, void *mem, int i= nc TSRMLS_DC); +void free_resource(int type, void *mem TSRMLS_DC); +char *connection_get_emulator(virConnectPtr conn, char *arch TSRMLS_DC); +int is_local_connection(virConnectPtr conn); +tTokenizer tokenize(char *string, char *by); +void free_tokens(tTokenizer t); int set_logfile(char *filename, long maxsize TSRMLS_DC); char *get_string_from_xpath(char *xml, char *xpath, zval **val, int *retVa= l); char **get_array_from_xpath(char *xml, char *xpath, int *num); =20 -#define PHP_LIBVIRT_CONNECTION_RES_NAME "Libvirt connection" #define PHP_LIBVIRT_DOMAIN_RES_NAME "Libvirt domain" #define PHP_LIBVIRT_STREAM_RES_NAME "Libvirt stream" #define PHP_LIBVIRT_STORAGEPOOL_RES_NAME "Libvirt storagepool" @@ -264,22 +274,6 @@ PHP_MINFO_FUNCTION(libvirt); =20 /* Common functions */ PHP_FUNCTION(libvirt_get_last_error); -/* Connect functions */ -PHP_FUNCTION(libvirt_connect); -PHP_FUNCTION(libvirt_connect_get_uri); -PHP_FUNCTION(libvirt_connect_get_hostname); -PHP_FUNCTION(libvirt_connect_get_hypervisor); -PHP_FUNCTION(libvirt_connect_get_capabilities); -PHP_FUNCTION(libvirt_connect_get_emulator); -PHP_FUNCTION(libvirt_connect_get_nic_models); -PHP_FUNCTION(libvirt_connect_get_soundhw_models); -PHP_FUNCTION(libvirt_connect_get_maxvcpus); -PHP_FUNCTION(libvirt_connect_get_sysinfo); -PHP_FUNCTION(libvirt_connect_get_encrypted); -PHP_FUNCTION(libvirt_connect_get_secure); -PHP_FUNCTION(libvirt_connect_get_information); -PHP_FUNCTION(libvirt_connect_get_machine_types); -PHP_FUNCTION(libvirt_connect_get_all_domain_stats); /* Node functions */ PHP_FUNCTION(libvirt_node_get_info); PHP_FUNCTION(libvirt_node_get_cpu_stats); diff --git a/src/util.h b/src/util.h index 6400164..167bd90 100644 --- a/src/util.h +++ b/src/util.h @@ -10,13 +10,6 @@ # include # include "libvirt-php.h" =20 -# define DEBUG_SUPPORT - -# ifdef DEBUG_SUPPORT -# define DEBUG_CORE -# define DEBUG_VNC -# endif - # define DEBUG_INIT(source) \ static const char *debugSource =3D "" source "" =20 --=20 2.13.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list