This is going to be squashed into previous commit.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/qemu/qemu_monitor_json.c | 266 ++++++++++++++++++++++---------------------
1 file changed, 139 insertions(+), 127 deletions(-)
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index e9e1c51..c99d300 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -3205,11 +3205,13 @@ int qemuMonitorJSONAddNetdev(qemuMonitorPtr mon,
goto cleanup;
args = NULL; /* obj owns reference to args now */
- ret = qemuMonitorJSONCommand(mon, cmd, &reply);
+ if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
+ goto cleanup;
- if (ret == 0)
- ret = qemuMonitorJSONCheckError(cmd, reply);
+ if (qemuMonitorJSONCheckError(cmd, reply) < 0)
+ goto cleanup;
+ ret = 0;
cleanup:
virJSONValueFree(args);
virJSONValueFree(cmd);
@@ -3221,7 +3223,7 @@ int qemuMonitorJSONAddNetdev(qemuMonitorPtr mon,
int qemuMonitorJSONRemoveNetdev(qemuMonitorPtr mon,
const char *alias)
{
- int ret;
+ int ret = -1;
virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("netdev_del",
"s:id", alias,
NULL);
@@ -3229,11 +3231,14 @@ int qemuMonitorJSONRemoveNetdev(qemuMonitorPtr mon,
if (!cmd)
return -1;
- ret = qemuMonitorJSONCommand(mon, cmd, &reply);
+ if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
+ goto cleanup;
- if (ret == 0)
- ret = qemuMonitorJSONCheckError(cmd, reply);
+ if (qemuMonitorJSONCheckError(cmd, reply) < 0)
+ goto cleanup;
+ ret = 0;
+ cleanup:
virJSONValueFree(cmd);
virJSONValueFree(reply);
return ret;
@@ -3539,7 +3544,7 @@ qemuMonitorJSONGetChardevInfo(qemuMonitorPtr mon,
virHashTablePtr info)
{
- int ret;
+ int ret = -1;
virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("query-chardev",
NULL);
virJSONValuePtr reply = NULL;
@@ -3547,14 +3552,14 @@ qemuMonitorJSONGetChardevInfo(qemuMonitorPtr mon,
if (!cmd)
return -1;
- ret = qemuMonitorJSONCommand(mon, cmd, &reply);
+ if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
+ goto cleanup;
- if (ret == 0)
- ret = qemuMonitorJSONCheckError(cmd, reply);
-
- if (ret == 0)
- ret = qemuMonitorJSONExtractChardevInfo(reply, info);
+ if (qemuMonitorJSONCheckError(cmd, reply) < 0)
+ goto cleanup;
+ ret = qemuMonitorJSONExtractChardevInfo(reply, info);
+ cleanup:
virJSONValueFree(cmd);
virJSONValueFree(reply);
return ret;
@@ -3573,7 +3578,7 @@ int qemuMonitorJSONGetAllPCIAddresses(qemuMonitorPtr mon
ATTRIBUTE_UNUSED,
int qemuMonitorJSONDelDevice(qemuMonitorPtr mon,
const char *devalias)
{
- int ret;
+ int ret = -1;
virJSONValuePtr cmd;
virJSONValuePtr reply = NULL;
@@ -3583,11 +3588,14 @@ int qemuMonitorJSONDelDevice(qemuMonitorPtr mon,
if (!cmd)
return -1;
- ret = qemuMonitorJSONCommand(mon, cmd, &reply);
+ if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
+ goto cleanup;
- if (ret == 0)
- ret = qemuMonitorJSONCheckError(cmd, reply);
+ if (qemuMonitorJSONCheckError(cmd, reply) < 0)
+ goto cleanup;
+ ret = 0;
+ cleanup:
virJSONValueFree(cmd);
virJSONValueFree(reply);
return ret;
@@ -3614,11 +3622,13 @@ int qemuMonitorJSONAddDevice(qemuMonitorPtr mon,
goto cleanup;
args = NULL; /* obj owns reference to args now */
- ret = qemuMonitorJSONCommand(mon, cmd, &reply);
+ if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
+ goto cleanup;
- if (ret == 0)
- ret = qemuMonitorJSONCheckError(cmd, reply);
+ if (qemuMonitorJSONCheckError(cmd, reply) < 0)
+ goto cleanup;
+ ret = 0;
cleanup:
virJSONValueFree(args);
virJSONValueFree(cmd);
@@ -3644,14 +3654,16 @@ int qemuMonitorJSONAddObject(qemuMonitorPtr mon,
if (!cmd)
goto cleanup;
- /* @props is part of @cmd now. Avoid double free */
+ /* @props is part of @cmd now. Avoid double free */
props = NULL;
- ret = qemuMonitorJSONCommand(mon, cmd, &reply);
+ if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
+ goto cleanup;
- if (ret == 0)
- ret = qemuMonitorJSONCheckError(cmd, reply);
+ if (qemuMonitorJSONCheckError(cmd, reply) < 0)
+ goto cleanup;
+ ret = 0;
cleanup:
virJSONValueFree(cmd);
virJSONValueFree(reply);
@@ -3663,7 +3675,7 @@ int qemuMonitorJSONAddObject(qemuMonitorPtr mon,
int qemuMonitorJSONDelObject(qemuMonitorPtr mon,
const char *objalias)
{
- int ret;
+ int ret = -1;
virJSONValuePtr cmd;
virJSONValuePtr reply = NULL;
@@ -3673,11 +3685,14 @@ int qemuMonitorJSONDelObject(qemuMonitorPtr mon,
if (!cmd)
return -1;
- ret = qemuMonitorJSONCommand(mon, cmd, &reply);
+ if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
+ goto cleanup;
- if (ret == 0)
- ret = qemuMonitorJSONCheckError(cmd, reply);
+ if (qemuMonitorJSONCheckError(cmd, reply) < 0)
+ goto cleanup;
+ ret = 0;
+ cleanup:
virJSONValueFree(cmd);
virJSONValueFree(reply);
return ret;
@@ -3688,7 +3703,7 @@ int qemuMonitorJSONSetDrivePassphrase(qemuMonitorPtr mon,
const char *alias,
const char *passphrase)
{
- int ret;
+ int ret = -1;
virJSONValuePtr cmd;
virJSONValuePtr reply = NULL;
char *drive;
@@ -3704,11 +3719,14 @@ int qemuMonitorJSONSetDrivePassphrase(qemuMonitorPtr mon,
if (!cmd)
return -1;
- ret = qemuMonitorJSONCommand(mon, cmd, &reply);
+ if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
+ goto cleanup;
- if (ret == 0)
- ret = qemuMonitorJSONCheckError(cmd, reply);
+ if (qemuMonitorJSONCheckError(cmd, reply) < 0)
+ goto cleanup;
+ ret = 0;
+ cleanup:
virJSONValueFree(cmd);
virJSONValueFree(reply);
return ret;
@@ -3800,10 +3818,13 @@ qemuMonitorJSONDriveMirror(qemuMonitorPtr mon,
if (!cmd)
return -1;
- if ((ret = qemuMonitorJSONCommand(mon, cmd, &reply)) < 0)
+ if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
goto cleanup;
- ret = qemuMonitorJSONCheckError(cmd, reply);
+ if (qemuMonitorJSONCheckError(cmd, reply) < 0)
+ goto cleanup;
+
+ ret = 0;
cleanup:
virJSONValueFree(cmd);
virJSONValueFree(reply);
@@ -3826,11 +3847,13 @@ qemuMonitorJSONTransaction(qemuMonitorPtr mon, virJSONValuePtr
actions)
if (!cmd)
goto cleanup;
- if ((ret = qemuMonitorJSONCommand(mon, cmd, &reply)) < 0)
+ if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
goto cleanup;
- ret = qemuMonitorJSONCheckError(cmd, reply);
+ if (qemuMonitorJSONCheckError(cmd, reply) < 0)
+ goto cleanup;
+ ret = 0;
cleanup:
virJSONValueFree(cmd);
virJSONValueFree(reply);
@@ -3866,7 +3889,7 @@ qemuMonitorJSONBlockCommit(qemuMonitorPtr mon, const char *device,
if (!cmd)
return -1;
- if ((ret = qemuMonitorJSONCommand(mon, cmd, &reply)) < 0)
+ if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
goto cleanup;
if (!top && !base) {
/* Normally we always specify top and base; but omitting them
@@ -3896,7 +3919,7 @@ int
qemuMonitorJSONDrivePivot(qemuMonitorPtr mon,
const char *device)
{
- int ret;
+ int ret = -1;
virJSONValuePtr cmd;
virJSONValuePtr reply = NULL;
@@ -3906,10 +3929,13 @@ qemuMonitorJSONDrivePivot(qemuMonitorPtr mon,
if (!cmd)
return -1;
- if ((ret = qemuMonitorJSONCommand(mon, cmd, &reply)) < 0)
+ if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
goto cleanup;
- ret = qemuMonitorJSONCheckError(cmd, reply);
+ if (qemuMonitorJSONCheckError(cmd, reply) < 0)
+ goto cleanup;
+
+ ret = 0;
cleanup:
virJSONValueFree(cmd);
virJSONValueFree(reply);
@@ -4043,13 +4069,12 @@ int qemuMonitorJSONArbitraryCommand(qemuMonitorPtr mon,
cleanup:
virJSONValueFree(cmd);
virJSONValueFree(reply);
-
return ret;
}
int qemuMonitorJSONInjectNMI(qemuMonitorPtr mon)
{
- int ret;
+ int ret = -1;
virJSONValuePtr cmd;
virJSONValuePtr reply = NULL;
@@ -4057,7 +4082,7 @@ int qemuMonitorJSONInjectNMI(qemuMonitorPtr mon)
if (!cmd)
return -1;
- if ((ret = qemuMonitorJSONCommand(mon, cmd, &reply)) < 0)
+ if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
goto cleanup;
if (qemuMonitorJSONHasError(reply, "CommandNotFound")) {
@@ -4125,7 +4150,7 @@ int qemuMonitorJSONSendKey(qemuMonitorPtr mon,
/* @keys is part of @cmd now. Avoid double free */
keys = NULL;
- if ((ret = qemuMonitorJSONCommand(mon, cmd, &reply)) < 0)
+ if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
goto cleanup;
if (qemuMonitorJSONHasError(reply, "CommandNotFound")) {
@@ -4146,7 +4171,7 @@ int qemuMonitorJSONSendKey(qemuMonitorPtr mon,
int qemuMonitorJSONScreendump(qemuMonitorPtr mon,
const char *file)
{
- int ret;
+ int ret = -1;
virJSONValuePtr cmd, reply = NULL;
cmd = qemuMonitorJSONMakeCommand("screendump",
@@ -4156,11 +4181,14 @@ int qemuMonitorJSONScreendump(qemuMonitorPtr mon,
if (!cmd)
return -1;
- ret = qemuMonitorJSONCommand(mon, cmd, &reply);
+ if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
+ goto cleanup;
- if (ret == 0)
- ret = qemuMonitorJSONCheckError(cmd, reply);
+ if (qemuMonitorJSONCheckError(cmd, reply) < 0)
+ goto cleanup;
+ ret = 0;
+ cleanup:
virJSONValueFree(cmd);
virJSONValueFree(reply);
return ret;
@@ -4422,7 +4450,7 @@ int qemuMonitorJSONOpenGraphics(qemuMonitorPtr mon,
const char *fdname,
bool skipauth)
{
- int ret;
+ int ret = -1;
virJSONValuePtr cmd, reply = NULL;
cmd = qemuMonitorJSONMakeCommand("add_client",
@@ -4434,11 +4462,14 @@ int qemuMonitorJSONOpenGraphics(qemuMonitorPtr mon,
if (!cmd)
return -1;
- ret = qemuMonitorJSONCommand(mon, cmd, &reply);
+ if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
+ goto cleanup;
- if (ret == 0)
- ret = qemuMonitorJSONCheckError(cmd, reply);
+ if (qemuMonitorJSONCheckError(cmd, reply) < 0)
+ goto cleanup;
+ ret = 0;
+ cleanup:
virJSONValueFree(cmd);
virJSONValueFree(reply);
return ret;
@@ -4583,9 +4614,10 @@ int qemuMonitorJSONSetBlockIoThrottle(qemuMonitorPtr mon,
if (!cmd)
return -1;
- ret = qemuMonitorJSONCommand(mon, cmd, &result);
+ if (qemuMonitorJSONCommand(mon, cmd, &result) < 0)
+ goto cleanup;
- if (ret == 0 && virJSONValueObjectHasKey(result, "error")) {
+ if (virJSONValueObjectHasKey(result, "error")) {
if (qemuMonitorJSONHasError(result, "DeviceNotActive"))
virReportError(VIR_ERR_OPERATION_INVALID,
_("No active operation on device: %s"), device);
@@ -4595,9 +4627,11 @@ int qemuMonitorJSONSetBlockIoThrottle(qemuMonitorPtr mon,
else
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unexpected error"));
- ret = -1;
+ goto cleanup;
}
+ ret = 0;
+ cleanup:
virJSONValueFree(cmd);
virJSONValueFree(result);
return ret;
@@ -4616,9 +4650,10 @@ int qemuMonitorJSONGetBlockIoThrottle(qemuMonitorPtr mon,
if (!cmd)
return -1;
- ret = qemuMonitorJSONCommand(mon, cmd, &result);
+ if (qemuMonitorJSONCommand(mon, cmd, &result) < 0)
+ goto cleanup;
- if (ret == 0 && virJSONValueObjectHasKey(result, "error")) {
+ if (virJSONValueObjectHasKey(result, "error")) {
if (qemuMonitorJSONHasError(result, "DeviceNotActive"))
virReportError(VIR_ERR_OPERATION_INVALID,
_("No active operation on device: %s"), device);
@@ -4628,12 +4663,11 @@ int qemuMonitorJSONGetBlockIoThrottle(qemuMonitorPtr mon,
else
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unexpected error"));
- ret = -1;
+ goto cleanup;
}
- if (ret == 0)
- ret = qemuMonitorJSONBlockIoThrottleInfo(result, device, reply,
supportMaxOptions);
-
+ ret = qemuMonitorJSONBlockIoThrottleInfo(result, device, reply, supportMaxOptions);
+ cleanup:
virJSONValueFree(cmd);
virJSONValueFree(result);
return ret;
@@ -4649,11 +4683,14 @@ int qemuMonitorJSONSystemWakeup(qemuMonitorPtr mon)
if (!cmd)
return -1;
- ret = qemuMonitorJSONCommand(mon, cmd, &reply);
+ if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
+ goto cleanup;
- if (ret == 0)
- ret = qemuMonitorJSONCheckError(cmd, reply);
+ if (qemuMonitorJSONCheckError(cmd, reply) < 0)
+ goto cleanup;
+ ret = 0;
+ cleanup:
virJSONValueFree(cmd);
virJSONValueFree(reply);
return ret;
@@ -4665,7 +4702,7 @@ int qemuMonitorJSONGetVersion(qemuMonitorPtr mon,
int *micro,
char **package)
{
- int ret;
+ int ret = -1;
virJSONValuePtr cmd;
virJSONValuePtr reply = NULL;
virJSONValuePtr data;
@@ -4678,15 +4715,11 @@ int qemuMonitorJSONGetVersion(qemuMonitorPtr mon,
if (!(cmd = qemuMonitorJSONMakeCommand("query-version", NULL)))
return -1;
- ret = qemuMonitorJSONCommand(mon, cmd, &reply);
-
- if (ret == 0)
- ret = qemuMonitorJSONCheckError(cmd, reply);
-
- if (ret < 0)
+ if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
goto cleanup;
- ret = -1;
+ if (qemuMonitorJSONCheckError(cmd, reply) < 0)
+ goto cleanup;
if (!(data = virJSONValueObjectGetObject(reply, "return"))) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@@ -4739,7 +4772,7 @@ int qemuMonitorJSONGetVersion(qemuMonitorPtr mon,
int qemuMonitorJSONGetMachines(qemuMonitorPtr mon,
qemuMonitorMachineInfoPtr **machines)
{
- int ret;
+ int ret = -1;
virJSONValuePtr cmd;
virJSONValuePtr reply = NULL;
virJSONValuePtr data;
@@ -4752,15 +4785,11 @@ int qemuMonitorJSONGetMachines(qemuMonitorPtr mon,
if (!(cmd = qemuMonitorJSONMakeCommand("query-machines", NULL)))
return -1;
- ret = qemuMonitorJSONCommand(mon, cmd, &reply);
-
- if (ret == 0)
- ret = qemuMonitorJSONCheckError(cmd, reply);
-
- if (ret < 0)
+ if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
goto cleanup;
- ret = -1;
+ if (qemuMonitorJSONCheckError(cmd, reply) < 0)
+ goto cleanup;
if (!(data = virJSONValueObjectGetArray(reply, "return"))) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@@ -4839,7 +4868,7 @@ int qemuMonitorJSONGetMachines(qemuMonitorPtr mon,
int qemuMonitorJSONGetCPUDefinitions(qemuMonitorPtr mon,
char ***cpus)
{
- int ret;
+ int ret = -1;
virJSONValuePtr cmd;
virJSONValuePtr reply = NULL;
virJSONValuePtr data;
@@ -4852,28 +4881,21 @@ int qemuMonitorJSONGetCPUDefinitions(qemuMonitorPtr mon,
if (!(cmd = qemuMonitorJSONMakeCommand("query-cpu-definitions", NULL)))
return -1;
- ret = qemuMonitorJSONCommand(mon, cmd, &reply);
+ if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
+ goto cleanup;
- if (ret == 0) {
- /* Urgh, some QEMU architectures have the query-cpu-definitions
- * command, but return 'GenericError' with string "Not
supported",
- * instead of simply omitting the command entirely :-(
- */
- if (qemuMonitorJSONHasError(reply, "GenericError")) {
- ret = 0;
- goto cleanup;
- }
- ret = qemuMonitorJSONCheckError(cmd, reply);
+ /* Urgh, some QEMU architectures have the query-cpu-definitions
+ * command, but return 'GenericError' with string "Not supported",
+ * instead of simply omitting the command entirely :-(
+ */
+ if (qemuMonitorJSONHasError(reply, "GenericError")) {
+ ret = 0;
+ goto cleanup;
}
- if (ret == 0)
- ret = qemuMonitorJSONCheckError(cmd, reply);
-
- if (ret < 0)
+ if (qemuMonitorJSONCheckError(cmd, reply) < 0)
goto cleanup;
- ret = -1;
-
if (!(data = virJSONValueObjectGetArray(reply, "return"))) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("query-cpu-definitions reply was missing return
data"));
@@ -4919,7 +4941,7 @@ int qemuMonitorJSONGetCPUDefinitions(qemuMonitorPtr mon,
int qemuMonitorJSONGetCommands(qemuMonitorPtr mon,
char ***commands)
{
- int ret;
+ int ret = -1;
virJSONValuePtr cmd;
virJSONValuePtr reply = NULL;
virJSONValuePtr data;
@@ -4932,15 +4954,11 @@ int qemuMonitorJSONGetCommands(qemuMonitorPtr mon,
if (!(cmd = qemuMonitorJSONMakeCommand("query-commands", NULL)))
return -1;
- ret = qemuMonitorJSONCommand(mon, cmd, &reply);
-
- if (ret == 0)
- ret = qemuMonitorJSONCheckError(cmd, reply);
-
- if (ret < 0)
+ if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
goto cleanup;
- ret = -1;
+ if (qemuMonitorJSONCheckError(cmd, reply) < 0)
+ goto cleanup;
if (!(data = virJSONValueObjectGetArray(reply, "return"))) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@@ -4987,7 +5005,7 @@ int qemuMonitorJSONGetCommands(qemuMonitorPtr mon,
int qemuMonitorJSONGetEvents(qemuMonitorPtr mon,
char ***events)
{
- int ret;
+ int ret = -1;
virJSONValuePtr cmd;
virJSONValuePtr reply = NULL;
virJSONValuePtr data;
@@ -5000,21 +5018,17 @@ int qemuMonitorJSONGetEvents(qemuMonitorPtr mon,
if (!(cmd = qemuMonitorJSONMakeCommand("query-events", NULL)))
return -1;
- ret = qemuMonitorJSONCommand(mon, cmd, &reply);
+ if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
+ goto cleanup;
- if (ret == 0) {
- if (qemuMonitorJSONHasError(reply, "CommandNotFound")) {
- ret = 0;
- goto cleanup;
- }
- ret = qemuMonitorJSONCheckError(cmd, reply);
+ if (qemuMonitorJSONHasError(reply, "CommandNotFound")) {
+ ret = 0;
+ goto cleanup;
}
- if (ret < 0)
+ if (qemuMonitorJSONCheckError(cmd, reply) < 0)
goto cleanup;
- ret = -1;
-
if (!(data = virJSONValueObjectGetArray(reply, "return"))) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("query-events reply was missing return data"));
@@ -5063,7 +5077,7 @@ qemuMonitorJSONGetCommandLineOptionParameters(qemuMonitorPtr mon,
char ***params,
bool *found)
{
- int ret;
+ int ret = -1;
virJSONValuePtr cmd = NULL;
virJSONValuePtr reply = NULL;
virJSONValuePtr data = NULL;
@@ -5084,15 +5098,15 @@ qemuMonitorJSONGetCommandLineOptionParameters(qemuMonitorPtr mon,
NULL)))
return -1;
- ret = qemuMonitorJSONCommand(mon, cmd, &reply);
+ if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
+ goto cleanup;
- if (ret == 0) {
- if (qemuMonitorJSONHasError(reply, "CommandNotFound"))
- goto cleanup;
- ret = qemuMonitorJSONCheckError(cmd, reply);
+ if (qemuMonitorJSONHasError(reply, "CommandNotFound")) {
+ ret = 0;
+ goto cleanup;
}
- if (ret < 0)
+ if (qemuMonitorJSONCheckError(cmd, reply) < 0)
goto cleanup;
if (virJSONValueObjectRemoveKey(reply, "return", &array) <= 0)
{
@@ -5104,8 +5118,6 @@ qemuMonitorJSONGetCommandLineOptionParameters(qemuMonitorPtr mon,
qemuMonitorSetOptions(mon, array);
}
- ret = -1;
-
if ((n = virJSONValueArraySize(array)) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("query-command-line-options reply data was not "
--
2.8.1