* current domain state. VIR_DOMAIN_AFFECT_LIVE requires a running
* domain, and VIR_DOMAIN_AFFECT_CONFIG requires a persistent domain
* (whether or not it is running).
+ *
+ * These enums should not conflict with those of virTypedParameterFlags.
*/
typedef enum {
VIR_DOMAIN_AFFECT_CURRENT = 0, /* Affect current domain state. */
VIR_DOMAIN_AFFECT_LIVE = 1 << 0, /* Affect running domain state. */
VIR_DOMAIN_AFFECT_CONFIG = 1 << 1, /* Affect persistent domain state. */
+ /* 1 << 2 is reserved for virTypedParameterFlags */
} virDomainModificationImpact;
/**
VIR_TYPED_PARAM_LLONG = 3, /* long long case */
VIR_TYPED_PARAM_ULLONG = 4, /* unsigned long long case */
VIR_TYPED_PARAM_DOUBLE = 5, /* double case */
- VIR_TYPED_PARAM_BOOLEAN = 6 /* boolean(character) case */
+ VIR_TYPED_PARAM_BOOLEAN = 6, /* boolean(character) case */
+ VIR_TYPED_PARAM_STRING = 7, /* string case */
} virTypedParameterType;
+/**
+ * virTypedParameterFlags:
+ *
+ * Flags related to libvirt APIs that use virTypedParameter.
+ *
+ * These enums should not conflict with those of virDomainModificationImpact.
+ */
+typedef enum {
+ /* 1 << 0 is reserved for virDomainModificationImpact */
+ /* 1 << 1 is reserved for virDomainModificationImpact */
+
+ /* Older servers lacked the ability to handle string typed
+ * parameters. Attempts to set a string parameter with an older
+ * server will fail at the client, but attempts to retrieve
+ * parameters must not return strings from a new server to an
+ * older client, so this flag exists to identify newer clients to
+ * newer servers. This flag is automatically set when needed, so
+ * the user does not have to worry about it; however, manually
+ * setting the flag can be used to reject servers that cannot
+ * return typed strings, even if no strings would be returned.
+ */
+ VIR_TYPED_PARAM_STRING_OKAY = 1 << 2,
+
+} virTypedParameterFlags;
+
/**
* VIR_TYPED_PARAM_FIELD_LENGTH:
*
unsigned long long int ul; /* type is ULLONG */
double d; /* type is DOUBLE */
char b; /* type is BOOLEAN */
+ char *s; /* type is STRING, may not be NULL */
} value; /* parameter value */
};
return -1;
}
+/* Helper function called to validate incoming client array on any
+ * interface that sets typed parameters in the hypervisor. */
+static int
+virTypedParameterValidateSet(virDomainPtr domain,
+ virTypedParameterPtr params,
+ int nparams)
+{
+ bool string_okay;
+ int i;
+
+ string_okay = VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver,
+ domain->conn,
+ VIR_DRV_FEATURE_TYPED_PARAM_STRING);
+ for (i = 0; i < nparams; i++) {
+ if (strnlen(params[i].field, VIR_TYPED_PARAM_FIELD_LENGTH) ==
+ VIR_TYPED_PARAM_FIELD_LENGTH) {
+ virLibDomainError(VIR_ERR_INVALID_ARG,
+ _("string parameter name '%.*s' too long"),
+ VIR_TYPED_PARAM_FIELD_LENGTH,
+ params[i].field);
+ virDispatchError(NULL);
+ return -1;
+ }
+ if (params[i].type == VIR_TYPED_PARAM_STRING) {
+ if (string_okay) {
+ if (!params[i].value.s) {
+ virLibDomainError(VIR_ERR_INVALID_ARG,
+ _("NULL string parameter '%s'"),
+ params[i].field);
+ virDispatchError(NULL);
+ return -1;
+ }
+ } else {
+ virLibDomainError(VIR_ERR_INVALID_ARG,
+ _("string parameter '%s' unsupported"),
+ params[i].field);
+ virDispatchError(NULL);
+ return -1;
+ }
+ }
+ }
+ return 0;
+}
+
/**
* virDomainSetMemoryParameters:
* @domain: pointer to domain object
virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__);
goto error;
}
+ if (virTypedParameterValidateSet(domain, params, nparams) < 0)
+ return -1;
+
conn = domain->conn;
if (conn->driver->domainSetMemoryParameters) {
* @params: pointer to memory parameter object
* (return value, allocated by the caller)
* @nparams: pointer to number of memory parameters; input and output
- * @flags: one of virDomainModificationImpact
+ * @flags: bitwise-OR of virDomainModificationImpact and virTypedParameterFlags
*
* Get all memory parameters. On input, @nparams gives the size of the
* @params array; on output, @nparams gives how many slots were filled
virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__);
goto error;
}
+ if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
+ VIR_DRV_FEATURE_TYPED_PARAM_STRING))
+ flags |= VIR_TYPED_PARAM_STRING_OKAY;
conn = domain->conn;
if (conn->driver->domainGetMemoryParameters) {
* @params: pointer to blkio parameter objects
* @nparams: number of blkio parameters (this value can be the same or
* less than the number of parameters supported)
- * @flags: an OR'ed set of virDomainModificationImpact
+ * @flags: bitwise-OR of virDomainModificationImpact
*
* Change all or a subset of the blkio tunables.
* This function may require privileged access to the hypervisor.
virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__);
goto error;
}
+ if (virTypedParameterValidateSet(domain, params, nparams) < 0)
+ return -1;
+
conn = domain->conn;
if (conn->driver->domainSetBlkioParameters) {
* @params: pointer to blkio parameter object
* (return value, allocated by the caller)
* @nparams: pointer to number of blkio parameters; input and output
- * @flags: an OR'ed set of virDomainModificationImpact
+ * @flags: bitwise-OR of virDomainModificationImpact and virTypedParameterFlags
*
* Get all blkio parameters. On input, @nparams gives the size of the
* @params array; on output, @nparams gives how many slots were filled
virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__);
goto error;
}
+ if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
+ VIR_DRV_FEATURE_TYPED_PARAM_STRING))
+ flags |= VIR_TYPED_PARAM_STRING_OKAY;
conn = domain->conn;
if (conn->driver->domainGetBlkioParameters) {
* @nparams: pointer to number of scheduler parameter
* (this value should be same than the returned value
* nparams of virDomainGetSchedulerType()); input and output
- * @flags: one of virDomainModificationImpact
+ * @flags: bitwise-OR of virDomainModificationImpact and virTypedParameterFlags
*
* Get all scheduler parameters. On input, @nparams gives the size of the
* @params array; on output, @nparams gives how many slots were filled
goto error;
}
+ if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
+ VIR_DRV_FEATURE_TYPED_PARAM_STRING))
+ flags |= VIR_TYPED_PARAM_STRING_OKAY;
conn = domain->conn;
if (conn->driver->domainGetSchedulerParametersFlags) {
return -1;
}
+ if (domain->conn->flags & VIR_CONNECT_RO) {
+ virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+ goto error;
+ }
if (params == NULL || nparams < 0) {
virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__);
goto error;
}
+ if (virTypedParameterValidateSet(domain, params, nparams) < 0)
+ return -1;
- if (domain->conn->flags & VIR_CONNECT_RO) {
- virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
- goto error;
- }
conn = domain->conn;
if (conn->driver->domainSetSchedulerParameters) {
return -1;
}
+ if (domain->conn->flags & VIR_CONNECT_RO) {
+ virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+ goto error;
+ }
if (params == NULL || nparams < 0) {
virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__);
goto error;
}
+ if (virTypedParameterValidateSet(domain, params, nparams) < 0)
+ return -1;
- if (domain->conn->flags & VIR_CONNECT_RO) {
- virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
- goto error;
- }
conn = domain->conn;
if (conn->driver->domainSetSchedulerParametersFlags) {
* @params: pointer to block stats parameter object
* (return value)
* @nparams: pointer to number of block stats; input and output
- * @flags: unused, always pass 0
+ * @flags: bitwise-OR of virTypedParameterFlags
*
* This function is to get block stats parameters for block
* devices attached to the domain.
virLibConnError(VIR_ERR_INVALID_ARG, __FUNCTION__);
goto error;
}
+ if (VIR_DRV_SUPPORTS_FEATURE(dom->conn->driver, dom->conn,
+ VIR_DRV_FEATURE_TYPED_PARAM_STRING))
+ flags |= VIR_TYPED_PARAM_STRING_OKAY;
conn = dom->conn;
if (conn->driver->domainBlockStatsFlags) {