本文整理汇总了C++中NULLSTR函数的典型用法代码示例。如果您正苦于以下问题:C++ NULLSTR函数的具体用法?C++ NULLSTR怎么用?C++ NULLSTR使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了NULLSTR函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: _yapi_desc
static int
_yapi_desc(const cint_parameter_desc_t *desc, int level)
{
int dim_index;
_yapi_indent(level);
CINT_PRINTF("basetype: %s\n", NULLSTR(desc->basetype));
_yapi_indent(level);
CINT_PRINTF("pcount: %d\n", desc->pcount);
_yapi_indent(level);
CINT_PRINTF("name: %s\n", NULLSTR(desc->name));
_yapi_indent(level);
CINT_PRINTF(
"arrayDimensions: %d\n",
desc->utype.declaration.arrayDimensions);
for(dim_index = 0;
dim_index < desc->utype.declaration.arrayDimensions;
++dim_index) {
_yapi_indent(level);
CINT_PRINTF(
"dimensions[%d]: %d\n",
dim_index,
desc->dimensions[dim_index]);
}
_yapi_indent(level);
CINT_PRINTF("flags: %d\n", desc->flags);
return 0;
}
示例2: do_chsave
void do_chsave( CHAR_DATA *ch, char *argument )
{
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
char buf[MSL];
argument = one_argument( argument, arg1 );
argument = one_argument( argument, arg2 );
if ( IS_NPC(ch) )
return;
if (!ch->desc || NULLSTR(arg1) )
{
send_to_char("Syntax: chsave load/save\n\r",ch);
send_to_char("Syntax: chsave delete (change number)\n\r",ch);
return;
}
if ( !str_cmp(arg1,"load") )
{
load_changes( );
send_to_char("Changes Loaded.\n\r",ch);
return;
}
if ( !str_cmp(arg1,"save") )
{
save_changes( );
send_to_char("Changes Saved.\n\r",ch);
return;
}
if ( !str_cmp(arg1, "delete"))
{
int num;
if ( NULLSTR(arg2) || !is_number( arg2 ) )
{
send_to_char("For chsave delete, you must provide a change number.\n\r",ch);
send_to_char("Syntax: chsave delete (change number)\n\r",ch);
return;
}
num = atoi( arg2 );
if ( num < 0 || num > maxChanges )
{
sprintf( buf, "Valid changes are from 0 to %d.\n\r", maxChanges );
send_to_char( buf, ch );
return;
}
delete_change( num );
send_to_char("Change deleted.\n\r",ch);
return;
}
return;
}
示例3: qemuAgentSend
/**
* qemuAgentSend:
* @mon: Monitor
* @msg: Message
* @seconds: number of seconds to wait for the result, it can be either
* -2, -1, 0 or positive.
*
* Send @msg to agent @mon. If @seconds is equal to
* VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK(-2), this function will block forever
* waiting for the result. The value of
* VIR_DOMAIN_QEMU_AGENT_COMMAND_DEFAULT(-1) means use default timeout value
* and VIR_DOMAIN_QEMU_AGENT_COMMAND_NOWAIT(0) makes this this function return
* immediately without waiting. Any positive value means the number of seconds
* to wait for the result.
*
* Returns: 0 on success,
* -2 on timeout,
* -1 otherwise
*/
static int qemuAgentSend(qemuAgentPtr mon,
qemuAgentMessagePtr msg,
int seconds)
{
int ret = -1;
unsigned long long then = 0;
/* Check whether qemu quit unexpectedly */
if (mon->lastError.code != VIR_ERR_OK) {
VIR_DEBUG("Attempt to send command while error is set %s",
NULLSTR(mon->lastError.message));
virSetError(&mon->lastError);
return -1;
}
if (seconds > VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK) {
unsigned long long now;
if (virTimeMillisNow(&now) < 0)
return -1;
if (seconds == VIR_DOMAIN_QEMU_AGENT_COMMAND_DEFAULT)
seconds = QEMU_AGENT_WAIT_TIME;
then = now + seconds * 1000ull;
}
mon->msg = msg;
qemuAgentUpdateWatch(mon);
while (!mon->msg->finished) {
if ((then && virCondWaitUntil(&mon->notify, &mon->parent.lock, then) < 0) ||
(!then && virCondWait(&mon->notify, &mon->parent.lock) < 0)) {
if (errno == ETIMEDOUT) {
virReportError(VIR_ERR_AGENT_UNRESPONSIVE, "%s",
_("Guest agent not available for now"));
ret = -2;
} else {
virReportSystemError(errno, "%s",
_("Unable to wait on agent monitor "
"condition"));
}
goto cleanup;
}
}
if (mon->lastError.code != VIR_ERR_OK) {
VIR_DEBUG("Send command resulted in error %s",
NULLSTR(mon->lastError.message));
virSetError(&mon->lastError);
goto cleanup;
}
ret = 0;
cleanup:
mon->msg = NULL;
qemuAgentUpdateWatch(mon);
return ret;
}
示例4: virNetDevVethCreate
/**
* virNetDevVethCreate:
* @veth1: pointer to name for parent end of veth pair
* @veth2: pointer to return name for container end of veth pair
*
* Creates a veth device pair using the ip command:
* ip link add veth1 type veth peer name veth2
* If veth1 points to NULL on entry, it will be a valid interface on
* return. veth2 should point to NULL on entry.
*
* NOTE: If veth1 and veth2 names are not specified, ip will auto assign
* names. There seems to be two problems here -
* 1) There doesn't seem to be a way to determine the names of the
* devices that it creates. They show up in ip link show and
* under /sys/class/net/ however there is no guarantee that they
* are the devices that this process just created.
* 2) Once one of the veth devices is moved to another namespace, it
* is no longer visible in the parent namespace. This seems to
* confuse the name assignment causing it to fail with File exists.
* Because of these issues, this function currently allocates names
* prior to using the ip command, and returns any allocated names
* to the caller.
*
* Returns 0 on success or -1 in case of error
*/
int virNetDevVethCreate(char** veth1, char** veth2)
{
int rc = -1;
const char *argv[] = {
"ip", "link", "add", NULL, "type", "veth", "peer", "name", NULL, NULL
};
int vethDev = 0;
bool veth1_alloc = false;
bool veth2_alloc = false;
VIR_DEBUG("Host: %s guest: %s", NULLSTR(*veth1), NULLSTR(*veth2));
if (*veth1 == NULL) {
if ((vethDev = virNetDevVethGetFreeName(veth1, vethDev)) < 0)
goto cleanup;
VIR_DEBUG("Assigned host: %s", *veth1);
veth1_alloc = true;
vethDev++;
}
argv[3] = *veth1;
while (*veth2 == NULL) {
if ((vethDev = virNetDevVethGetFreeName(veth2, vethDev)) < 0) {
if (veth1_alloc)
VIR_FREE(*veth1);
goto cleanup;
}
/* Just make sure they didn't accidentally get same name */
if (STREQ(*veth1, *veth2)) {
vethDev++;
VIR_FREE(*veth2);
continue;
}
VIR_DEBUG("Assigned guest: %s", *veth2);
veth2_alloc = true;
}
argv[8] = *veth2;
VIR_DEBUG("Create Host: %s guest: %s", *veth1, *veth2);
if (virRun(argv, NULL) < 0) {
if (veth1_alloc)
VIR_FREE(*veth1);
if (veth2_alloc)
VIR_FREE(*veth2);
goto cleanup;
}
rc = 0;
cleanup:
return rc;
}
示例5: qemuAgentSend
/**
* qemuAgentSend:
* @mon: Monitor
* @msg: Message
* @timeout: use timeout?
*
* Send @msg to agent @mon.
* Wait max QEMU_AGENT_WAIT_TIME for agent
* to reply.
*
* Returns: 0 on success,
* -2 on timeout,
* -1 otherwise
*/
static int qemuAgentSend(qemuAgentPtr mon,
qemuAgentMessagePtr msg,
bool timeout)
{
int ret = -1;
unsigned long long now, then = 0;
/* Check whether qemu quit unexpectedly */
if (mon->lastError.code != VIR_ERR_OK) {
VIR_DEBUG("Attempt to send command while error is set %s",
NULLSTR(mon->lastError.message));
virSetError(&mon->lastError);
return -1;
}
if (timeout) {
if (virTimeMillisNow(&now) < 0)
return -1;
then = now + QEMU_AGENT_WAIT_TIME;
}
mon->msg = msg;
qemuAgentUpdateWatch(mon);
while (!mon->msg->finished) {
if ((timeout && virCondWaitUntil(&mon->notify, &mon->lock, then) < 0) ||
(!timeout && virCondWait(&mon->notify, &mon->lock) < 0)) {
if (errno == ETIMEDOUT) {
qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Guest agent not available for now"));
ret = -2;
} else {
qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to wait on monitor condition"));
}
goto cleanup;
}
}
if (mon->lastError.code != VIR_ERR_OK) {
VIR_DEBUG("Send command resulted in error %s",
NULLSTR(mon->lastError.message));
virSetError(&mon->lastError);
goto cleanup;
}
ret = 0;
cleanup:
mon->msg = NULL;
qemuAgentUpdateWatch(mon);
return ret;
}
示例6: hyperyVerifyResponse
int
hyperyVerifyResponse(WsManClient *client, WsXmlDocH response,
const char *detail)
{
int lastError = wsmc_get_last_error(client);
int responseCode = wsmc_get_response_code(client);
WsManFault *fault;
if (lastError != WS_LASTERR_OK) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Transport error during %s: %s (%d)"),
detail, wsman_transport_get_last_error_string(lastError),
lastError);
return -1;
}
/* Check the HTTP response code and report an error if it's not 200 (OK),
* 400 (Bad Request) or 500 (Internal Server Error) */
if (responseCode != 200 && responseCode != 400 && responseCode != 500) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Unexpected HTTP response during %s: %d"),
detail, responseCode);
return -1;
}
if (response == NULL) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Empty response during %s"), detail);
return -1;
}
if (wsmc_check_for_fault(response)) {
fault = wsmc_fault_new();
if (fault == NULL) {
virReportOOMError();
return -1;
}
wsmc_get_fault_data(response, fault);
virReportError(VIR_ERR_INTERNAL_ERROR,
_("SOAP fault during %s: code '%s', subcode '%s', "
"reason '%s', detail '%s'"),
detail, NULLSTR(fault->code), NULLSTR(fault->subcode),
NULLSTR(fault->reason), NULLSTR(fault->fault_detail));
wsmc_fault_destroy(fault);
return -1;
}
return 0;
}
示例7: virCPUUpdate
/**
* virCPUUpdate:
*
* @arch: CPU architecture
* @guest: guest CPU definition to be updated
* @host: host CPU definition
*
* Updates @guest CPU definition according to @host CPU. This is required to
* support guest CPU definitions specified relatively to host CPU, such as
* CPUs with VIR_CPU_MODE_CUSTOM and optional features or
* VIR_CPU_MATCH_MINIMUM, or CPUs with VIR_CPU_MODE_HOST_MODEL.
* When the guest CPU was not specified relatively, the function does nothing
* and returns success.
*
* Returns 0 on success, -1 on error.
*/
int
virCPUUpdate(virArch arch,
virCPUDefPtr guest,
const virCPUDef *host)
{
struct cpuArchDriver *driver;
VIR_DEBUG("arch=%s, guest=%p mode=%s model=%s, host=%p model=%s",
virArchToString(arch), guest, virCPUModeTypeToString(guest->mode),
NULLSTR(guest->model), host, NULLSTR(host ? host->model : NULL));
if (!(driver = cpuGetSubDriver(arch)))
return -1;
if (guest->mode == VIR_CPU_MODE_HOST_PASSTHROUGH)
return 0;
if (guest->mode == VIR_CPU_MODE_CUSTOM &&
guest->match != VIR_CPU_MATCH_MINIMUM) {
size_t i;
bool optional = false;
for (i = 0; i < guest->nfeatures; i++) {
if (guest->features[i].policy == VIR_CPU_FEATURE_OPTIONAL) {
optional = true;
break;
}
}
if (!optional)
return 0;
}
/* We get here if guest CPU is either
* - host-model
* - custom with minimum match
* - custom with optional features
*/
if (!driver->update) {
virReportError(VIR_ERR_NO_SUPPORT,
_("cannot update guest CPU for %s architecture"),
virArchToString(arch));
return -1;
}
if (driver->update(guest, host) < 0)
return -1;
VIR_DEBUG("model=%s", NULLSTR(guest->model));
return 0;
}
示例8: cpuCompareXML
virCPUCompareResult
cpuCompareXML(virCPUDefPtr host,
const char *xml)
{
xmlDocPtr doc = NULL;
xmlXPathContextPtr ctxt = NULL;
virCPUDefPtr cpu = NULL;
virCPUCompareResult ret = VIR_CPU_COMPARE_ERROR;
VIR_DEBUG("host=%p, xml=%s", host, NULLSTR(xml));
if (!(doc = virXMLParseStringCtxt(xml, _("(CPU_definition)"), &ctxt)))
goto cleanup;
cpu = virCPUDefParseXML(ctxt->node, ctxt, VIR_CPU_TYPE_AUTO);
if (cpu == NULL)
goto cleanup;
if (!cpu->model) {
virCPUReportError(VIR_ERR_OPERATION_INVALID,
"%s", _("no CPU model specified"));
goto cleanup;
}
ret = cpuCompare(host, cpu);
cleanup:
virCPUDefFree(cpu);
xmlXPathFreeContext(ctxt);
xmlFreeDoc(doc);
return ret;
}
示例9: qemuTeardownImageCgroup
int
qemuTeardownImageCgroup(virDomainObjPtr vm,
virStorageSourcePtr src)
{
qemuDomainObjPrivatePtr priv = vm->privateData;
int perms = VIR_CGROUP_DEVICE_READ |
VIR_CGROUP_DEVICE_WRITE |
VIR_CGROUP_DEVICE_MKNOD;
int ret;
if (!virCgroupHasController(priv->cgroup,
VIR_CGROUP_CONTROLLER_DEVICES))
return 0;
if (!src->path || !virStorageSourceIsLocalStorage(src)) {
VIR_DEBUG("Not updating cgroups for disk path '%s', type: %s",
NULLSTR(src->path), virStorageTypeToString(src->type));
return 0;
}
VIR_DEBUG("Deny path %s", src->path);
ret = virCgroupDenyDevicePath(priv->cgroup, src->path, perms, true);
virDomainAuditCgroupPath(vm, priv->cgroup, "deny", src->path,
virCgroupGetDevicePermsString(perms), ret == 0);
return ret;
}
示例10: virCPUCompareXML
/**
* virCPUCompareXML:
*
* @arch: CPU architecture
* @host: host CPU definition
* @xml: XML description of either guest or host CPU to be compared with @host
* @failIncompatible: return an error instead of VIR_CPU_COMPARE_INCOMPATIBLE
*
* Compares the CPU described by @xml with @host CPU.
*
* Returns VIR_CPU_COMPARE_ERROR on error, VIR_CPU_COMPARE_INCOMPATIBLE when
* the two CPUs are incompatible, VIR_CPU_COMPARE_IDENTICAL when the two CPUs
* are identical, VIR_CPU_COMPARE_SUPERSET when the @xml CPU is a superset of
* the @host CPU. If @failIncompatible is true, the function will return
* VIR_CPU_COMPARE_ERROR (and set VIR_ERR_CPU_INCOMPATIBLE error) when the
* two CPUs are incompatible.
*/
virCPUCompareResult
virCPUCompareXML(virArch arch,
virCPUDefPtr host,
const char *xml,
bool failIncompatible)
{
xmlDocPtr doc = NULL;
xmlXPathContextPtr ctxt = NULL;
virCPUDefPtr cpu = NULL;
virCPUCompareResult ret = VIR_CPU_COMPARE_ERROR;
VIR_DEBUG("arch=%s, host=%p, xml=%s",
virArchToString(arch), host, NULLSTR(xml));
if (!xml) {
virReportError(VIR_ERR_INVALID_ARG, "%s", _("missing CPU definition"));
goto cleanup;
}
if (!(doc = virXMLParseStringCtxt(xml, _("(CPU_definition)"), &ctxt)))
goto cleanup;
if (virCPUDefParseXML(ctxt, NULL, VIR_CPU_TYPE_AUTO, &cpu) < 0)
goto cleanup;
ret = virCPUCompare(arch, host, cpu, failIncompatible);
cleanup:
virCPUDefFree(cpu);
xmlXPathFreeContext(ctxt);
xmlFreeDoc(doc);
return ret;
}
示例11: testQemuDiskXMLToPropsValidateSchema
static int
testQemuDiskXMLToPropsValidateSchema(const void *opaque)
{
struct testQemuDiskXMLToJSONData *data = (void *) opaque;
virBuffer debug = VIR_BUFFER_INITIALIZER;
char *propsstr = NULL;
char *debugmsg = NULL;
int ret = 0;
size_t i;
if (data->fail)
return EXIT_AM_SKIP;
for (i = 0; i < data->nprops; i++) {
if (testQEMUSchemaValidate(data->props[i], data->schemaroot,
data->schema, &debug) < 0) {
debugmsg = virBufferContentAndReset(&debug);
propsstr = virJSONValueToString(data->props[i], true);
VIR_TEST_VERBOSE("json does not conform to QAPI schema");
VIR_TEST_DEBUG("json:\n%s\ndoes not match schema. Debug output:\n %s",
propsstr, NULLSTR(debugmsg));
VIR_FREE(debugmsg);
VIR_FREE(propsstr);
ret = -1;
}
virBufferFreeAndReset(&debug);
}
return ret;
}
示例12: do_delchange
void do_delchange( CHAR_DATA * ch, char *argument )
{
char arg1[MAX_INPUT_LENGTH];
char buf[MSL];
int num;
argument = one_argument( argument, arg1 );
if( IS_NPC( ch ) )
return;
if( !ch->desc || NULLSTR( arg1 ) || !is_number( arg1 ) )
{
send_to_char( "#wFor delchange you must provide a change number.#D\n\r", ch );
send_to_char( "Syntax: delchange (change number)\n\r", ch );
return;
}
num = atoi( arg1 );
if( num < 0 || num > maxChanges )
{
xprintf( buf, "Valid changes are from 0 to %d.\n\r", maxChanges );
send_to_char( buf, ch );
return;
}
delete_change( num );
send_to_char( "Change deleted.\n\r", ch );
return;
}
示例13: virNetworkDefineXML
/**
* virNetworkDefineXML:
* @conn: pointer to the hypervisor connection
* @xml: the XML description for the network, preferably in UTF-8
*
* Define an inactive persistent virtual network or modify an existing
* persistent one from the XML description.
*
* virNetworkFree should be used to free the resources after the
* network object is no longer needed.
*
* Returns NULL in case of error, a pointer to the network otherwise
*/
virNetworkPtr
virNetworkDefineXML(virConnectPtr conn, const char *xml)
{
VIR_DEBUG("conn=%p, xml=%s", conn, NULLSTR(xml));
virResetLastError();
virCheckConnectReturn(conn, NULL);
virCheckReadOnlyGoto(conn->flags, error);
virCheckNonNullArgGoto(xml, error);
if (conn->networkDriver && conn->networkDriver->networkDefineXML) {
virNetworkPtr ret;
ret = conn->networkDriver->networkDefineXML(conn, xml);
if (!ret)
goto error;
return ret;
}
virReportUnsupportedError();
error:
virDispatchError(conn);
return NULL;
}
示例14: virNetworkGetDHCPLeases
/**
* virNetworkGetDHCPLeases:
* @network: Pointer to network object
* @mac: Optional ASCII formatted MAC address of an interface
* @leases: Pointer to a variable to store the array containing details on
* obtained leases, or NULL if the list is not required (just returns
* number of leases).
* @flags: Extra flags, not used yet, so callers should always pass 0
*
* For DHCPv4, the information returned:
* - Network Interface Name
* - Expiry Time
* - MAC address
* - IAID (NULL)
* - IPv4 address (with type and prefix)
* - Hostname (can be NULL)
* - Client ID (can be NULL)
*
* For DHCPv6, the information returned:
* - Network Interface Name
* - Expiry Time
* - MAC address
* - IAID (can be NULL, only in rare cases)
* - IPv6 address (with type and prefix)
* - Hostname (can be NULL)
* - Client DUID
*
* Note: @mac, @iaid, @ipaddr, @clientid are in ASCII form, not raw bytes.
* Note: @expirytime can 0, in case the lease is for infinite time.
*
* The API fetches leases info of guests in the specified network. If the
* optional parameter @mac is specified, the returned list will contain only
* lease info about a specific guest interface with @mac. There can be
* multiple leases for a single @mac because this API supports DHCPv6 too.
*
* Returns the number of leases found or -1 and sets @leases to NULL in
* case of error. On success, the array stored into @leases is guaranteed to
* have an extra allocated element set to NULL but not included in the return
* count, to make iteration easier. The caller is responsible for calling
* virNetworkDHCPLeaseFree() on each array element, then calling free() on @leases.
*
* See also virNetworkGetDHCPLeasesForMAC() as a convenience for filtering
* the list to a single MAC address.
*
* Example of usage:
*
* virNetworkDHCPLeasePtr *leases = NULL;
* virNetworkPtr network = ... obtain a network pointer here ...;
* size_t i;
* int nleases;
* unsigned int flags = 0;
*
* nleases = virNetworkGetDHCPLeases(network, NULL, &leases, flags);
* if (nleases < 0)
* error();
*
* ... do something with returned values, for example:
*
* for (i = 0; i < nleases; i++) {
* virNetworkDHCPLeasePtr lease = leases[i];
*
* printf("Time(epoch): %lu, MAC address: %s, "
* "IP address: %s, Hostname: %s, ClientID: %s\n",
* lease->expirytime, lease->mac, lease->ipaddr,
* lease->hostname, lease->clientid);
*
* virNetworkDHCPLeaseFree(leases[i]);
* }
*
* free(leases);
*
*/
int
virNetworkGetDHCPLeases(virNetworkPtr network,
const char *mac,
virNetworkDHCPLeasePtr **leases,
unsigned int flags)
{
virConnectPtr conn;
VIR_DEBUG("network=%p, mac='%s' leases=%p, flags=0x%x",
network, NULLSTR(mac), leases, flags);
virResetLastError();
if (leases)
*leases = NULL;
virCheckNetworkReturn(network, -1);
conn = network->conn;
if (conn->networkDriver && conn->networkDriver->networkGetDHCPLeases) {
int ret;
ret = conn->networkDriver->networkGetDHCPLeases(network, mac, leases, flags);
if (ret < 0)
goto error;
return ret;
}
virReportUnsupportedError();
//.........这里部分代码省略.........
示例15: virNWFilterBindingCreateXML
/**
* virNWFilterBindingCreateXML:
* @conn: pointer to the hypervisor connection
* @xml: an XML description of the binding
* @flags: currently unused, pass 0
*
* Define a new network filter, based on an XML description
* similar to the one returned by virNWFilterGetXMLDesc(). This
* API may be used to associate a filter with a currently running
* guest that does not have a filter defined for a specific network
* port. Since the bindings are generally automatically managed by
* the hypervisor, using this command to define a filter for a network
* port and then starting the guest afterwards may prevent the guest
* from starting if it attempts to use the network port and finds a
* filter already defined.
*
* virNWFilterFree should be used to free the resources after the
* binding object is no longer needed.
*
* Returns a new binding object or NULL in case of failure
*/
virNWFilterBindingPtr
virNWFilterBindingCreateXML(virConnectPtr conn, const char *xml, unsigned int flags)
{
VIR_DEBUG("conn=%p, xml=%s", conn, NULLSTR(xml));
virResetLastError();
virCheckConnectReturn(conn, NULL);
virCheckNonNullArgGoto(xml, error);
virCheckReadOnlyGoto(conn->flags, error);
if (conn->nwfilterDriver && conn->nwfilterDriver->nwfilterBindingCreateXML) {
virNWFilterBindingPtr ret;
ret = conn->nwfilterDriver->nwfilterBindingCreateXML(conn, xml, flags);
if (!ret)
goto error;
return ret;
}
virReportUnsupportedError();
error:
virDispatchError(conn);
return NULL;
}