/* Automatically generated by gendispatch.pl.
 * Do not edit this file.  Any changes you make will be lost.
 */

static char *
remoteCPUBaseline(virConnectPtr conn, const char **xmlCPUs, unsigned int xmlCPUslen, unsigned int flags)
{
    char *rv = NULL;
    struct private_data *priv = conn->privateData;
    remote_cpu_baseline_args args;
    remote_cpu_baseline_ret ret;

    remoteDriverLock(priv);

    if (xmlCPUslen > REMOTE_CPU_BASELINE_MAX) {
        remoteError(VIR_ERR_RPC,
                    _("%s length greater than maximum: %d > %d"),
                    "xmlCPUs", (int)xmlCPUslen, REMOTE_CPU_BASELINE_MAX);
        goto done;
    }

    args.xmlCPUs.xmlCPUs_val = (char **)xmlCPUs;
    args.xmlCPUs.xmlCPUs_len = xmlCPUslen;
    args.flags = flags;

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_CPU_BASELINE,
             (xdrproc_t)xdr_remote_cpu_baseline_args, (char *)&args,
             (xdrproc_t)xdr_remote_cpu_baseline_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = ret.cpu;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteCPUCompare(virConnectPtr conn, const char *xml, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = conn->privateData;
    remote_cpu_compare_args args;
    remote_cpu_compare_ret ret;

    remoteDriverLock(priv);

    args.xml = (char *)xml;
    args.flags = flags;

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_CPU_COMPARE,
             (xdrproc_t)xdr_remote_cpu_compare_args, (char *)&args,
             (xdrproc_t)xdr_remote_cpu_compare_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = ret.result;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainAbortJob(virDomainPtr dom)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_abort_job_args args;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_ABORT_JOB,
             (xdrproc_t)xdr_remote_domain_abort_job_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainAttachDevice(virDomainPtr dom, const char *xml)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_attach_device_args args;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.xml = (char *)xml;

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_ATTACH_DEVICE,
             (xdrproc_t)xdr_remote_domain_attach_device_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainAttachDeviceFlags(virDomainPtr dom, const char *xml, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_attach_device_flags_args args;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.xml = (char *)xml;
    args.flags = flags;

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_ATTACH_DEVICE_FLAGS,
             (xdrproc_t)xdr_remote_domain_attach_device_flags_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainBlockJobAbort(virDomainPtr dom, const char *path, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_block_job_abort_args args;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.path = (char *)path;
    args.flags = flags;

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_BLOCK_JOB_ABORT,
             (xdrproc_t)xdr_remote_domain_block_job_abort_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainBlockJobSetSpeed(virDomainPtr dom, const char *path, unsigned long bandwidth, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_block_job_set_speed_args args;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.path = (char *)path;
    args.bandwidth = bandwidth;
    args.flags = flags;

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_BLOCK_JOB_SET_SPEED,
             (xdrproc_t)xdr_remote_domain_block_job_set_speed_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainBlockPull(virDomainPtr dom, const char *path, unsigned long bandwidth, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_block_pull_args args;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.path = (char *)path;
    args.bandwidth = bandwidth;
    args.flags = flags;

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_BLOCK_PULL,
             (xdrproc_t)xdr_remote_domain_block_pull_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainBlockRebase(virDomainPtr dom, const char *path, const char *base, unsigned long bandwidth, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_block_rebase_args args;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.path = (char *)path;
    args.base = base ? (char **)&base : NULL;
    args.bandwidth = bandwidth;
    args.flags = flags;

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_BLOCK_REBASE,
             (xdrproc_t)xdr_remote_domain_block_rebase_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainBlockResize(virDomainPtr dom, const char *disk, unsigned long long size, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_block_resize_args args;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.disk = (char *)disk;
    args.size = size;
    args.flags = flags;

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_BLOCK_RESIZE,
             (xdrproc_t)xdr_remote_domain_block_resize_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainBlockStats(virDomainPtr dom, const char *path, virDomainBlockStatsPtr result)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_block_stats_args args;
    remote_domain_block_stats_ret ret;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.path = (char *)path;

    memset(&ret, 0, sizeof(ret));

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_BLOCK_STATS,
             (xdrproc_t)xdr_remote_domain_block_stats_args, (char *)&args,
             (xdrproc_t)xdr_remote_domain_block_stats_ret, (char *)&ret) == -1) {
        goto done;
    }

    result->rd_req = ret.rd_req;
    result->rd_bytes = ret.rd_bytes;
    result->wr_req = ret.wr_req;
    result->wr_bytes = ret.wr_bytes;
    result->errs = ret.errs;
    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainCoreDump(virDomainPtr dom, const char *to, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_core_dump_args args;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.to = (char *)to;
    args.flags = flags;

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_CORE_DUMP,
             (xdrproc_t)xdr_remote_domain_core_dump_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainCreateWithFlags(virDomainPtr dom, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_create_with_flags_args args;
    remote_domain_create_with_flags_ret ret;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.flags = flags;

    memset(&ret, 0, sizeof(ret));

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_CREATE_WITH_FLAGS,
             (xdrproc_t)xdr_remote_domain_create_with_flags_args, (char *)&args,
             (xdrproc_t)xdr_remote_domain_create_with_flags_ret, (char *)&ret) == -1) {
        goto done;
    }

    dom->id = ret.dom.id;
    xdr_free((xdrproc_t)xdr_remote_domain_create_with_flags_ret, (char *)&ret);
    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static virDomainPtr
remoteDomainCreateXML(virConnectPtr conn, const char *xml_desc, unsigned int flags)
{
    virDomainPtr rv = NULL;
    struct private_data *priv = conn->privateData;
    remote_domain_create_xml_args args;
    remote_domain_create_xml_ret ret;

    remoteDriverLock(priv);

    args.xml_desc = (char *)xml_desc;
    args.flags = flags;

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_DOMAIN_CREATE_XML,
             (xdrproc_t)xdr_remote_domain_create_xml_args, (char *)&args,
             (xdrproc_t)xdr_remote_domain_create_xml_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = get_nonnull_domain(conn, ret.dom);
    xdr_free((xdrproc_t)xdr_remote_domain_create_xml_ret, (char *)&ret);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static virDomainPtr
remoteDomainDefineXML(virConnectPtr conn, const char *xml)
{
    virDomainPtr rv = NULL;
    struct private_data *priv = conn->privateData;
    remote_domain_define_xml_args args;
    remote_domain_define_xml_ret ret;

    remoteDriverLock(priv);

    args.xml = (char *)xml;

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_DOMAIN_DEFINE_XML,
             (xdrproc_t)xdr_remote_domain_define_xml_args, (char *)&args,
             (xdrproc_t)xdr_remote_domain_define_xml_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = get_nonnull_domain(conn, ret.dom);
    xdr_free((xdrproc_t)xdr_remote_domain_define_xml_ret, (char *)&ret);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainDestroy(virDomainPtr dom)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_destroy_args args;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_DESTROY,
             (xdrproc_t)xdr_remote_domain_destroy_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    dom->id = -1;
    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainDestroyFlags(virDomainPtr dom, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_destroy_flags_args args;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.flags = flags;

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_DESTROY_FLAGS,
             (xdrproc_t)xdr_remote_domain_destroy_flags_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainDetachDevice(virDomainPtr dom, const char *xml)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_detach_device_args args;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.xml = (char *)xml;

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_DETACH_DEVICE,
             (xdrproc_t)xdr_remote_domain_detach_device_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainDetachDeviceFlags(virDomainPtr dom, const char *xml, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_detach_device_flags_args args;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.xml = (char *)xml;
    args.flags = flags;

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_DETACH_DEVICE_FLAGS,
             (xdrproc_t)xdr_remote_domain_detach_device_flags_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainGetAutostart(virDomainPtr dom, int *autostart)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_get_autostart_args args;
    remote_domain_get_autostart_ret ret;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);

    memset(&ret, 0, sizeof(ret));

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_AUTOSTART,
             (xdrproc_t)xdr_remote_domain_get_autostart_args, (char *)&args,
             (xdrproc_t)xdr_remote_domain_get_autostart_ret, (char *)&ret) == -1) {
        goto done;
    }

    if (autostart) *autostart = ret.autostart;
    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainGetBlockInfo(virDomainPtr dom, const char *path, virDomainBlockInfoPtr result, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_get_block_info_args args;
    remote_domain_get_block_info_ret ret;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.path = (char *)path;
    args.flags = flags;

    memset(&ret, 0, sizeof(ret));

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_BLOCK_INFO,
             (xdrproc_t)xdr_remote_domain_get_block_info_args, (char *)&args,
             (xdrproc_t)xdr_remote_domain_get_block_info_ret, (char *)&ret) == -1) {
        goto done;
    }

    result->allocation = ret.allocation;
    result->capacity = ret.capacity;
    result->physical = ret.physical;
    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainGetControlInfo(virDomainPtr dom, virDomainControlInfoPtr result, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_get_control_info_args args;
    remote_domain_get_control_info_ret ret;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.flags = flags;

    memset(&ret, 0, sizeof(ret));

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_CONTROL_INFO,
             (xdrproc_t)xdr_remote_domain_get_control_info_args, (char *)&args,
             (xdrproc_t)xdr_remote_domain_get_control_info_ret, (char *)&ret) == -1) {
        goto done;
    }

    result->state = ret.state;
    result->details = ret.details;
    result->stateTime = ret.stateTime;
    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainGetInfo(virDomainPtr dom, virDomainInfoPtr result)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_get_info_args args;
    remote_domain_get_info_ret ret;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);

    memset(&ret, 0, sizeof(ret));

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_INFO,
             (xdrproc_t)xdr_remote_domain_get_info_args, (char *)&args,
             (xdrproc_t)xdr_remote_domain_get_info_ret, (char *)&ret) == -1) {
        goto done;
    }

    result->state = ret.state;
    HYPER_TO_ULONG(result->maxMem, ret.maxMem);
    HYPER_TO_ULONG(result->memory, ret.memory);
    result->nrVirtCpu = ret.nrVirtCpu;
    result->cpuTime = ret.cpuTime;
    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainGetJobInfo(virDomainPtr dom, virDomainJobInfoPtr result)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_get_job_info_args args;
    remote_domain_get_job_info_ret ret;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);

    memset(&ret, 0, sizeof(ret));

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_JOB_INFO,
             (xdrproc_t)xdr_remote_domain_get_job_info_args, (char *)&args,
             (xdrproc_t)xdr_remote_domain_get_job_info_ret, (char *)&ret) == -1) {
        goto done;
    }

    result->type = ret.type;
    result->timeElapsed = ret.timeElapsed;
    result->timeRemaining = ret.timeRemaining;
    result->dataTotal = ret.dataTotal;
    result->dataProcessed = ret.dataProcessed;
    result->dataRemaining = ret.dataRemaining;
    result->memTotal = ret.memTotal;
    result->memProcessed = ret.memProcessed;
    result->memRemaining = ret.memRemaining;
    result->fileTotal = ret.fileTotal;
    result->fileProcessed = ret.fileProcessed;
    result->fileRemaining = ret.fileRemaining;
    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static unsigned long long
remoteDomainGetMaxMemory(virDomainPtr dom)
{
    unsigned long long rv = 0;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_get_max_memory_args args;
    remote_domain_get_max_memory_ret ret;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);

    memset(&ret, 0, sizeof(ret));

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_MAX_MEMORY,
             (xdrproc_t)xdr_remote_domain_get_max_memory_args, (char *)&args,
             (xdrproc_t)xdr_remote_domain_get_max_memory_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = ret.memory;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainGetMaxVcpus(virDomainPtr dom)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_get_max_vcpus_args args;
    remote_domain_get_max_vcpus_ret ret;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);

    memset(&ret, 0, sizeof(ret));

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_MAX_VCPUS,
             (xdrproc_t)xdr_remote_domain_get_max_vcpus_args, (char *)&args,
             (xdrproc_t)xdr_remote_domain_get_max_vcpus_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = ret.num;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static char *
remoteDomainGetMetadata(virDomainPtr dom, int type, const char *uri, unsigned int flags)
{
    char *rv = NULL;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_get_metadata_args args;
    remote_domain_get_metadata_ret ret;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.type = type;
    args.uri = uri ? (char **)&uri : NULL;
    args.flags = flags;

    memset(&ret, 0, sizeof(ret));

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_METADATA,
             (xdrproc_t)xdr_remote_domain_get_metadata_args, (char *)&args,
             (xdrproc_t)xdr_remote_domain_get_metadata_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = ret.metadata;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static char *
remoteDomainGetOSType(virDomainPtr dom)
{
    char *rv = NULL;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_get_os_type_args args;
    remote_domain_get_os_type_ret ret;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);

    memset(&ret, 0, sizeof(ret));

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_OS_TYPE,
             (xdrproc_t)xdr_remote_domain_get_os_type_args, (char *)&args,
             (xdrproc_t)xdr_remote_domain_get_os_type_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = ret.type;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainGetSchedulerParameters(virDomainPtr dom, virTypedParameterPtr params, int * nparams)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_get_scheduler_parameters_args args;
    remote_domain_get_scheduler_parameters_ret ret;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.nparams = *nparams;

    memset(&ret, 0, sizeof(ret));

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_SCHEDULER_PARAMETERS,
             (xdrproc_t)xdr_remote_domain_get_scheduler_parameters_args, (char *)&args,
             (xdrproc_t)xdr_remote_domain_get_scheduler_parameters_ret, (char *)&ret) == -1) {
        goto done;
    }

    if (remoteDeserializeTypedParameters(ret.params.params_val,
                                         ret.params.params_len,
                                         REMOTE_DOMAIN_SCHEDULER_PARAMETERS_MAX,
                                         params,
                                         nparams) < 0)
        goto cleanup;

    rv = 0;

cleanup:
    xdr_free((xdrproc_t)xdr_remote_domain_get_scheduler_parameters_ret, (char *)&ret);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainGetSchedulerParametersFlags(virDomainPtr dom, virTypedParameterPtr params, int * nparams, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_get_scheduler_parameters_flags_args args;
    remote_domain_get_scheduler_parameters_flags_ret ret;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.nparams = *nparams;
    args.flags = flags;

    memset(&ret, 0, sizeof(ret));

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_SCHEDULER_PARAMETERS_FLAGS,
             (xdrproc_t)xdr_remote_domain_get_scheduler_parameters_flags_args, (char *)&args,
             (xdrproc_t)xdr_remote_domain_get_scheduler_parameters_flags_ret, (char *)&ret) == -1) {
        goto done;
    }

    if (remoteDeserializeTypedParameters(ret.params.params_val,
                                         ret.params.params_len,
                                         REMOTE_DOMAIN_SCHEDULER_PARAMETERS_MAX,
                                         params,
                                         nparams) < 0)
        goto cleanup;

    rv = 0;

cleanup:
    xdr_free((xdrproc_t)xdr_remote_domain_get_scheduler_parameters_flags_ret, (char *)&ret);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainGetVcpusFlags(virDomainPtr dom, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_get_vcpus_flags_args args;
    remote_domain_get_vcpus_flags_ret ret;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.flags = flags;

    memset(&ret, 0, sizeof(ret));

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_VCPUS_FLAGS,
             (xdrproc_t)xdr_remote_domain_get_vcpus_flags_args, (char *)&args,
             (xdrproc_t)xdr_remote_domain_get_vcpus_flags_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = ret.num;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static char *
remoteDomainGetXMLDesc(virDomainPtr dom, unsigned int flags)
{
    char *rv = NULL;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_get_xml_desc_args args;
    remote_domain_get_xml_desc_ret ret;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.flags = flags;

    memset(&ret, 0, sizeof(ret));

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_XML_DESC,
             (xdrproc_t)xdr_remote_domain_get_xml_desc_args, (char *)&args,
             (xdrproc_t)xdr_remote_domain_get_xml_desc_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = ret.xml;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainHasCurrentSnapshot(virDomainPtr dom, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_has_current_snapshot_args args;
    remote_domain_has_current_snapshot_ret ret;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.flags = flags;

    memset(&ret, 0, sizeof(ret));

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_HAS_CURRENT_SNAPSHOT,
             (xdrproc_t)xdr_remote_domain_has_current_snapshot_args, (char *)&args,
             (xdrproc_t)xdr_remote_domain_has_current_snapshot_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = ret.result;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainHasManagedSaveImage(virDomainPtr dom, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_has_managed_save_image_args args;
    remote_domain_has_managed_save_image_ret ret;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.flags = flags;

    memset(&ret, 0, sizeof(ret));

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_HAS_MANAGED_SAVE_IMAGE,
             (xdrproc_t)xdr_remote_domain_has_managed_save_image_args, (char *)&args,
             (xdrproc_t)xdr_remote_domain_has_managed_save_image_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = ret.result;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainInjectNMI(virDomainPtr dom, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_inject_nmi_args args;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.flags = flags;

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_INJECT_NMI,
             (xdrproc_t)xdr_remote_domain_inject_nmi_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainInterfaceStats(virDomainPtr dom, const char *path, virDomainInterfaceStatsPtr result)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_interface_stats_args args;
    remote_domain_interface_stats_ret ret;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.path = (char *)path;

    memset(&ret, 0, sizeof(ret));

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_INTERFACE_STATS,
             (xdrproc_t)xdr_remote_domain_interface_stats_args, (char *)&args,
             (xdrproc_t)xdr_remote_domain_interface_stats_ret, (char *)&ret) == -1) {
        goto done;
    }

    result->rx_bytes = ret.rx_bytes;
    result->rx_packets = ret.rx_packets;
    result->rx_errs = ret.rx_errs;
    result->rx_drop = ret.rx_drop;
    result->tx_bytes = ret.tx_bytes;
    result->tx_packets = ret.tx_packets;
    result->tx_errs = ret.tx_errs;
    result->tx_drop = ret.tx_drop;
    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainIsActive(virDomainPtr dom)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_is_active_args args;
    remote_domain_is_active_ret ret;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);

    memset(&ret, 0, sizeof(ret));

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_IS_ACTIVE,
             (xdrproc_t)xdr_remote_domain_is_active_args, (char *)&args,
             (xdrproc_t)xdr_remote_domain_is_active_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = ret.active;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainIsPersistent(virDomainPtr dom)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_is_persistent_args args;
    remote_domain_is_persistent_ret ret;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);

    memset(&ret, 0, sizeof(ret));

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_IS_PERSISTENT,
             (xdrproc_t)xdr_remote_domain_is_persistent_args, (char *)&args,
             (xdrproc_t)xdr_remote_domain_is_persistent_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = ret.persistent;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainIsUpdated(virDomainPtr dom)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_is_updated_args args;
    remote_domain_is_updated_ret ret;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);

    memset(&ret, 0, sizeof(ret));

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_IS_UPDATED,
             (xdrproc_t)xdr_remote_domain_is_updated_args, (char *)&args,
             (xdrproc_t)xdr_remote_domain_is_updated_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = ret.updated;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static virDomainPtr
remoteDomainLookupByID(virConnectPtr conn, int id)
{
    virDomainPtr rv = NULL;
    struct private_data *priv = conn->privateData;
    remote_domain_lookup_by_id_args args;
    remote_domain_lookup_by_id_ret ret;

    remoteDriverLock(priv);

    args.id = id;

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_DOMAIN_LOOKUP_BY_ID,
             (xdrproc_t)xdr_remote_domain_lookup_by_id_args, (char *)&args,
             (xdrproc_t)xdr_remote_domain_lookup_by_id_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = get_nonnull_domain(conn, ret.dom);
    xdr_free((xdrproc_t)xdr_remote_domain_lookup_by_id_ret, (char *)&ret);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static virDomainPtr
remoteDomainLookupByName(virConnectPtr conn, const char *name)
{
    virDomainPtr rv = NULL;
    struct private_data *priv = conn->privateData;
    remote_domain_lookup_by_name_args args;
    remote_domain_lookup_by_name_ret ret;

    remoteDriverLock(priv);

    args.name = (char *)name;

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_DOMAIN_LOOKUP_BY_NAME,
             (xdrproc_t)xdr_remote_domain_lookup_by_name_args, (char *)&args,
             (xdrproc_t)xdr_remote_domain_lookup_by_name_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = get_nonnull_domain(conn, ret.dom);
    xdr_free((xdrproc_t)xdr_remote_domain_lookup_by_name_ret, (char *)&ret);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static virDomainPtr
remoteDomainLookupByUUID(virConnectPtr conn, const unsigned char *uuid)
{
    virDomainPtr rv = NULL;
    struct private_data *priv = conn->privateData;
    remote_domain_lookup_by_uuid_args args;
    remote_domain_lookup_by_uuid_ret ret;

    remoteDriverLock(priv);

    memcpy(args.uuid, uuid, VIR_UUID_BUFLEN);

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_DOMAIN_LOOKUP_BY_UUID,
             (xdrproc_t)xdr_remote_domain_lookup_by_uuid_args, (char *)&args,
             (xdrproc_t)xdr_remote_domain_lookup_by_uuid_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = get_nonnull_domain(conn, ret.dom);
    xdr_free((xdrproc_t)xdr_remote_domain_lookup_by_uuid_ret, (char *)&ret);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainManagedSave(virDomainPtr dom, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_managed_save_args args;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.flags = flags;

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_MANAGED_SAVE,
             (xdrproc_t)xdr_remote_domain_managed_save_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    dom->id = -1;
    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainManagedSaveRemove(virDomainPtr dom, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_managed_save_remove_args args;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.flags = flags;

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_MANAGED_SAVE_REMOVE,
             (xdrproc_t)xdr_remote_domain_managed_save_remove_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static virDomainPtr
remoteDomainMigrateFinish(virConnectPtr conn, const char *dname, const char *cookie, int cookielen, const char *uri, unsigned long flags)
{
    virDomainPtr rv = NULL;
    struct private_data *priv = conn->privateData;
    remote_domain_migrate_finish_args args;
    remote_domain_migrate_finish_ret ret;

    remoteDriverLock(priv);

    if (cookielen > REMOTE_MIGRATE_COOKIE_MAX) {
        remoteError(VIR_ERR_RPC,
                    _("%s length greater than maximum: %d > %d"),
                    "cookie", (int)cookielen, REMOTE_MIGRATE_COOKIE_MAX);
        goto done;
    }

    args.dname = (char *)dname;
    args.cookie.cookie_val = (char *)cookie;
    args.cookie.cookie_len = cookielen;
    args.uri = (char *)uri;
    args.flags = flags;

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_DOMAIN_MIGRATE_FINISH,
             (xdrproc_t)xdr_remote_domain_migrate_finish_args, (char *)&args,
             (xdrproc_t)xdr_remote_domain_migrate_finish_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = get_nonnull_domain(conn, ret.ddom);
    xdr_free((xdrproc_t)xdr_remote_domain_migrate_finish_ret, (char *)&ret);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static virDomainPtr
remoteDomainMigrateFinish2(virConnectPtr conn, const char *dname, const char *cookie, int cookielen, const char *uri, unsigned long flags, int retcode)
{
    virDomainPtr rv = NULL;
    struct private_data *priv = conn->privateData;
    remote_domain_migrate_finish2_args args;
    remote_domain_migrate_finish2_ret ret;

    remoteDriverLock(priv);

    if (cookielen > REMOTE_MIGRATE_COOKIE_MAX) {
        remoteError(VIR_ERR_RPC,
                    _("%s length greater than maximum: %d > %d"),
                    "cookie", (int)cookielen, REMOTE_MIGRATE_COOKIE_MAX);
        goto done;
    }

    args.dname = (char *)dname;
    args.cookie.cookie_val = (char *)cookie;
    args.cookie.cookie_len = cookielen;
    args.uri = (char *)uri;
    args.flags = flags;
    args.retcode = retcode;

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_DOMAIN_MIGRATE_FINISH2,
             (xdrproc_t)xdr_remote_domain_migrate_finish2_args, (char *)&args,
             (xdrproc_t)xdr_remote_domain_migrate_finish2_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = get_nonnull_domain(conn, ret.ddom);
    xdr_free((xdrproc_t)xdr_remote_domain_migrate_finish2_ret, (char *)&ret);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainMigrateGetMaxSpeed(virDomainPtr dom, unsigned long *bandwidth, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_migrate_get_max_speed_args args;
    remote_domain_migrate_get_max_speed_ret ret;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.flags = flags;

    memset(&ret, 0, sizeof(ret));

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_MIGRATE_GET_MAX_SPEED,
             (xdrproc_t)xdr_remote_domain_migrate_get_max_speed_args, (char *)&args,
             (xdrproc_t)xdr_remote_domain_migrate_get_max_speed_ret, (char *)&ret) == -1) {
        goto done;
    }

    if (bandwidth) HYPER_TO_ULONG(*bandwidth, ret.bandwidth);
    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainMigratePerform(virDomainPtr dom, const char *cookie, int cookielen, const char *uri, unsigned long flags, const char *dname, unsigned long resource)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_migrate_perform_args args;

    remoteDriverLock(priv);

    if (cookielen > REMOTE_MIGRATE_COOKIE_MAX) {
        remoteError(VIR_ERR_RPC,
                    _("%s length greater than maximum: %d > %d"),
                    "cookie", (int)cookielen, REMOTE_MIGRATE_COOKIE_MAX);
        goto done;
    }

    make_nonnull_domain(&args.dom, dom);
    args.cookie.cookie_val = (char *)cookie;
    args.cookie.cookie_len = cookielen;
    args.uri = (char *)uri;
    args.flags = flags;
    args.dname = dname ? (char **)&dname : NULL;
    args.resource = resource;

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_MIGRATE_PERFORM,
             (xdrproc_t)xdr_remote_domain_migrate_perform_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainMigratePrepareTunnel(virConnectPtr conn, virStreamPtr st, unsigned long flags, const char *dname, unsigned long resource, const char *dom_xml)
{
    int rv = -1;
    struct private_data *priv = conn->privateData;
    remote_domain_migrate_prepare_tunnel_args args;
    virNetClientStreamPtr netst = NULL;

    remoteDriverLock(priv);

    if (!(netst = virNetClientStreamNew(priv->remoteProgram, REMOTE_PROC_DOMAIN_MIGRATE_PREPARE_TUNNEL, priv->counter)))
        goto done;

    if (virNetClientAddStream(priv->client, netst) < 0) {
        virNetClientStreamFree(netst);
        goto done;
    }
    st->driver = &remoteStreamDrv;
    st->privateData = netst;

    args.flags = flags;
    args.dname = dname ? (char **)&dname : NULL;
    args.resource = resource;
    args.dom_xml = (char *)dom_xml;

    if (call(conn, priv, 0, REMOTE_PROC_DOMAIN_MIGRATE_PREPARE_TUNNEL,
             (xdrproc_t)xdr_remote_domain_migrate_prepare_tunnel_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        virNetClientRemoveStream(priv->client, netst);
        virNetClientStreamFree(netst);
        st->driver = NULL;
        st->privateData = NULL;
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainMigrateSetMaxDowntime(virDomainPtr dom, unsigned long long downtime, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_migrate_set_max_downtime_args args;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.downtime = downtime;
    args.flags = flags;

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_MIGRATE_SET_MAX_DOWNTIME,
             (xdrproc_t)xdr_remote_domain_migrate_set_max_downtime_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainMigrateSetMaxSpeed(virDomainPtr dom, unsigned long bandwidth, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_migrate_set_max_speed_args args;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.bandwidth = bandwidth;
    args.flags = flags;

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_MIGRATE_SET_MAX_SPEED,
             (xdrproc_t)xdr_remote_domain_migrate_set_max_speed_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainOpenConsole(virDomainPtr dom, const char *dev_name, virStreamPtr st, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_open_console_args args;
    virNetClientStreamPtr netst = NULL;

    remoteDriverLock(priv);

    if (!(netst = virNetClientStreamNew(priv->remoteProgram, REMOTE_PROC_DOMAIN_OPEN_CONSOLE, priv->counter)))
        goto done;

    if (virNetClientAddStream(priv->client, netst) < 0) {
        virNetClientStreamFree(netst);
        goto done;
    }
    st->driver = &remoteStreamDrv;
    st->privateData = netst;

    make_nonnull_domain(&args.dom, dom);
    args.dev_name = dev_name ? (char **)&dev_name : NULL;
    args.flags = flags;

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_OPEN_CONSOLE,
             (xdrproc_t)xdr_remote_domain_open_console_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        virNetClientRemoveStream(priv->client, netst);
        virNetClientStreamFree(netst);
        st->driver = NULL;
        st->privateData = NULL;
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainPinVcpu(virDomainPtr dom, unsigned int vcpu, unsigned char *cpumap, int cpumaplen)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_pin_vcpu_args args;

    remoteDriverLock(priv);

    if (cpumaplen > REMOTE_CPUMAP_MAX) {
        remoteError(VIR_ERR_RPC,
                    _("%s length greater than maximum: %d > %d"),
                    "cpumap", (int)cpumaplen, REMOTE_CPUMAP_MAX);
        goto done;
    }

    make_nonnull_domain(&args.dom, dom);
    args.vcpu = vcpu;
    args.cpumap.cpumap_val = (char *)cpumap;
    args.cpumap.cpumap_len = cpumaplen;

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_PIN_VCPU,
             (xdrproc_t)xdr_remote_domain_pin_vcpu_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainPinVcpuFlags(virDomainPtr dom, unsigned int vcpu, unsigned char *cpumap, int cpumaplen, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_pin_vcpu_flags_args args;

    remoteDriverLock(priv);

    if (cpumaplen > REMOTE_CPUMAP_MAX) {
        remoteError(VIR_ERR_RPC,
                    _("%s length greater than maximum: %d > %d"),
                    "cpumap", (int)cpumaplen, REMOTE_CPUMAP_MAX);
        goto done;
    }

    make_nonnull_domain(&args.dom, dom);
    args.vcpu = vcpu;
    args.cpumap.cpumap_val = (char *)cpumap;
    args.cpumap.cpumap_len = cpumaplen;
    args.flags = flags;

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_PIN_VCPU_FLAGS,
             (xdrproc_t)xdr_remote_domain_pin_vcpu_flags_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainPMSuspendForDuration(virDomainPtr dom, unsigned int target, unsigned long long duration, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_pm_suspend_for_duration_args args;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.target = target;
    args.duration = duration;
    args.flags = flags;

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_PM_SUSPEND_FOR_DURATION,
             (xdrproc_t)xdr_remote_domain_pm_suspend_for_duration_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainPMWakeup(virDomainPtr dom, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_pm_wakeup_args args;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.flags = flags;

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_PM_WAKEUP,
             (xdrproc_t)xdr_remote_domain_pm_wakeup_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainReboot(virDomainPtr dom, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_reboot_args args;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.flags = flags;

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_REBOOT,
             (xdrproc_t)xdr_remote_domain_reboot_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainReset(virDomainPtr dom, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_reset_args args;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.flags = flags;

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_RESET,
             (xdrproc_t)xdr_remote_domain_reset_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainRestore(virConnectPtr conn, const char *from)
{
    int rv = -1;
    struct private_data *priv = conn->privateData;
    remote_domain_restore_args args;

    remoteDriverLock(priv);

    args.from = (char *)from;

    if (call(conn, priv, 0, REMOTE_PROC_DOMAIN_RESTORE,
             (xdrproc_t)xdr_remote_domain_restore_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainRestoreFlags(virConnectPtr conn, const char *from, const char *dxml, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = conn->privateData;
    remote_domain_restore_flags_args args;

    remoteDriverLock(priv);

    args.from = (char *)from;
    args.dxml = dxml ? (char **)&dxml : NULL;
    args.flags = flags;

    if (call(conn, priv, 0, REMOTE_PROC_DOMAIN_RESTORE_FLAGS,
             (xdrproc_t)xdr_remote_domain_restore_flags_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainResume(virDomainPtr dom)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_resume_args args;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_RESUME,
             (xdrproc_t)xdr_remote_domain_resume_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainRevertToSnapshot(virDomainSnapshotPtr snap, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = snap->domain->conn->privateData;
    remote_domain_revert_to_snapshot_args args;

    remoteDriverLock(priv);

    make_nonnull_domain_snapshot(&args.snap, snap);
    args.flags = flags;

    if (call(snap->domain->conn, priv, 0, REMOTE_PROC_DOMAIN_REVERT_TO_SNAPSHOT,
             (xdrproc_t)xdr_remote_domain_revert_to_snapshot_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainSave(virDomainPtr dom, const char *to)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_save_args args;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.to = (char *)to;

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_SAVE,
             (xdrproc_t)xdr_remote_domain_save_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    dom->id = -1;
    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainSaveFlags(virDomainPtr dom, const char *to, const char *dxml, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_save_flags_args args;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.to = (char *)to;
    args.dxml = dxml ? (char **)&dxml : NULL;
    args.flags = flags;

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_SAVE_FLAGS,
             (xdrproc_t)xdr_remote_domain_save_flags_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainSaveImageDefineXML(virConnectPtr conn, const char *file, const char *dxml, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = conn->privateData;
    remote_domain_save_image_define_xml_args args;

    remoteDriverLock(priv);

    args.file = (char *)file;
    args.dxml = (char *)dxml;
    args.flags = flags;

    if (call(conn, priv, 0, REMOTE_PROC_DOMAIN_SAVE_IMAGE_DEFINE_XML,
             (xdrproc_t)xdr_remote_domain_save_image_define_xml_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static char *
remoteDomainSaveImageGetXMLDesc(virConnectPtr conn, const char *file, unsigned int flags)
{
    char *rv = NULL;
    struct private_data *priv = conn->privateData;
    remote_domain_save_image_get_xml_desc_args args;
    remote_domain_save_image_get_xml_desc_ret ret;

    remoteDriverLock(priv);

    args.file = (char *)file;
    args.flags = flags;

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_DOMAIN_SAVE_IMAGE_GET_XML_DESC,
             (xdrproc_t)xdr_remote_domain_save_image_get_xml_desc_args, (char *)&args,
             (xdrproc_t)xdr_remote_domain_save_image_get_xml_desc_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = ret.xml;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static char *
remoteDomainScreenshot(virDomainPtr dom, virStreamPtr st, unsigned int screen, unsigned int flags)
{
    char *rv = NULL;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_screenshot_args args;
    remote_domain_screenshot_ret ret;
    virNetClientStreamPtr netst = NULL;

    remoteDriverLock(priv);

    if (!(netst = virNetClientStreamNew(priv->remoteProgram, REMOTE_PROC_DOMAIN_SCREENSHOT, priv->counter)))
        goto done;

    if (virNetClientAddStream(priv->client, netst) < 0) {
        virNetClientStreamFree(netst);
        goto done;
    }
    st->driver = &remoteStreamDrv;
    st->privateData = netst;

    make_nonnull_domain(&args.dom, dom);
    args.screen = screen;
    args.flags = flags;

    memset(&ret, 0, sizeof(ret));

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_SCREENSHOT,
             (xdrproc_t)xdr_remote_domain_screenshot_args, (char *)&args,
             (xdrproc_t)xdr_remote_domain_screenshot_ret, (char *)&ret) == -1) {
        virNetClientRemoveStream(priv->client, netst);
        virNetClientStreamFree(netst);
        st->driver = NULL;
        st->privateData = NULL;
        goto done;
    }

    rv = ret.mime ? *ret.mime : NULL;
    VIR_FREE(ret.mime);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainSendKey(virDomainPtr dom, unsigned int codeset, unsigned int holdtime, unsigned int *keycodes, int keycodeslen, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_send_key_args args;

    remoteDriverLock(priv);

    if (keycodeslen > REMOTE_DOMAIN_SEND_KEY_MAX) {
        remoteError(VIR_ERR_RPC,
                    _("%s length greater than maximum: %d > %d"),
                    "keycodes", (int)keycodeslen, REMOTE_DOMAIN_SEND_KEY_MAX);
        goto done;
    }

    make_nonnull_domain(&args.dom, dom);
    args.codeset = codeset;
    args.holdtime = holdtime;
    args.keycodes.keycodes_val = keycodes;
    args.keycodes.keycodes_len = keycodeslen;
    args.flags = flags;

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_SEND_KEY,
             (xdrproc_t)xdr_remote_domain_send_key_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainSetAutostart(virDomainPtr dom, int autostart)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_set_autostart_args args;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.autostart = autostart;

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_SET_AUTOSTART,
             (xdrproc_t)xdr_remote_domain_set_autostart_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainSetBlkioParameters(virDomainPtr dom, virTypedParameterPtr params, int nparams, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_set_blkio_parameters_args args;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.flags = flags;

    if (remoteSerializeTypedParameters(params, nparams, &args.params.params_val, &args.params.params_len) < 0) {
        xdr_free((xdrproc_t)xdr_remote_domain_set_blkio_parameters_args, (char *)&args);
        goto done;
    }

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_SET_BLKIO_PARAMETERS,
             (xdrproc_t)xdr_remote_domain_set_blkio_parameters_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteFreeTypedParameters(args.params.params_val, args.params.params_len);
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainSetBlockIoTune(virDomainPtr dom, const char *disk, virTypedParameterPtr params, int nparams, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_set_block_io_tune_args args;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.disk = (char *)disk;
    args.flags = flags;

    if (remoteSerializeTypedParameters(params, nparams, &args.params.params_val, &args.params.params_len) < 0) {
        xdr_free((xdrproc_t)xdr_remote_domain_set_block_io_tune_args, (char *)&args);
        goto done;
    }

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_SET_BLOCK_IO_TUNE,
             (xdrproc_t)xdr_remote_domain_set_block_io_tune_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteFreeTypedParameters(args.params.params_val, args.params.params_len);
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainSetInterfaceParameters(virDomainPtr dom, const char *device, virTypedParameterPtr params, int nparams, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_set_interface_parameters_args args;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.device = (char *)device;
    args.flags = flags;

    if (remoteSerializeTypedParameters(params, nparams, &args.params.params_val, &args.params.params_len) < 0) {
        xdr_free((xdrproc_t)xdr_remote_domain_set_interface_parameters_args, (char *)&args);
        goto done;
    }

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_SET_INTERFACE_PARAMETERS,
             (xdrproc_t)xdr_remote_domain_set_interface_parameters_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteFreeTypedParameters(args.params.params_val, args.params.params_len);
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainSetMaxMemory(virDomainPtr dom, unsigned long memory)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_set_max_memory_args args;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.memory = memory;

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_SET_MAX_MEMORY,
             (xdrproc_t)xdr_remote_domain_set_max_memory_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainSetMemory(virDomainPtr dom, unsigned long memory)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_set_memory_args args;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.memory = memory;

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_SET_MEMORY,
             (xdrproc_t)xdr_remote_domain_set_memory_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainSetMemoryFlags(virDomainPtr dom, unsigned long memory, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_set_memory_flags_args args;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.memory = memory;
    args.flags = flags;

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_SET_MEMORY_FLAGS,
             (xdrproc_t)xdr_remote_domain_set_memory_flags_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainSetMemoryParameters(virDomainPtr dom, virTypedParameterPtr params, int nparams, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_set_memory_parameters_args args;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.flags = flags;

    if (remoteSerializeTypedParameters(params, nparams, &args.params.params_val, &args.params.params_len) < 0) {
        xdr_free((xdrproc_t)xdr_remote_domain_set_memory_parameters_args, (char *)&args);
        goto done;
    }

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_SET_MEMORY_PARAMETERS,
             (xdrproc_t)xdr_remote_domain_set_memory_parameters_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteFreeTypedParameters(args.params.params_val, args.params.params_len);
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainSetMetadata(virDomainPtr dom, int type, const char *metadata, const char *key, const char *uri, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_set_metadata_args args;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.type = type;
    args.metadata = metadata ? (char **)&metadata : NULL;
    args.key = key ? (char **)&key : NULL;
    args.uri = uri ? (char **)&uri : NULL;
    args.flags = flags;

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_SET_METADATA,
             (xdrproc_t)xdr_remote_domain_set_metadata_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainSetNumaParameters(virDomainPtr dom, virTypedParameterPtr params, int nparams, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_set_numa_parameters_args args;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.flags = flags;

    if (remoteSerializeTypedParameters(params, nparams, &args.params.params_val, &args.params.params_len) < 0) {
        xdr_free((xdrproc_t)xdr_remote_domain_set_numa_parameters_args, (char *)&args);
        goto done;
    }

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_SET_NUMA_PARAMETERS,
             (xdrproc_t)xdr_remote_domain_set_numa_parameters_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteFreeTypedParameters(args.params.params_val, args.params.params_len);
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainSetSchedulerParameters(virDomainPtr dom, virTypedParameterPtr params, int nparams)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_set_scheduler_parameters_args args;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);

    if (remoteSerializeTypedParameters(params, nparams, &args.params.params_val, &args.params.params_len) < 0) {
        xdr_free((xdrproc_t)xdr_remote_domain_set_scheduler_parameters_args, (char *)&args);
        goto done;
    }

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_SET_SCHEDULER_PARAMETERS,
             (xdrproc_t)xdr_remote_domain_set_scheduler_parameters_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteFreeTypedParameters(args.params.params_val, args.params.params_len);
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainSetSchedulerParametersFlags(virDomainPtr dom, virTypedParameterPtr params, int nparams, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_set_scheduler_parameters_flags_args args;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.flags = flags;

    if (remoteSerializeTypedParameters(params, nparams, &args.params.params_val, &args.params.params_len) < 0) {
        xdr_free((xdrproc_t)xdr_remote_domain_set_scheduler_parameters_flags_args, (char *)&args);
        goto done;
    }

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_SET_SCHEDULER_PARAMETERS_FLAGS,
             (xdrproc_t)xdr_remote_domain_set_scheduler_parameters_flags_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteFreeTypedParameters(args.params.params_val, args.params.params_len);
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainSetVcpus(virDomainPtr dom, unsigned int nvcpus)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_set_vcpus_args args;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.nvcpus = nvcpus;

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_SET_VCPUS,
             (xdrproc_t)xdr_remote_domain_set_vcpus_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_set_vcpus_flags_args args;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.nvcpus = nvcpus;
    args.flags = flags;

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_SET_VCPUS_FLAGS,
             (xdrproc_t)xdr_remote_domain_set_vcpus_flags_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainShutdown(virDomainPtr dom)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_shutdown_args args;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_SHUTDOWN,
             (xdrproc_t)xdr_remote_domain_shutdown_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainShutdownFlags(virDomainPtr dom, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_shutdown_flags_args args;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.flags = flags;

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_SHUTDOWN_FLAGS,
             (xdrproc_t)xdr_remote_domain_shutdown_flags_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static virDomainSnapshotPtr
remoteDomainSnapshotCreateXML(virDomainPtr dom, const char *xml_desc, unsigned int flags)
{
    virDomainSnapshotPtr rv = NULL;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_snapshot_create_xml_args args;
    remote_domain_snapshot_create_xml_ret ret;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.xml_desc = (char *)xml_desc;
    args.flags = flags;

    memset(&ret, 0, sizeof(ret));

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_SNAPSHOT_CREATE_XML,
             (xdrproc_t)xdr_remote_domain_snapshot_create_xml_args, (char *)&args,
             (xdrproc_t)xdr_remote_domain_snapshot_create_xml_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = get_nonnull_domain_snapshot(dom, ret.snap);
    xdr_free((xdrproc_t)xdr_remote_domain_snapshot_create_xml_ret, (char *)&ret);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static virDomainSnapshotPtr
remoteDomainSnapshotCurrent(virDomainPtr dom, unsigned int flags)
{
    virDomainSnapshotPtr rv = NULL;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_snapshot_current_args args;
    remote_domain_snapshot_current_ret ret;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.flags = flags;

    memset(&ret, 0, sizeof(ret));

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_SNAPSHOT_CURRENT,
             (xdrproc_t)xdr_remote_domain_snapshot_current_args, (char *)&args,
             (xdrproc_t)xdr_remote_domain_snapshot_current_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = get_nonnull_domain_snapshot(dom, ret.snap);
    xdr_free((xdrproc_t)xdr_remote_domain_snapshot_current_ret, (char *)&ret);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainSnapshotDelete(virDomainSnapshotPtr snap, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = snap->domain->conn->privateData;
    remote_domain_snapshot_delete_args args;

    remoteDriverLock(priv);

    make_nonnull_domain_snapshot(&args.snap, snap);
    args.flags = flags;

    if (call(snap->domain->conn, priv, 0, REMOTE_PROC_DOMAIN_SNAPSHOT_DELETE,
             (xdrproc_t)xdr_remote_domain_snapshot_delete_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static virDomainSnapshotPtr
remoteDomainSnapshotGetParent(virDomainSnapshotPtr snap, unsigned int flags)
{
    virDomainSnapshotPtr rv = NULL;
    struct private_data *priv = snap->domain->conn->privateData;
    remote_domain_snapshot_get_parent_args args;
    remote_domain_snapshot_get_parent_ret ret;

    remoteDriverLock(priv);

    make_nonnull_domain_snapshot(&args.snap, snap);
    args.flags = flags;

    memset(&ret, 0, sizeof(ret));

    if (call(snap->domain->conn, priv, 0, REMOTE_PROC_DOMAIN_SNAPSHOT_GET_PARENT,
             (xdrproc_t)xdr_remote_domain_snapshot_get_parent_args, (char *)&args,
             (xdrproc_t)xdr_remote_domain_snapshot_get_parent_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = get_nonnull_domain_snapshot(snap->domain, ret.snap);
    xdr_free((xdrproc_t)xdr_remote_domain_snapshot_get_parent_ret, (char *)&ret);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static char *
remoteDomainSnapshotGetXMLDesc(virDomainSnapshotPtr snap, unsigned int flags)
{
    char *rv = NULL;
    struct private_data *priv = snap->domain->conn->privateData;
    remote_domain_snapshot_get_xml_desc_args args;
    remote_domain_snapshot_get_xml_desc_ret ret;

    remoteDriverLock(priv);

    make_nonnull_domain_snapshot(&args.snap, snap);
    args.flags = flags;

    memset(&ret, 0, sizeof(ret));

    if (call(snap->domain->conn, priv, 0, REMOTE_PROC_DOMAIN_SNAPSHOT_GET_XML_DESC,
             (xdrproc_t)xdr_remote_domain_snapshot_get_xml_desc_args, (char *)&args,
             (xdrproc_t)xdr_remote_domain_snapshot_get_xml_desc_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = ret.xml;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainSnapshotListChildrenNames(virDomainSnapshotPtr snap, char **const names, int maxnames, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = snap->domain->conn->privateData;
    remote_domain_snapshot_list_children_names_args args;
    remote_domain_snapshot_list_children_names_ret ret;
    int i;

    remoteDriverLock(priv);

    if (maxnames > REMOTE_DOMAIN_SNAPSHOT_LIST_NAMES_MAX) {
        remoteError(VIR_ERR_RPC,
                    _("too many remote undefineds: %d > %d"),
                    maxnames, REMOTE_DOMAIN_SNAPSHOT_LIST_NAMES_MAX);
        goto done;
    }

    make_nonnull_domain_snapshot(&args.snap, snap);
    args.maxnames = maxnames;
    args.flags = flags;

    memset(&ret, 0, sizeof(ret));

    if (call(snap->domain->conn, priv, 0, REMOTE_PROC_DOMAIN_SNAPSHOT_LIST_CHILDREN_NAMES,
             (xdrproc_t)xdr_remote_domain_snapshot_list_children_names_args, (char *)&args,
             (xdrproc_t)xdr_remote_domain_snapshot_list_children_names_ret, (char *)&ret) == -1) {
        goto done;
    }

    if (ret.names.names_len > maxnames) {
        remoteError(VIR_ERR_RPC,
                    _("too many remote undefineds: %d > %d"),
                    ret.names.names_len, maxnames);
        goto cleanup;
    }

    /* This call is caller-frees (although that isn't clear from
     * the documentation).  However xdr_free will free up both the
     * names and the list of pointers, so we have to strdup the
     * names here. */
    for (i = 0; i < ret.names.names_len; ++i) {
        names[i] = strdup(ret.names.names_val[i]);

        if (names[i] == NULL) {
            for (--i; i >= 0; --i)
                VIR_FREE(names[i]);

            virReportOOMError();
            goto cleanup;
        }
    }

    rv = ret.names.names_len;

cleanup:
    xdr_free((xdrproc_t)xdr_remote_domain_snapshot_list_children_names_ret, (char *)&ret);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainSnapshotListNames(virDomainPtr dom, char **const names, int maxnames, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_snapshot_list_names_args args;
    remote_domain_snapshot_list_names_ret ret;
    int i;

    remoteDriverLock(priv);

    if (maxnames > REMOTE_DOMAIN_SNAPSHOT_LIST_NAMES_MAX) {
        remoteError(VIR_ERR_RPC,
                    _("too many remote undefineds: %d > %d"),
                    maxnames, REMOTE_DOMAIN_SNAPSHOT_LIST_NAMES_MAX);
        goto done;
    }

    make_nonnull_domain(&args.dom, dom);
    args.maxnames = maxnames;
    args.flags = flags;

    memset(&ret, 0, sizeof(ret));

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_SNAPSHOT_LIST_NAMES,
             (xdrproc_t)xdr_remote_domain_snapshot_list_names_args, (char *)&args,
             (xdrproc_t)xdr_remote_domain_snapshot_list_names_ret, (char *)&ret) == -1) {
        goto done;
    }

    if (ret.names.names_len > maxnames) {
        remoteError(VIR_ERR_RPC,
                    _("too many remote undefineds: %d > %d"),
                    ret.names.names_len, maxnames);
        goto cleanup;
    }

    /* This call is caller-frees (although that isn't clear from
     * the documentation).  However xdr_free will free up both the
     * names and the list of pointers, so we have to strdup the
     * names here. */
    for (i = 0; i < ret.names.names_len; ++i) {
        names[i] = strdup(ret.names.names_val[i]);

        if (names[i] == NULL) {
            for (--i; i >= 0; --i)
                VIR_FREE(names[i]);

            virReportOOMError();
            goto cleanup;
        }
    }

    rv = ret.names.names_len;

cleanup:
    xdr_free((xdrproc_t)xdr_remote_domain_snapshot_list_names_ret, (char *)&ret);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static virDomainSnapshotPtr
remoteDomainSnapshotLookupByName(virDomainPtr dom, const char *name, unsigned int flags)
{
    virDomainSnapshotPtr rv = NULL;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_snapshot_lookup_by_name_args args;
    remote_domain_snapshot_lookup_by_name_ret ret;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.name = (char *)name;
    args.flags = flags;

    memset(&ret, 0, sizeof(ret));

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_SNAPSHOT_LOOKUP_BY_NAME,
             (xdrproc_t)xdr_remote_domain_snapshot_lookup_by_name_args, (char *)&args,
             (xdrproc_t)xdr_remote_domain_snapshot_lookup_by_name_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = get_nonnull_domain_snapshot(dom, ret.snap);
    xdr_free((xdrproc_t)xdr_remote_domain_snapshot_lookup_by_name_ret, (char *)&ret);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainSnapshotNum(virDomainPtr dom, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_snapshot_num_args args;
    remote_domain_snapshot_num_ret ret;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.flags = flags;

    memset(&ret, 0, sizeof(ret));

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_SNAPSHOT_NUM,
             (xdrproc_t)xdr_remote_domain_snapshot_num_args, (char *)&args,
             (xdrproc_t)xdr_remote_domain_snapshot_num_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = ret.num;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainSnapshotNumChildren(virDomainSnapshotPtr snap, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = snap->domain->conn->privateData;
    remote_domain_snapshot_num_children_args args;
    remote_domain_snapshot_num_children_ret ret;

    remoteDriverLock(priv);

    make_nonnull_domain_snapshot(&args.snap, snap);
    args.flags = flags;

    memset(&ret, 0, sizeof(ret));

    if (call(snap->domain->conn, priv, 0, REMOTE_PROC_DOMAIN_SNAPSHOT_NUM_CHILDREN,
             (xdrproc_t)xdr_remote_domain_snapshot_num_children_args, (char *)&args,
             (xdrproc_t)xdr_remote_domain_snapshot_num_children_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = ret.num;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainSuspend(virDomainPtr dom)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_suspend_args args;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_SUSPEND,
             (xdrproc_t)xdr_remote_domain_suspend_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainUndefine(virDomainPtr dom)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_undefine_args args;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_UNDEFINE,
             (xdrproc_t)xdr_remote_domain_undefine_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainUndefineFlags(virDomainPtr dom, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_undefine_flags_args args;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.flags = flags;

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_UNDEFINE_FLAGS,
             (xdrproc_t)xdr_remote_domain_undefine_flags_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteDomainUpdateDeviceFlags(virDomainPtr dom, const char *xml, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = dom->conn->privateData;
    remote_domain_update_device_flags_args args;

    remoteDriverLock(priv);

    make_nonnull_domain(&args.dom, dom);
    args.xml = (char *)xml;
    args.flags = flags;

    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_UPDATE_DEVICE_FLAGS,
             (xdrproc_t)xdr_remote_domain_update_device_flags_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static char *
remoteDomainXMLFromNative(virConnectPtr conn, const char *nativeFormat, const char *nativeConfig, unsigned int flags)
{
    char *rv = NULL;
    struct private_data *priv = conn->privateData;
    remote_domain_xml_from_native_args args;
    remote_domain_xml_from_native_ret ret;

    remoteDriverLock(priv);

    args.nativeFormat = (char *)nativeFormat;
    args.nativeConfig = (char *)nativeConfig;
    args.flags = flags;

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_DOMAIN_XML_FROM_NATIVE,
             (xdrproc_t)xdr_remote_domain_xml_from_native_args, (char *)&args,
             (xdrproc_t)xdr_remote_domain_xml_from_native_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = ret.domainXml;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static char *
remoteDomainXMLToNative(virConnectPtr conn, const char *nativeFormat, const char *domainXml, unsigned int flags)
{
    char *rv = NULL;
    struct private_data *priv = conn->privateData;
    remote_domain_xml_to_native_args args;
    remote_domain_xml_to_native_ret ret;

    remoteDriverLock(priv);

    args.nativeFormat = (char *)nativeFormat;
    args.domainXml = (char *)domainXml;
    args.flags = flags;

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_DOMAIN_XML_TO_NATIVE,
             (xdrproc_t)xdr_remote_domain_xml_to_native_args, (char *)&args,
             (xdrproc_t)xdr_remote_domain_xml_to_native_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = ret.nativeConfig;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static char *
remoteGetCapabilities(virConnectPtr conn)
{
    char *rv = NULL;
    struct private_data *priv = conn->privateData;
    remote_get_capabilities_ret ret;

    remoteDriverLock(priv);

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_GET_CAPABILITIES,
             (xdrproc_t)xdr_void, (char *)NULL,
             (xdrproc_t)xdr_remote_get_capabilities_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = ret.capabilities;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static char *
remoteGetHostname(virConnectPtr conn)
{
    char *rv = NULL;
    struct private_data *priv = conn->privateData;
    remote_get_hostname_ret ret;

    remoteDriverLock(priv);

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_GET_HOSTNAME,
             (xdrproc_t)xdr_void, (char *)NULL,
             (xdrproc_t)xdr_remote_get_hostname_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = ret.hostname;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteGetLibVersion(virConnectPtr conn, unsigned long *lib_ver)
{
    int rv = -1;
    struct private_data *priv = conn->privateData;
    remote_get_lib_version_ret ret;

    remoteDriverLock(priv);

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_GET_LIB_VERSION,
             (xdrproc_t)xdr_void, (char *)NULL,
             (xdrproc_t)xdr_remote_get_lib_version_ret, (char *)&ret) == -1) {
        goto done;
    }

    if (lib_ver) HYPER_TO_ULONG(*lib_ver, ret.lib_ver);
    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteGetMaxVcpus(virConnectPtr conn, const char *type)
{
    int rv = -1;
    struct private_data *priv = conn->privateData;
    remote_get_max_vcpus_args args;
    remote_get_max_vcpus_ret ret;

    remoteDriverLock(priv);

    args.type = type ? (char **)&type : NULL;

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_GET_MAX_VCPUS,
             (xdrproc_t)xdr_remote_get_max_vcpus_args, (char *)&args,
             (xdrproc_t)xdr_remote_get_max_vcpus_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = ret.max_vcpus;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static char *
remoteGetSysinfo(virConnectPtr conn, unsigned int flags)
{
    char *rv = NULL;
    struct private_data *priv = conn->privateData;
    remote_get_sysinfo_args args;
    remote_get_sysinfo_ret ret;

    remoteDriverLock(priv);

    args.flags = flags;

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_GET_SYSINFO,
             (xdrproc_t)xdr_remote_get_sysinfo_args, (char *)&args,
             (xdrproc_t)xdr_remote_get_sysinfo_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = ret.sysinfo;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteGetVersion(virConnectPtr conn, unsigned long *hv_ver)
{
    int rv = -1;
    struct private_data *priv = conn->privateData;
    remote_get_version_ret ret;

    remoteDriverLock(priv);

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_GET_VERSION,
             (xdrproc_t)xdr_void, (char *)NULL,
             (xdrproc_t)xdr_remote_get_version_ret, (char *)&ret) == -1) {
        goto done;
    }

    if (hv_ver) HYPER_TO_ULONG(*hv_ver, ret.hv_ver);
    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteInterfaceChangeBegin(virConnectPtr conn, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = conn->privateData;
    remote_interface_change_begin_args args;

    remoteDriverLock(priv);

    args.flags = flags;

    if (call(conn, priv, 0, REMOTE_PROC_INTERFACE_CHANGE_BEGIN,
             (xdrproc_t)xdr_remote_interface_change_begin_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteInterfaceChangeCommit(virConnectPtr conn, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = conn->privateData;
    remote_interface_change_commit_args args;

    remoteDriverLock(priv);

    args.flags = flags;

    if (call(conn, priv, 0, REMOTE_PROC_INTERFACE_CHANGE_COMMIT,
             (xdrproc_t)xdr_remote_interface_change_commit_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteInterfaceChangeRollback(virConnectPtr conn, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = conn->privateData;
    remote_interface_change_rollback_args args;

    remoteDriverLock(priv);

    args.flags = flags;

    if (call(conn, priv, 0, REMOTE_PROC_INTERFACE_CHANGE_ROLLBACK,
             (xdrproc_t)xdr_remote_interface_change_rollback_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteInterfaceCreate(virInterfacePtr iface, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = iface->conn->interfacePrivateData;
    remote_interface_create_args args;

    remoteDriverLock(priv);

    make_nonnull_interface(&args.iface, iface);
    args.flags = flags;

    if (call(iface->conn, priv, 0, REMOTE_PROC_INTERFACE_CREATE,
             (xdrproc_t)xdr_remote_interface_create_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static virInterfacePtr
remoteInterfaceDefineXML(virConnectPtr conn, const char *xml, unsigned int flags)
{
    virInterfacePtr rv = NULL;
    struct private_data *priv = conn->interfacePrivateData;
    remote_interface_define_xml_args args;
    remote_interface_define_xml_ret ret;

    remoteDriverLock(priv);

    args.xml = (char *)xml;
    args.flags = flags;

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_INTERFACE_DEFINE_XML,
             (xdrproc_t)xdr_remote_interface_define_xml_args, (char *)&args,
             (xdrproc_t)xdr_remote_interface_define_xml_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = get_nonnull_interface(conn, ret.iface);
    xdr_free((xdrproc_t)xdr_remote_interface_define_xml_ret, (char *)&ret);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteInterfaceDestroy(virInterfacePtr iface, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = iface->conn->interfacePrivateData;
    remote_interface_destroy_args args;

    remoteDriverLock(priv);

    make_nonnull_interface(&args.iface, iface);
    args.flags = flags;

    if (call(iface->conn, priv, 0, REMOTE_PROC_INTERFACE_DESTROY,
             (xdrproc_t)xdr_remote_interface_destroy_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static char *
remoteInterfaceGetXMLDesc(virInterfacePtr iface, unsigned int flags)
{
    char *rv = NULL;
    struct private_data *priv = iface->conn->interfacePrivateData;
    remote_interface_get_xml_desc_args args;
    remote_interface_get_xml_desc_ret ret;

    remoteDriverLock(priv);

    make_nonnull_interface(&args.iface, iface);
    args.flags = flags;

    memset(&ret, 0, sizeof(ret));

    if (call(iface->conn, priv, 0, REMOTE_PROC_INTERFACE_GET_XML_DESC,
             (xdrproc_t)xdr_remote_interface_get_xml_desc_args, (char *)&args,
             (xdrproc_t)xdr_remote_interface_get_xml_desc_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = ret.xml;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteInterfaceIsActive(virInterfacePtr iface)
{
    int rv = -1;
    struct private_data *priv = iface->conn->interfacePrivateData;
    remote_interface_is_active_args args;
    remote_interface_is_active_ret ret;

    remoteDriverLock(priv);

    make_nonnull_interface(&args.iface, iface);

    memset(&ret, 0, sizeof(ret));

    if (call(iface->conn, priv, 0, REMOTE_PROC_INTERFACE_IS_ACTIVE,
             (xdrproc_t)xdr_remote_interface_is_active_args, (char *)&args,
             (xdrproc_t)xdr_remote_interface_is_active_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = ret.active;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static virInterfacePtr
remoteInterfaceLookupByMACString(virConnectPtr conn, const char *mac)
{
    virInterfacePtr rv = NULL;
    struct private_data *priv = conn->interfacePrivateData;
    remote_interface_lookup_by_mac_string_args args;
    remote_interface_lookup_by_mac_string_ret ret;

    remoteDriverLock(priv);

    args.mac = (char *)mac;

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_INTERFACE_LOOKUP_BY_MAC_STRING,
             (xdrproc_t)xdr_remote_interface_lookup_by_mac_string_args, (char *)&args,
             (xdrproc_t)xdr_remote_interface_lookup_by_mac_string_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = get_nonnull_interface(conn, ret.iface);
    xdr_free((xdrproc_t)xdr_remote_interface_lookup_by_mac_string_ret, (char *)&ret);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static virInterfacePtr
remoteInterfaceLookupByName(virConnectPtr conn, const char *name)
{
    virInterfacePtr rv = NULL;
    struct private_data *priv = conn->interfacePrivateData;
    remote_interface_lookup_by_name_args args;
    remote_interface_lookup_by_name_ret ret;

    remoteDriverLock(priv);

    args.name = (char *)name;

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_INTERFACE_LOOKUP_BY_NAME,
             (xdrproc_t)xdr_remote_interface_lookup_by_name_args, (char *)&args,
             (xdrproc_t)xdr_remote_interface_lookup_by_name_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = get_nonnull_interface(conn, ret.iface);
    xdr_free((xdrproc_t)xdr_remote_interface_lookup_by_name_ret, (char *)&ret);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteInterfaceUndefine(virInterfacePtr iface)
{
    int rv = -1;
    struct private_data *priv = iface->conn->interfacePrivateData;
    remote_interface_undefine_args args;

    remoteDriverLock(priv);

    make_nonnull_interface(&args.iface, iface);

    if (call(iface->conn, priv, 0, REMOTE_PROC_INTERFACE_UNDEFINE,
             (xdrproc_t)xdr_remote_interface_undefine_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteListDefinedDomains(virConnectPtr conn, char **const names, int maxnames)
{
    int rv = -1;
    struct private_data *priv = conn->privateData;
    remote_list_defined_domains_args args;
    remote_list_defined_domains_ret ret;
    int i;

    remoteDriverLock(priv);

    if (maxnames > REMOTE_DOMAIN_NAME_LIST_MAX) {
        remoteError(VIR_ERR_RPC,
                    _("too many remote undefineds: %d > %d"),
                    maxnames, REMOTE_DOMAIN_NAME_LIST_MAX);
        goto done;
    }

    args.maxnames = maxnames;

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_LIST_DEFINED_DOMAINS,
             (xdrproc_t)xdr_remote_list_defined_domains_args, (char *)&args,
             (xdrproc_t)xdr_remote_list_defined_domains_ret, (char *)&ret) == -1) {
        goto done;
    }

    if (ret.names.names_len > maxnames) {
        remoteError(VIR_ERR_RPC,
                    _("too many remote undefineds: %d > %d"),
                    ret.names.names_len, maxnames);
        goto cleanup;
    }

    /* This call is caller-frees (although that isn't clear from
     * the documentation).  However xdr_free will free up both the
     * names and the list of pointers, so we have to strdup the
     * names here. */
    for (i = 0; i < ret.names.names_len; ++i) {
        names[i] = strdup(ret.names.names_val[i]);

        if (names[i] == NULL) {
            for (--i; i >= 0; --i)
                VIR_FREE(names[i]);

            virReportOOMError();
            goto cleanup;
        }
    }

    rv = ret.names.names_len;

cleanup:
    xdr_free((xdrproc_t)xdr_remote_list_defined_domains_ret, (char *)&ret);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteListDefinedInterfaces(virConnectPtr conn, char **const names, int maxnames)
{
    int rv = -1;
    struct private_data *priv = conn->interfacePrivateData;
    remote_list_defined_interfaces_args args;
    remote_list_defined_interfaces_ret ret;
    int i;

    remoteDriverLock(priv);

    if (maxnames > REMOTE_DEFINED_INTERFACE_NAME_LIST_MAX) {
        remoteError(VIR_ERR_RPC,
                    _("too many remote undefineds: %d > %d"),
                    maxnames, REMOTE_DEFINED_INTERFACE_NAME_LIST_MAX);
        goto done;
    }

    args.maxnames = maxnames;

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_LIST_DEFINED_INTERFACES,
             (xdrproc_t)xdr_remote_list_defined_interfaces_args, (char *)&args,
             (xdrproc_t)xdr_remote_list_defined_interfaces_ret, (char *)&ret) == -1) {
        goto done;
    }

    if (ret.names.names_len > maxnames) {
        remoteError(VIR_ERR_RPC,
                    _("too many remote undefineds: %d > %d"),
                    ret.names.names_len, maxnames);
        goto cleanup;
    }

    /* This call is caller-frees (although that isn't clear from
     * the documentation).  However xdr_free will free up both the
     * names and the list of pointers, so we have to strdup the
     * names here. */
    for (i = 0; i < ret.names.names_len; ++i) {
        names[i] = strdup(ret.names.names_val[i]);

        if (names[i] == NULL) {
            for (--i; i >= 0; --i)
                VIR_FREE(names[i]);

            virReportOOMError();
            goto cleanup;
        }
    }

    rv = ret.names.names_len;

cleanup:
    xdr_free((xdrproc_t)xdr_remote_list_defined_interfaces_ret, (char *)&ret);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteListDefinedNetworks(virConnectPtr conn, char **const names, int maxnames)
{
    int rv = -1;
    struct private_data *priv = conn->networkPrivateData;
    remote_list_defined_networks_args args;
    remote_list_defined_networks_ret ret;
    int i;

    remoteDriverLock(priv);

    if (maxnames > REMOTE_NETWORK_NAME_LIST_MAX) {
        remoteError(VIR_ERR_RPC,
                    _("too many remote undefineds: %d > %d"),
                    maxnames, REMOTE_NETWORK_NAME_LIST_MAX);
        goto done;
    }

    args.maxnames = maxnames;

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_LIST_DEFINED_NETWORKS,
             (xdrproc_t)xdr_remote_list_defined_networks_args, (char *)&args,
             (xdrproc_t)xdr_remote_list_defined_networks_ret, (char *)&ret) == -1) {
        goto done;
    }

    if (ret.names.names_len > maxnames) {
        remoteError(VIR_ERR_RPC,
                    _("too many remote undefineds: %d > %d"),
                    ret.names.names_len, maxnames);
        goto cleanup;
    }

    /* This call is caller-frees (although that isn't clear from
     * the documentation).  However xdr_free will free up both the
     * names and the list of pointers, so we have to strdup the
     * names here. */
    for (i = 0; i < ret.names.names_len; ++i) {
        names[i] = strdup(ret.names.names_val[i]);

        if (names[i] == NULL) {
            for (--i; i >= 0; --i)
                VIR_FREE(names[i]);

            virReportOOMError();
            goto cleanup;
        }
    }

    rv = ret.names.names_len;

cleanup:
    xdr_free((xdrproc_t)xdr_remote_list_defined_networks_ret, (char *)&ret);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteListDefinedStoragePools(virConnectPtr conn, char **const names, int maxnames)
{
    int rv = -1;
    struct private_data *priv = conn->storagePrivateData;
    remote_list_defined_storage_pools_args args;
    remote_list_defined_storage_pools_ret ret;
    int i;

    remoteDriverLock(priv);

    if (maxnames > REMOTE_STORAGE_POOL_NAME_LIST_MAX) {
        remoteError(VIR_ERR_RPC,
                    _("too many remote undefineds: %d > %d"),
                    maxnames, REMOTE_STORAGE_POOL_NAME_LIST_MAX);
        goto done;
    }

    args.maxnames = maxnames;

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_LIST_DEFINED_STORAGE_POOLS,
             (xdrproc_t)xdr_remote_list_defined_storage_pools_args, (char *)&args,
             (xdrproc_t)xdr_remote_list_defined_storage_pools_ret, (char *)&ret) == -1) {
        goto done;
    }

    if (ret.names.names_len > maxnames) {
        remoteError(VIR_ERR_RPC,
                    _("too many remote undefineds: %d > %d"),
                    ret.names.names_len, maxnames);
        goto cleanup;
    }

    /* This call is caller-frees (although that isn't clear from
     * the documentation).  However xdr_free will free up both the
     * names and the list of pointers, so we have to strdup the
     * names here. */
    for (i = 0; i < ret.names.names_len; ++i) {
        names[i] = strdup(ret.names.names_val[i]);

        if (names[i] == NULL) {
            for (--i; i >= 0; --i)
                VIR_FREE(names[i]);

            virReportOOMError();
            goto cleanup;
        }
    }

    rv = ret.names.names_len;

cleanup:
    xdr_free((xdrproc_t)xdr_remote_list_defined_storage_pools_ret, (char *)&ret);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteListInterfaces(virConnectPtr conn, char **const names, int maxnames)
{
    int rv = -1;
    struct private_data *priv = conn->interfacePrivateData;
    remote_list_interfaces_args args;
    remote_list_interfaces_ret ret;
    int i;

    remoteDriverLock(priv);

    if (maxnames > REMOTE_INTERFACE_NAME_LIST_MAX) {
        remoteError(VIR_ERR_RPC,
                    _("too many remote undefineds: %d > %d"),
                    maxnames, REMOTE_INTERFACE_NAME_LIST_MAX);
        goto done;
    }

    args.maxnames = maxnames;

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_LIST_INTERFACES,
             (xdrproc_t)xdr_remote_list_interfaces_args, (char *)&args,
             (xdrproc_t)xdr_remote_list_interfaces_ret, (char *)&ret) == -1) {
        goto done;
    }

    if (ret.names.names_len > maxnames) {
        remoteError(VIR_ERR_RPC,
                    _("too many remote undefineds: %d > %d"),
                    ret.names.names_len, maxnames);
        goto cleanup;
    }

    /* This call is caller-frees (although that isn't clear from
     * the documentation).  However xdr_free will free up both the
     * names and the list of pointers, so we have to strdup the
     * names here. */
    for (i = 0; i < ret.names.names_len; ++i) {
        names[i] = strdup(ret.names.names_val[i]);

        if (names[i] == NULL) {
            for (--i; i >= 0; --i)
                VIR_FREE(names[i]);

            virReportOOMError();
            goto cleanup;
        }
    }

    rv = ret.names.names_len;

cleanup:
    xdr_free((xdrproc_t)xdr_remote_list_interfaces_ret, (char *)&ret);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteListNetworks(virConnectPtr conn, char **const names, int maxnames)
{
    int rv = -1;
    struct private_data *priv = conn->networkPrivateData;
    remote_list_networks_args args;
    remote_list_networks_ret ret;
    int i;

    remoteDriverLock(priv);

    if (maxnames > REMOTE_NETWORK_NAME_LIST_MAX) {
        remoteError(VIR_ERR_RPC,
                    _("too many remote undefineds: %d > %d"),
                    maxnames, REMOTE_NETWORK_NAME_LIST_MAX);
        goto done;
    }

    args.maxnames = maxnames;

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_LIST_NETWORKS,
             (xdrproc_t)xdr_remote_list_networks_args, (char *)&args,
             (xdrproc_t)xdr_remote_list_networks_ret, (char *)&ret) == -1) {
        goto done;
    }

    if (ret.names.names_len > maxnames) {
        remoteError(VIR_ERR_RPC,
                    _("too many remote undefineds: %d > %d"),
                    ret.names.names_len, maxnames);
        goto cleanup;
    }

    /* This call is caller-frees (although that isn't clear from
     * the documentation).  However xdr_free will free up both the
     * names and the list of pointers, so we have to strdup the
     * names here. */
    for (i = 0; i < ret.names.names_len; ++i) {
        names[i] = strdup(ret.names.names_val[i]);

        if (names[i] == NULL) {
            for (--i; i >= 0; --i)
                VIR_FREE(names[i]);

            virReportOOMError();
            goto cleanup;
        }
    }

    rv = ret.names.names_len;

cleanup:
    xdr_free((xdrproc_t)xdr_remote_list_networks_ret, (char *)&ret);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteListNWFilters(virConnectPtr conn, char **const names, int maxnames)
{
    int rv = -1;
    struct private_data *priv = conn->nwfilterPrivateData;
    remote_list_nwfilters_args args;
    remote_list_nwfilters_ret ret;
    int i;

    remoteDriverLock(priv);

    if (maxnames > REMOTE_NWFILTER_NAME_LIST_MAX) {
        remoteError(VIR_ERR_RPC,
                    _("too many remote undefineds: %d > %d"),
                    maxnames, REMOTE_NWFILTER_NAME_LIST_MAX);
        goto done;
    }

    args.maxnames = maxnames;

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_LIST_NWFILTERS,
             (xdrproc_t)xdr_remote_list_nwfilters_args, (char *)&args,
             (xdrproc_t)xdr_remote_list_nwfilters_ret, (char *)&ret) == -1) {
        goto done;
    }

    if (ret.names.names_len > maxnames) {
        remoteError(VIR_ERR_RPC,
                    _("too many remote undefineds: %d > %d"),
                    ret.names.names_len, maxnames);
        goto cleanup;
    }

    /* This call is caller-frees (although that isn't clear from
     * the documentation).  However xdr_free will free up both the
     * names and the list of pointers, so we have to strdup the
     * names here. */
    for (i = 0; i < ret.names.names_len; ++i) {
        names[i] = strdup(ret.names.names_val[i]);

        if (names[i] == NULL) {
            for (--i; i >= 0; --i)
                VIR_FREE(names[i]);

            virReportOOMError();
            goto cleanup;
        }
    }

    rv = ret.names.names_len;

cleanup:
    xdr_free((xdrproc_t)xdr_remote_list_nwfilters_ret, (char *)&ret);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteListSecrets(virConnectPtr conn, char **const uuids, int maxuuids)
{
    int rv = -1;
    struct private_data *priv = conn->secretPrivateData;
    remote_list_secrets_args args;
    remote_list_secrets_ret ret;
    int i;

    remoteDriverLock(priv);

    if (maxuuids > REMOTE_SECRET_UUID_LIST_MAX) {
        remoteError(VIR_ERR_RPC,
                    _("too many remote undefineds: %d > %d"),
                    maxuuids, REMOTE_SECRET_UUID_LIST_MAX);
        goto done;
    }

    args.maxuuids = maxuuids;

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_LIST_SECRETS,
             (xdrproc_t)xdr_remote_list_secrets_args, (char *)&args,
             (xdrproc_t)xdr_remote_list_secrets_ret, (char *)&ret) == -1) {
        goto done;
    }

    if (ret.uuids.uuids_len > maxuuids) {
        remoteError(VIR_ERR_RPC,
                    _("too many remote undefineds: %d > %d"),
                    ret.uuids.uuids_len, maxuuids);
        goto cleanup;
    }

    /* This call is caller-frees (although that isn't clear from
     * the documentation).  However xdr_free will free up both the
     * names and the list of pointers, so we have to strdup the
     * names here. */
    for (i = 0; i < ret.uuids.uuids_len; ++i) {
        uuids[i] = strdup(ret.uuids.uuids_val[i]);

        if (uuids[i] == NULL) {
            for (--i; i >= 0; --i)
                VIR_FREE(uuids[i]);

            virReportOOMError();
            goto cleanup;
        }
    }

    rv = ret.uuids.uuids_len;

cleanup:
    xdr_free((xdrproc_t)xdr_remote_list_secrets_ret, (char *)&ret);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteListStoragePools(virConnectPtr conn, char **const names, int maxnames)
{
    int rv = -1;
    struct private_data *priv = conn->storagePrivateData;
    remote_list_storage_pools_args args;
    remote_list_storage_pools_ret ret;
    int i;

    remoteDriverLock(priv);

    if (maxnames > REMOTE_STORAGE_POOL_NAME_LIST_MAX) {
        remoteError(VIR_ERR_RPC,
                    _("too many remote undefineds: %d > %d"),
                    maxnames, REMOTE_STORAGE_POOL_NAME_LIST_MAX);
        goto done;
    }

    args.maxnames = maxnames;

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_LIST_STORAGE_POOLS,
             (xdrproc_t)xdr_remote_list_storage_pools_args, (char *)&args,
             (xdrproc_t)xdr_remote_list_storage_pools_ret, (char *)&ret) == -1) {
        goto done;
    }

    if (ret.names.names_len > maxnames) {
        remoteError(VIR_ERR_RPC,
                    _("too many remote undefineds: %d > %d"),
                    ret.names.names_len, maxnames);
        goto cleanup;
    }

    /* This call is caller-frees (although that isn't clear from
     * the documentation).  However xdr_free will free up both the
     * names and the list of pointers, so we have to strdup the
     * names here. */
    for (i = 0; i < ret.names.names_len; ++i) {
        names[i] = strdup(ret.names.names_val[i]);

        if (names[i] == NULL) {
            for (--i; i >= 0; --i)
                VIR_FREE(names[i]);

            virReportOOMError();
            goto cleanup;
        }
    }

    rv = ret.names.names_len;

cleanup:
    xdr_free((xdrproc_t)xdr_remote_list_storage_pools_ret, (char *)&ret);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteNetworkCreate(virNetworkPtr net)
{
    int rv = -1;
    struct private_data *priv = net->conn->networkPrivateData;
    remote_network_create_args args;

    remoteDriverLock(priv);

    make_nonnull_network(&args.net, net);

    if (call(net->conn, priv, 0, REMOTE_PROC_NETWORK_CREATE,
             (xdrproc_t)xdr_remote_network_create_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static virNetworkPtr
remoteNetworkCreateXML(virConnectPtr conn, const char *xml)
{
    virNetworkPtr rv = NULL;
    struct private_data *priv = conn->networkPrivateData;
    remote_network_create_xml_args args;
    remote_network_create_xml_ret ret;

    remoteDriverLock(priv);

    args.xml = (char *)xml;

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_NETWORK_CREATE_XML,
             (xdrproc_t)xdr_remote_network_create_xml_args, (char *)&args,
             (xdrproc_t)xdr_remote_network_create_xml_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = get_nonnull_network(conn, ret.net);
    xdr_free((xdrproc_t)xdr_remote_network_create_xml_ret, (char *)&ret);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static virNetworkPtr
remoteNetworkDefineXML(virConnectPtr conn, const char *xml)
{
    virNetworkPtr rv = NULL;
    struct private_data *priv = conn->networkPrivateData;
    remote_network_define_xml_args args;
    remote_network_define_xml_ret ret;

    remoteDriverLock(priv);

    args.xml = (char *)xml;

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_NETWORK_DEFINE_XML,
             (xdrproc_t)xdr_remote_network_define_xml_args, (char *)&args,
             (xdrproc_t)xdr_remote_network_define_xml_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = get_nonnull_network(conn, ret.net);
    xdr_free((xdrproc_t)xdr_remote_network_define_xml_ret, (char *)&ret);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteNetworkDestroy(virNetworkPtr net)
{
    int rv = -1;
    struct private_data *priv = net->conn->networkPrivateData;
    remote_network_destroy_args args;

    remoteDriverLock(priv);

    make_nonnull_network(&args.net, net);

    if (call(net->conn, priv, 0, REMOTE_PROC_NETWORK_DESTROY,
             (xdrproc_t)xdr_remote_network_destroy_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteNetworkGetAutostart(virNetworkPtr net, int *autostart)
{
    int rv = -1;
    struct private_data *priv = net->conn->networkPrivateData;
    remote_network_get_autostart_args args;
    remote_network_get_autostart_ret ret;

    remoteDriverLock(priv);

    make_nonnull_network(&args.net, net);

    memset(&ret, 0, sizeof(ret));

    if (call(net->conn, priv, 0, REMOTE_PROC_NETWORK_GET_AUTOSTART,
             (xdrproc_t)xdr_remote_network_get_autostart_args, (char *)&args,
             (xdrproc_t)xdr_remote_network_get_autostart_ret, (char *)&ret) == -1) {
        goto done;
    }

    if (autostart) *autostart = ret.autostart;
    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static char *
remoteNetworkGetBridgeName(virNetworkPtr net)
{
    char *rv = NULL;
    struct private_data *priv = net->conn->networkPrivateData;
    remote_network_get_bridge_name_args args;
    remote_network_get_bridge_name_ret ret;

    remoteDriverLock(priv);

    make_nonnull_network(&args.net, net);

    memset(&ret, 0, sizeof(ret));

    if (call(net->conn, priv, 0, REMOTE_PROC_NETWORK_GET_BRIDGE_NAME,
             (xdrproc_t)xdr_remote_network_get_bridge_name_args, (char *)&args,
             (xdrproc_t)xdr_remote_network_get_bridge_name_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = ret.name;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static char *
remoteNetworkGetXMLDesc(virNetworkPtr net, unsigned int flags)
{
    char *rv = NULL;
    struct private_data *priv = net->conn->networkPrivateData;
    remote_network_get_xml_desc_args args;
    remote_network_get_xml_desc_ret ret;

    remoteDriverLock(priv);

    make_nonnull_network(&args.net, net);
    args.flags = flags;

    memset(&ret, 0, sizeof(ret));

    if (call(net->conn, priv, 0, REMOTE_PROC_NETWORK_GET_XML_DESC,
             (xdrproc_t)xdr_remote_network_get_xml_desc_args, (char *)&args,
             (xdrproc_t)xdr_remote_network_get_xml_desc_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = ret.xml;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteNetworkIsActive(virNetworkPtr net)
{
    int rv = -1;
    struct private_data *priv = net->conn->networkPrivateData;
    remote_network_is_active_args args;
    remote_network_is_active_ret ret;

    remoteDriverLock(priv);

    make_nonnull_network(&args.net, net);

    memset(&ret, 0, sizeof(ret));

    if (call(net->conn, priv, 0, REMOTE_PROC_NETWORK_IS_ACTIVE,
             (xdrproc_t)xdr_remote_network_is_active_args, (char *)&args,
             (xdrproc_t)xdr_remote_network_is_active_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = ret.active;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteNetworkIsPersistent(virNetworkPtr net)
{
    int rv = -1;
    struct private_data *priv = net->conn->networkPrivateData;
    remote_network_is_persistent_args args;
    remote_network_is_persistent_ret ret;

    remoteDriverLock(priv);

    make_nonnull_network(&args.net, net);

    memset(&ret, 0, sizeof(ret));

    if (call(net->conn, priv, 0, REMOTE_PROC_NETWORK_IS_PERSISTENT,
             (xdrproc_t)xdr_remote_network_is_persistent_args, (char *)&args,
             (xdrproc_t)xdr_remote_network_is_persistent_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = ret.persistent;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static virNetworkPtr
remoteNetworkLookupByName(virConnectPtr conn, const char *name)
{
    virNetworkPtr rv = NULL;
    struct private_data *priv = conn->networkPrivateData;
    remote_network_lookup_by_name_args args;
    remote_network_lookup_by_name_ret ret;

    remoteDriverLock(priv);

    args.name = (char *)name;

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_NETWORK_LOOKUP_BY_NAME,
             (xdrproc_t)xdr_remote_network_lookup_by_name_args, (char *)&args,
             (xdrproc_t)xdr_remote_network_lookup_by_name_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = get_nonnull_network(conn, ret.net);
    xdr_free((xdrproc_t)xdr_remote_network_lookup_by_name_ret, (char *)&ret);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static virNetworkPtr
remoteNetworkLookupByUUID(virConnectPtr conn, const unsigned char *uuid)
{
    virNetworkPtr rv = NULL;
    struct private_data *priv = conn->networkPrivateData;
    remote_network_lookup_by_uuid_args args;
    remote_network_lookup_by_uuid_ret ret;

    remoteDriverLock(priv);

    memcpy(args.uuid, uuid, VIR_UUID_BUFLEN);

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_NETWORK_LOOKUP_BY_UUID,
             (xdrproc_t)xdr_remote_network_lookup_by_uuid_args, (char *)&args,
             (xdrproc_t)xdr_remote_network_lookup_by_uuid_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = get_nonnull_network(conn, ret.net);
    xdr_free((xdrproc_t)xdr_remote_network_lookup_by_uuid_ret, (char *)&ret);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteNetworkSetAutostart(virNetworkPtr net, int autostart)
{
    int rv = -1;
    struct private_data *priv = net->conn->networkPrivateData;
    remote_network_set_autostart_args args;

    remoteDriverLock(priv);

    make_nonnull_network(&args.net, net);
    args.autostart = autostart;

    if (call(net->conn, priv, 0, REMOTE_PROC_NETWORK_SET_AUTOSTART,
             (xdrproc_t)xdr_remote_network_set_autostart_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteNetworkUndefine(virNetworkPtr net)
{
    int rv = -1;
    struct private_data *priv = net->conn->networkPrivateData;
    remote_network_undefine_args args;

    remoteDriverLock(priv);

    make_nonnull_network(&args.net, net);

    if (call(net->conn, priv, 0, REMOTE_PROC_NETWORK_UNDEFINE,
             (xdrproc_t)xdr_remote_network_undefine_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static virNodeDevicePtr
remoteNodeDeviceCreateXML(virConnectPtr conn, const char *xml_desc, unsigned int flags)
{
    virNodeDevicePtr rv = NULL;
    struct private_data *priv = conn->devMonPrivateData;
    remote_node_device_create_xml_args args;
    remote_node_device_create_xml_ret ret;

    remoteDriverLock(priv);

    args.xml_desc = (char *)xml_desc;
    args.flags = flags;

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_NODE_DEVICE_CREATE_XML,
             (xdrproc_t)xdr_remote_node_device_create_xml_args, (char *)&args,
             (xdrproc_t)xdr_remote_node_device_create_xml_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = get_nonnull_node_device(conn, ret.dev);
    xdr_free((xdrproc_t)xdr_remote_node_device_create_xml_ret, (char *)&ret);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteNodeDeviceDestroy(virNodeDevicePtr dev)
{
    int rv = -1;
    struct private_data *priv = dev->conn->devMonPrivateData;
    remote_node_device_destroy_args args;

    remoteDriverLock(priv);

    args.name = dev->name;

    if (call(dev->conn, priv, 0, REMOTE_PROC_NODE_DEVICE_DESTROY,
             (xdrproc_t)xdr_remote_node_device_destroy_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static char *
remoteNodeDeviceGetParent(virNodeDevicePtr dev)
{
    char *rv = NULL;
    struct private_data *priv = dev->conn->devMonPrivateData;
    remote_node_device_get_parent_args args;
    remote_node_device_get_parent_ret ret;

    remoteDriverLock(priv);

    args.name = dev->name;

    memset(&ret, 0, sizeof(ret));

    if (call(dev->conn, priv, 0, REMOTE_PROC_NODE_DEVICE_GET_PARENT,
             (xdrproc_t)xdr_remote_node_device_get_parent_args, (char *)&args,
             (xdrproc_t)xdr_remote_node_device_get_parent_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = ret.parent ? *ret.parent : NULL;
    VIR_FREE(ret.parent);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static char *
remoteNodeDeviceGetXMLDesc(virNodeDevicePtr dev, unsigned int flags)
{
    char *rv = NULL;
    struct private_data *priv = dev->conn->devMonPrivateData;
    remote_node_device_get_xml_desc_args args;
    remote_node_device_get_xml_desc_ret ret;

    remoteDriverLock(priv);

    args.name = dev->name;
    args.flags = flags;

    memset(&ret, 0, sizeof(ret));

    if (call(dev->conn, priv, 0, REMOTE_PROC_NODE_DEVICE_GET_XML_DESC,
             (xdrproc_t)xdr_remote_node_device_get_xml_desc_args, (char *)&args,
             (xdrproc_t)xdr_remote_node_device_get_xml_desc_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = ret.xml;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteNodeDeviceListCaps(virNodeDevicePtr dev, char **const names, int maxnames)
{
    int rv = -1;
    struct private_data *priv = dev->conn->devMonPrivateData;
    remote_node_device_list_caps_args args;
    remote_node_device_list_caps_ret ret;
    int i;

    remoteDriverLock(priv);

    if (maxnames > REMOTE_NODE_DEVICE_CAPS_LIST_MAX) {
        remoteError(VIR_ERR_RPC,
                    _("too many remote undefineds: %d > %d"),
                    maxnames, REMOTE_NODE_DEVICE_CAPS_LIST_MAX);
        goto done;
    }

    args.name = dev->name;
    args.maxnames = maxnames;

    memset(&ret, 0, sizeof(ret));

    if (call(dev->conn, priv, 0, REMOTE_PROC_NODE_DEVICE_LIST_CAPS,
             (xdrproc_t)xdr_remote_node_device_list_caps_args, (char *)&args,
             (xdrproc_t)xdr_remote_node_device_list_caps_ret, (char *)&ret) == -1) {
        goto done;
    }

    if (ret.names.names_len > maxnames) {
        remoteError(VIR_ERR_RPC,
                    _("too many remote undefineds: %d > %d"),
                    ret.names.names_len, maxnames);
        goto cleanup;
    }

    /* This call is caller-frees (although that isn't clear from
     * the documentation).  However xdr_free will free up both the
     * names and the list of pointers, so we have to strdup the
     * names here. */
    for (i = 0; i < ret.names.names_len; ++i) {
        names[i] = strdup(ret.names.names_val[i]);

        if (names[i] == NULL) {
            for (--i; i >= 0; --i)
                VIR_FREE(names[i]);

            virReportOOMError();
            goto cleanup;
        }
    }

    rv = ret.names.names_len;

cleanup:
    xdr_free((xdrproc_t)xdr_remote_node_device_list_caps_ret, (char *)&ret);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static virNodeDevicePtr
remoteNodeDeviceLookupByName(virConnectPtr conn, const char *name)
{
    virNodeDevicePtr rv = NULL;
    struct private_data *priv = conn->devMonPrivateData;
    remote_node_device_lookup_by_name_args args;
    remote_node_device_lookup_by_name_ret ret;

    remoteDriverLock(priv);

    args.name = (char *)name;

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_NODE_DEVICE_LOOKUP_BY_NAME,
             (xdrproc_t)xdr_remote_node_device_lookup_by_name_args, (char *)&args,
             (xdrproc_t)xdr_remote_node_device_lookup_by_name_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = get_nonnull_node_device(conn, ret.dev);
    xdr_free((xdrproc_t)xdr_remote_node_device_lookup_by_name_ret, (char *)&ret);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteNodeDeviceNumOfCaps(virNodeDevicePtr dev)
{
    int rv = -1;
    struct private_data *priv = dev->conn->devMonPrivateData;
    remote_node_device_num_of_caps_args args;
    remote_node_device_num_of_caps_ret ret;

    remoteDriverLock(priv);

    args.name = dev->name;

    memset(&ret, 0, sizeof(ret));

    if (call(dev->conn, priv, 0, REMOTE_PROC_NODE_DEVICE_NUM_OF_CAPS,
             (xdrproc_t)xdr_remote_node_device_num_of_caps_args, (char *)&args,
             (xdrproc_t)xdr_remote_node_device_num_of_caps_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = ret.num;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static unsigned long long
remoteNodeGetFreeMemory(virConnectPtr conn)
{
    unsigned long long rv = 0;
    struct private_data *priv = conn->privateData;
    remote_node_get_free_memory_ret ret;

    remoteDriverLock(priv);

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_NODE_GET_FREE_MEMORY,
             (xdrproc_t)xdr_void, (char *)NULL,
             (xdrproc_t)xdr_remote_node_get_free_memory_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = ret.freeMem;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteNodeGetInfo(virConnectPtr conn, virNodeInfoPtr result)
{
    int rv = -1;
    struct private_data *priv = conn->privateData;
    remote_node_get_info_ret ret;

    remoteDriverLock(priv);

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_NODE_GET_INFO,
             (xdrproc_t)xdr_void, (char *)NULL,
             (xdrproc_t)xdr_remote_node_get_info_ret, (char *)&ret) == -1) {
        goto done;
    }

    memcpy(result->model, ret.model, sizeof(result->model));
    HYPER_TO_ULONG(result->memory, ret.memory);
    result->cpus = ret.cpus;
    result->mhz = ret.mhz;
    result->nodes = ret.nodes;
    result->sockets = ret.sockets;
    result->cores = ret.cores;
    result->threads = ret.threads;
    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteNodeListDevices(virConnectPtr conn, const char *cap, char **const names, int maxnames, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = conn->devMonPrivateData;
    remote_node_list_devices_args args;
    remote_node_list_devices_ret ret;
    int i;

    remoteDriverLock(priv);

    if (maxnames > REMOTE_NODE_DEVICE_NAME_LIST_MAX) {
        remoteError(VIR_ERR_RPC,
                    _("too many remote undefineds: %d > %d"),
                    maxnames, REMOTE_NODE_DEVICE_NAME_LIST_MAX);
        goto done;
    }

    args.cap = cap ? (char **)&cap : NULL;
    args.maxnames = maxnames;
    args.flags = flags;

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_NODE_LIST_DEVICES,
             (xdrproc_t)xdr_remote_node_list_devices_args, (char *)&args,
             (xdrproc_t)xdr_remote_node_list_devices_ret, (char *)&ret) == -1) {
        goto done;
    }

    if (ret.names.names_len > maxnames) {
        remoteError(VIR_ERR_RPC,
                    _("too many remote undefineds: %d > %d"),
                    ret.names.names_len, maxnames);
        goto cleanup;
    }

    /* This call is caller-frees (although that isn't clear from
     * the documentation).  However xdr_free will free up both the
     * names and the list of pointers, so we have to strdup the
     * names here. */
    for (i = 0; i < ret.names.names_len; ++i) {
        names[i] = strdup(ret.names.names_val[i]);

        if (names[i] == NULL) {
            for (--i; i >= 0; --i)
                VIR_FREE(names[i]);

            virReportOOMError();
            goto cleanup;
        }
    }

    rv = ret.names.names_len;

cleanup:
    xdr_free((xdrproc_t)xdr_remote_node_list_devices_ret, (char *)&ret);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteNodeNumOfDevices(virConnectPtr conn, const char *cap, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = conn->devMonPrivateData;
    remote_node_num_of_devices_args args;
    remote_node_num_of_devices_ret ret;

    remoteDriverLock(priv);

    args.cap = cap ? (char **)&cap : NULL;
    args.flags = flags;

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_NODE_NUM_OF_DEVICES,
             (xdrproc_t)xdr_remote_node_num_of_devices_args, (char *)&args,
             (xdrproc_t)xdr_remote_node_num_of_devices_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = ret.num;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteNodeSuspendForDuration(virConnectPtr conn, unsigned int target, unsigned long long duration, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = conn->devMonPrivateData;
    remote_node_suspend_for_duration_args args;

    remoteDriverLock(priv);

    args.target = target;
    args.duration = duration;
    args.flags = flags;

    if (call(conn, priv, 0, REMOTE_PROC_NODE_SUSPEND_FOR_DURATION,
             (xdrproc_t)xdr_remote_node_suspend_for_duration_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteNumOfDefinedDomains(virConnectPtr conn)
{
    int rv = -1;
    struct private_data *priv = conn->privateData;
    remote_num_of_defined_domains_ret ret;

    remoteDriverLock(priv);

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_NUM_OF_DEFINED_DOMAINS,
             (xdrproc_t)xdr_void, (char *)NULL,
             (xdrproc_t)xdr_remote_num_of_defined_domains_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = ret.num;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteNumOfDefinedInterfaces(virConnectPtr conn)
{
    int rv = -1;
    struct private_data *priv = conn->interfacePrivateData;
    remote_num_of_defined_interfaces_ret ret;

    remoteDriverLock(priv);

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_NUM_OF_DEFINED_INTERFACES,
             (xdrproc_t)xdr_void, (char *)NULL,
             (xdrproc_t)xdr_remote_num_of_defined_interfaces_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = ret.num;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteNumOfDefinedNetworks(virConnectPtr conn)
{
    int rv = -1;
    struct private_data *priv = conn->networkPrivateData;
    remote_num_of_defined_networks_ret ret;

    remoteDriverLock(priv);

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_NUM_OF_DEFINED_NETWORKS,
             (xdrproc_t)xdr_void, (char *)NULL,
             (xdrproc_t)xdr_remote_num_of_defined_networks_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = ret.num;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteNumOfDefinedStoragePools(virConnectPtr conn)
{
    int rv = -1;
    struct private_data *priv = conn->storagePrivateData;
    remote_num_of_defined_storage_pools_ret ret;

    remoteDriverLock(priv);

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_NUM_OF_DEFINED_STORAGE_POOLS,
             (xdrproc_t)xdr_void, (char *)NULL,
             (xdrproc_t)xdr_remote_num_of_defined_storage_pools_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = ret.num;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteNumOfDomains(virConnectPtr conn)
{
    int rv = -1;
    struct private_data *priv = conn->privateData;
    remote_num_of_domains_ret ret;

    remoteDriverLock(priv);

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_NUM_OF_DOMAINS,
             (xdrproc_t)xdr_void, (char *)NULL,
             (xdrproc_t)xdr_remote_num_of_domains_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = ret.num;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteNumOfInterfaces(virConnectPtr conn)
{
    int rv = -1;
    struct private_data *priv = conn->interfacePrivateData;
    remote_num_of_interfaces_ret ret;

    remoteDriverLock(priv);

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_NUM_OF_INTERFACES,
             (xdrproc_t)xdr_void, (char *)NULL,
             (xdrproc_t)xdr_remote_num_of_interfaces_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = ret.num;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteNumOfNetworks(virConnectPtr conn)
{
    int rv = -1;
    struct private_data *priv = conn->networkPrivateData;
    remote_num_of_networks_ret ret;

    remoteDriverLock(priv);

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_NUM_OF_NETWORKS,
             (xdrproc_t)xdr_void, (char *)NULL,
             (xdrproc_t)xdr_remote_num_of_networks_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = ret.num;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteNumOfNWFilters(virConnectPtr conn)
{
    int rv = -1;
    struct private_data *priv = conn->nwfilterPrivateData;
    remote_num_of_nwfilters_ret ret;

    remoteDriverLock(priv);

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_NUM_OF_NWFILTERS,
             (xdrproc_t)xdr_void, (char *)NULL,
             (xdrproc_t)xdr_remote_num_of_nwfilters_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = ret.num;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteNumOfSecrets(virConnectPtr conn)
{
    int rv = -1;
    struct private_data *priv = conn->secretPrivateData;
    remote_num_of_secrets_ret ret;

    remoteDriverLock(priv);

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_NUM_OF_SECRETS,
             (xdrproc_t)xdr_void, (char *)NULL,
             (xdrproc_t)xdr_remote_num_of_secrets_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = ret.num;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteNumOfStoragePools(virConnectPtr conn)
{
    int rv = -1;
    struct private_data *priv = conn->storagePrivateData;
    remote_num_of_storage_pools_ret ret;

    remoteDriverLock(priv);

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_NUM_OF_STORAGE_POOLS,
             (xdrproc_t)xdr_void, (char *)NULL,
             (xdrproc_t)xdr_remote_num_of_storage_pools_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = ret.num;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static virNWFilterPtr
remoteNWFilterDefineXML(virConnectPtr conn, const char *xml)
{
    virNWFilterPtr rv = NULL;
    struct private_data *priv = conn->nwfilterPrivateData;
    remote_nwfilter_define_xml_args args;
    remote_nwfilter_define_xml_ret ret;

    remoteDriverLock(priv);

    args.xml = (char *)xml;

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_NWFILTER_DEFINE_XML,
             (xdrproc_t)xdr_remote_nwfilter_define_xml_args, (char *)&args,
             (xdrproc_t)xdr_remote_nwfilter_define_xml_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = get_nonnull_nwfilter(conn, ret.nwfilter);
    xdr_free((xdrproc_t)xdr_remote_nwfilter_define_xml_ret, (char *)&ret);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static char *
remoteNWFilterGetXMLDesc(virNWFilterPtr nwfilter, unsigned int flags)
{
    char *rv = NULL;
    struct private_data *priv = nwfilter->conn->nwfilterPrivateData;
    remote_nwfilter_get_xml_desc_args args;
    remote_nwfilter_get_xml_desc_ret ret;

    remoteDriverLock(priv);

    make_nonnull_nwfilter(&args.nwfilter, nwfilter);
    args.flags = flags;

    memset(&ret, 0, sizeof(ret));

    if (call(nwfilter->conn, priv, 0, REMOTE_PROC_NWFILTER_GET_XML_DESC,
             (xdrproc_t)xdr_remote_nwfilter_get_xml_desc_args, (char *)&args,
             (xdrproc_t)xdr_remote_nwfilter_get_xml_desc_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = ret.xml;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static virNWFilterPtr
remoteNWFilterLookupByName(virConnectPtr conn, const char *name)
{
    virNWFilterPtr rv = NULL;
    struct private_data *priv = conn->nwfilterPrivateData;
    remote_nwfilter_lookup_by_name_args args;
    remote_nwfilter_lookup_by_name_ret ret;

    remoteDriverLock(priv);

    args.name = (char *)name;

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_NWFILTER_LOOKUP_BY_NAME,
             (xdrproc_t)xdr_remote_nwfilter_lookup_by_name_args, (char *)&args,
             (xdrproc_t)xdr_remote_nwfilter_lookup_by_name_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = get_nonnull_nwfilter(conn, ret.nwfilter);
    xdr_free((xdrproc_t)xdr_remote_nwfilter_lookup_by_name_ret, (char *)&ret);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static virNWFilterPtr
remoteNWFilterLookupByUUID(virConnectPtr conn, const unsigned char *uuid)
{
    virNWFilterPtr rv = NULL;
    struct private_data *priv = conn->nwfilterPrivateData;
    remote_nwfilter_lookup_by_uuid_args args;
    remote_nwfilter_lookup_by_uuid_ret ret;

    remoteDriverLock(priv);

    memcpy(args.uuid, uuid, VIR_UUID_BUFLEN);

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_NWFILTER_LOOKUP_BY_UUID,
             (xdrproc_t)xdr_remote_nwfilter_lookup_by_uuid_args, (char *)&args,
             (xdrproc_t)xdr_remote_nwfilter_lookup_by_uuid_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = get_nonnull_nwfilter(conn, ret.nwfilter);
    xdr_free((xdrproc_t)xdr_remote_nwfilter_lookup_by_uuid_ret, (char *)&ret);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteNWFilterUndefine(virNWFilterPtr nwfilter)
{
    int rv = -1;
    struct private_data *priv = nwfilter->conn->nwfilterPrivateData;
    remote_nwfilter_undefine_args args;

    remoteDriverLock(priv);

    make_nonnull_nwfilter(&args.nwfilter, nwfilter);

    if (call(nwfilter->conn, priv, 0, REMOTE_PROC_NWFILTER_UNDEFINE,
             (xdrproc_t)xdr_remote_nwfilter_undefine_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static virSecretPtr
remoteSecretDefineXML(virConnectPtr conn, const char *xml, unsigned int flags)
{
    virSecretPtr rv = NULL;
    struct private_data *priv = conn->secretPrivateData;
    remote_secret_define_xml_args args;
    remote_secret_define_xml_ret ret;

    remoteDriverLock(priv);

    args.xml = (char *)xml;
    args.flags = flags;

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_SECRET_DEFINE_XML,
             (xdrproc_t)xdr_remote_secret_define_xml_args, (char *)&args,
             (xdrproc_t)xdr_remote_secret_define_xml_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = get_nonnull_secret(conn, ret.secret);
    xdr_free((xdrproc_t)xdr_remote_secret_define_xml_ret, (char *)&ret);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static char *
remoteSecretGetXMLDesc(virSecretPtr secret, unsigned int flags)
{
    char *rv = NULL;
    struct private_data *priv = secret->conn->secretPrivateData;
    remote_secret_get_xml_desc_args args;
    remote_secret_get_xml_desc_ret ret;

    remoteDriverLock(priv);

    make_nonnull_secret(&args.secret, secret);
    args.flags = flags;

    memset(&ret, 0, sizeof(ret));

    if (call(secret->conn, priv, 0, REMOTE_PROC_SECRET_GET_XML_DESC,
             (xdrproc_t)xdr_remote_secret_get_xml_desc_args, (char *)&args,
             (xdrproc_t)xdr_remote_secret_get_xml_desc_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = ret.xml;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static virSecretPtr
remoteSecretLookupByUsage(virConnectPtr conn, int usageType, const char *usageID)
{
    virSecretPtr rv = NULL;
    struct private_data *priv = conn->secretPrivateData;
    remote_secret_lookup_by_usage_args args;
    remote_secret_lookup_by_usage_ret ret;

    remoteDriverLock(priv);

    args.usageType = usageType;
    args.usageID = (char *)usageID;

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_SECRET_LOOKUP_BY_USAGE,
             (xdrproc_t)xdr_remote_secret_lookup_by_usage_args, (char *)&args,
             (xdrproc_t)xdr_remote_secret_lookup_by_usage_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = get_nonnull_secret(conn, ret.secret);
    xdr_free((xdrproc_t)xdr_remote_secret_lookup_by_usage_ret, (char *)&ret);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static virSecretPtr
remoteSecretLookupByUUID(virConnectPtr conn, const unsigned char *uuid)
{
    virSecretPtr rv = NULL;
    struct private_data *priv = conn->secretPrivateData;
    remote_secret_lookup_by_uuid_args args;
    remote_secret_lookup_by_uuid_ret ret;

    remoteDriverLock(priv);

    memcpy(args.uuid, uuid, VIR_UUID_BUFLEN);

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_SECRET_LOOKUP_BY_UUID,
             (xdrproc_t)xdr_remote_secret_lookup_by_uuid_args, (char *)&args,
             (xdrproc_t)xdr_remote_secret_lookup_by_uuid_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = get_nonnull_secret(conn, ret.secret);
    xdr_free((xdrproc_t)xdr_remote_secret_lookup_by_uuid_ret, (char *)&ret);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteSecretSetValue(virSecretPtr secret, const unsigned char *value, size_t valuelen, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = secret->conn->secretPrivateData;
    remote_secret_set_value_args args;

    remoteDriverLock(priv);

    if (valuelen > REMOTE_SECRET_VALUE_MAX) {
        remoteError(VIR_ERR_RPC,
                    _("%s length greater than maximum: %d > %d"),
                    "value", (int)valuelen, REMOTE_SECRET_VALUE_MAX);
        goto done;
    }

    make_nonnull_secret(&args.secret, secret);
    args.value.value_val = (char *)value;
    args.value.value_len = valuelen;
    args.flags = flags;

    if (call(secret->conn, priv, 0, REMOTE_PROC_SECRET_SET_VALUE,
             (xdrproc_t)xdr_remote_secret_set_value_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteSecretUndefine(virSecretPtr secret)
{
    int rv = -1;
    struct private_data *priv = secret->conn->secretPrivateData;
    remote_secret_undefine_args args;

    remoteDriverLock(priv);

    make_nonnull_secret(&args.secret, secret);

    if (call(secret->conn, priv, 0, REMOTE_PROC_SECRET_UNDEFINE,
             (xdrproc_t)xdr_remote_secret_undefine_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteStoragePoolBuild(virStoragePoolPtr pool, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = pool->conn->storagePrivateData;
    remote_storage_pool_build_args args;

    remoteDriverLock(priv);

    make_nonnull_storage_pool(&args.pool, pool);
    args.flags = flags;

    if (call(pool->conn, priv, 0, REMOTE_PROC_STORAGE_POOL_BUILD,
             (xdrproc_t)xdr_remote_storage_pool_build_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteStoragePoolCreate(virStoragePoolPtr pool, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = pool->conn->storagePrivateData;
    remote_storage_pool_create_args args;

    remoteDriverLock(priv);

    make_nonnull_storage_pool(&args.pool, pool);
    args.flags = flags;

    if (call(pool->conn, priv, 0, REMOTE_PROC_STORAGE_POOL_CREATE,
             (xdrproc_t)xdr_remote_storage_pool_create_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static virStoragePoolPtr
remoteStoragePoolCreateXML(virConnectPtr conn, const char *xml, unsigned int flags)
{
    virStoragePoolPtr rv = NULL;
    struct private_data *priv = conn->storagePrivateData;
    remote_storage_pool_create_xml_args args;
    remote_storage_pool_create_xml_ret ret;

    remoteDriverLock(priv);

    args.xml = (char *)xml;
    args.flags = flags;

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_STORAGE_POOL_CREATE_XML,
             (xdrproc_t)xdr_remote_storage_pool_create_xml_args, (char *)&args,
             (xdrproc_t)xdr_remote_storage_pool_create_xml_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = get_nonnull_storage_pool(conn, ret.pool);
    xdr_free((xdrproc_t)xdr_remote_storage_pool_create_xml_ret, (char *)&ret);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static virStoragePoolPtr
remoteStoragePoolDefineXML(virConnectPtr conn, const char *xml, unsigned int flags)
{
    virStoragePoolPtr rv = NULL;
    struct private_data *priv = conn->storagePrivateData;
    remote_storage_pool_define_xml_args args;
    remote_storage_pool_define_xml_ret ret;

    remoteDriverLock(priv);

    args.xml = (char *)xml;
    args.flags = flags;

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_STORAGE_POOL_DEFINE_XML,
             (xdrproc_t)xdr_remote_storage_pool_define_xml_args, (char *)&args,
             (xdrproc_t)xdr_remote_storage_pool_define_xml_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = get_nonnull_storage_pool(conn, ret.pool);
    xdr_free((xdrproc_t)xdr_remote_storage_pool_define_xml_ret, (char *)&ret);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteStoragePoolDelete(virStoragePoolPtr pool, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = pool->conn->storagePrivateData;
    remote_storage_pool_delete_args args;

    remoteDriverLock(priv);

    make_nonnull_storage_pool(&args.pool, pool);
    args.flags = flags;

    if (call(pool->conn, priv, 0, REMOTE_PROC_STORAGE_POOL_DELETE,
             (xdrproc_t)xdr_remote_storage_pool_delete_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteStoragePoolDestroy(virStoragePoolPtr pool)
{
    int rv = -1;
    struct private_data *priv = pool->conn->storagePrivateData;
    remote_storage_pool_destroy_args args;

    remoteDriverLock(priv);

    make_nonnull_storage_pool(&args.pool, pool);

    if (call(pool->conn, priv, 0, REMOTE_PROC_STORAGE_POOL_DESTROY,
             (xdrproc_t)xdr_remote_storage_pool_destroy_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteStoragePoolGetAutostart(virStoragePoolPtr pool, int *autostart)
{
    int rv = -1;
    struct private_data *priv = pool->conn->storagePrivateData;
    remote_storage_pool_get_autostart_args args;
    remote_storage_pool_get_autostart_ret ret;

    remoteDriverLock(priv);

    make_nonnull_storage_pool(&args.pool, pool);

    memset(&ret, 0, sizeof(ret));

    if (call(pool->conn, priv, 0, REMOTE_PROC_STORAGE_POOL_GET_AUTOSTART,
             (xdrproc_t)xdr_remote_storage_pool_get_autostart_args, (char *)&args,
             (xdrproc_t)xdr_remote_storage_pool_get_autostart_ret, (char *)&ret) == -1) {
        goto done;
    }

    if (autostart) *autostart = ret.autostart;
    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteStoragePoolGetInfo(virStoragePoolPtr pool, virStoragePoolInfoPtr result)
{
    int rv = -1;
    struct private_data *priv = pool->conn->storagePrivateData;
    remote_storage_pool_get_info_args args;
    remote_storage_pool_get_info_ret ret;

    remoteDriverLock(priv);

    make_nonnull_storage_pool(&args.pool, pool);

    memset(&ret, 0, sizeof(ret));

    if (call(pool->conn, priv, 0, REMOTE_PROC_STORAGE_POOL_GET_INFO,
             (xdrproc_t)xdr_remote_storage_pool_get_info_args, (char *)&args,
             (xdrproc_t)xdr_remote_storage_pool_get_info_ret, (char *)&ret) == -1) {
        goto done;
    }

    result->state = ret.state;
    result->capacity = ret.capacity;
    result->allocation = ret.allocation;
    result->available = ret.available;
    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static char *
remoteStoragePoolGetXMLDesc(virStoragePoolPtr pool, unsigned int flags)
{
    char *rv = NULL;
    struct private_data *priv = pool->conn->storagePrivateData;
    remote_storage_pool_get_xml_desc_args args;
    remote_storage_pool_get_xml_desc_ret ret;

    remoteDriverLock(priv);

    make_nonnull_storage_pool(&args.pool, pool);
    args.flags = flags;

    memset(&ret, 0, sizeof(ret));

    if (call(pool->conn, priv, 0, REMOTE_PROC_STORAGE_POOL_GET_XML_DESC,
             (xdrproc_t)xdr_remote_storage_pool_get_xml_desc_args, (char *)&args,
             (xdrproc_t)xdr_remote_storage_pool_get_xml_desc_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = ret.xml;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteStoragePoolIsActive(virStoragePoolPtr pool)
{
    int rv = -1;
    struct private_data *priv = pool->conn->storagePrivateData;
    remote_storage_pool_is_active_args args;
    remote_storage_pool_is_active_ret ret;

    remoteDriverLock(priv);

    make_nonnull_storage_pool(&args.pool, pool);

    memset(&ret, 0, sizeof(ret));

    if (call(pool->conn, priv, 0, REMOTE_PROC_STORAGE_POOL_IS_ACTIVE,
             (xdrproc_t)xdr_remote_storage_pool_is_active_args, (char *)&args,
             (xdrproc_t)xdr_remote_storage_pool_is_active_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = ret.active;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteStoragePoolIsPersistent(virStoragePoolPtr pool)
{
    int rv = -1;
    struct private_data *priv = pool->conn->storagePrivateData;
    remote_storage_pool_is_persistent_args args;
    remote_storage_pool_is_persistent_ret ret;

    remoteDriverLock(priv);

    make_nonnull_storage_pool(&args.pool, pool);

    memset(&ret, 0, sizeof(ret));

    if (call(pool->conn, priv, 0, REMOTE_PROC_STORAGE_POOL_IS_PERSISTENT,
             (xdrproc_t)xdr_remote_storage_pool_is_persistent_args, (char *)&args,
             (xdrproc_t)xdr_remote_storage_pool_is_persistent_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = ret.persistent;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteStoragePoolListVolumes(virStoragePoolPtr pool, char **const names, int maxnames)
{
    int rv = -1;
    struct private_data *priv = pool->conn->storagePrivateData;
    remote_storage_pool_list_volumes_args args;
    remote_storage_pool_list_volumes_ret ret;
    int i;

    remoteDriverLock(priv);

    if (maxnames > REMOTE_STORAGE_VOL_NAME_LIST_MAX) {
        remoteError(VIR_ERR_RPC,
                    _("too many remote undefineds: %d > %d"),
                    maxnames, REMOTE_STORAGE_VOL_NAME_LIST_MAX);
        goto done;
    }

    make_nonnull_storage_pool(&args.pool, pool);
    args.maxnames = maxnames;

    memset(&ret, 0, sizeof(ret));

    if (call(pool->conn, priv, 0, REMOTE_PROC_STORAGE_POOL_LIST_VOLUMES,
             (xdrproc_t)xdr_remote_storage_pool_list_volumes_args, (char *)&args,
             (xdrproc_t)xdr_remote_storage_pool_list_volumes_ret, (char *)&ret) == -1) {
        goto done;
    }

    if (ret.names.names_len > maxnames) {
        remoteError(VIR_ERR_RPC,
                    _("too many remote undefineds: %d > %d"),
                    ret.names.names_len, maxnames);
        goto cleanup;
    }

    /* This call is caller-frees (although that isn't clear from
     * the documentation).  However xdr_free will free up both the
     * names and the list of pointers, so we have to strdup the
     * names here. */
    for (i = 0; i < ret.names.names_len; ++i) {
        names[i] = strdup(ret.names.names_val[i]);

        if (names[i] == NULL) {
            for (--i; i >= 0; --i)
                VIR_FREE(names[i]);

            virReportOOMError();
            goto cleanup;
        }
    }

    rv = ret.names.names_len;

cleanup:
    xdr_free((xdrproc_t)xdr_remote_storage_pool_list_volumes_ret, (char *)&ret);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static virStoragePoolPtr
remoteStoragePoolLookupByName(virConnectPtr conn, const char *name)
{
    virStoragePoolPtr rv = NULL;
    struct private_data *priv = conn->storagePrivateData;
    remote_storage_pool_lookup_by_name_args args;
    remote_storage_pool_lookup_by_name_ret ret;

    remoteDriverLock(priv);

    args.name = (char *)name;

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_STORAGE_POOL_LOOKUP_BY_NAME,
             (xdrproc_t)xdr_remote_storage_pool_lookup_by_name_args, (char *)&args,
             (xdrproc_t)xdr_remote_storage_pool_lookup_by_name_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = get_nonnull_storage_pool(conn, ret.pool);
    xdr_free((xdrproc_t)xdr_remote_storage_pool_lookup_by_name_ret, (char *)&ret);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static virStoragePoolPtr
remoteStoragePoolLookupByUUID(virConnectPtr conn, const unsigned char *uuid)
{
    virStoragePoolPtr rv = NULL;
    struct private_data *priv = conn->storagePrivateData;
    remote_storage_pool_lookup_by_uuid_args args;
    remote_storage_pool_lookup_by_uuid_ret ret;

    remoteDriverLock(priv);

    memcpy(args.uuid, uuid, VIR_UUID_BUFLEN);

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_STORAGE_POOL_LOOKUP_BY_UUID,
             (xdrproc_t)xdr_remote_storage_pool_lookup_by_uuid_args, (char *)&args,
             (xdrproc_t)xdr_remote_storage_pool_lookup_by_uuid_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = get_nonnull_storage_pool(conn, ret.pool);
    xdr_free((xdrproc_t)xdr_remote_storage_pool_lookup_by_uuid_ret, (char *)&ret);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static virStoragePoolPtr
remoteStoragePoolLookupByVolume(virStorageVolPtr vol)
{
    virStoragePoolPtr rv = NULL;
    struct private_data *priv = vol->conn->storagePrivateData;
    remote_storage_pool_lookup_by_volume_args args;
    remote_storage_pool_lookup_by_volume_ret ret;

    remoteDriverLock(priv);

    make_nonnull_storage_vol(&args.vol, vol);

    memset(&ret, 0, sizeof(ret));

    if (call(vol->conn, priv, 0, REMOTE_PROC_STORAGE_POOL_LOOKUP_BY_VOLUME,
             (xdrproc_t)xdr_remote_storage_pool_lookup_by_volume_args, (char *)&args,
             (xdrproc_t)xdr_remote_storage_pool_lookup_by_volume_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = get_nonnull_storage_pool(vol->conn, ret.pool);
    xdr_free((xdrproc_t)xdr_remote_storage_pool_lookup_by_volume_ret, (char *)&ret);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteStoragePoolNumOfVolumes(virStoragePoolPtr pool)
{
    int rv = -1;
    struct private_data *priv = pool->conn->storagePrivateData;
    remote_storage_pool_num_of_volumes_args args;
    remote_storage_pool_num_of_volumes_ret ret;

    remoteDriverLock(priv);

    make_nonnull_storage_pool(&args.pool, pool);

    memset(&ret, 0, sizeof(ret));

    if (call(pool->conn, priv, 0, REMOTE_PROC_STORAGE_POOL_NUM_OF_VOLUMES,
             (xdrproc_t)xdr_remote_storage_pool_num_of_volumes_args, (char *)&args,
             (xdrproc_t)xdr_remote_storage_pool_num_of_volumes_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = ret.num;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteStoragePoolRefresh(virStoragePoolPtr pool, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = pool->conn->storagePrivateData;
    remote_storage_pool_refresh_args args;

    remoteDriverLock(priv);

    make_nonnull_storage_pool(&args.pool, pool);
    args.flags = flags;

    if (call(pool->conn, priv, 0, REMOTE_PROC_STORAGE_POOL_REFRESH,
             (xdrproc_t)xdr_remote_storage_pool_refresh_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteStoragePoolSetAutostart(virStoragePoolPtr pool, int autostart)
{
    int rv = -1;
    struct private_data *priv = pool->conn->storagePrivateData;
    remote_storage_pool_set_autostart_args args;

    remoteDriverLock(priv);

    make_nonnull_storage_pool(&args.pool, pool);
    args.autostart = autostart;

    if (call(pool->conn, priv, 0, REMOTE_PROC_STORAGE_POOL_SET_AUTOSTART,
             (xdrproc_t)xdr_remote_storage_pool_set_autostart_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteStoragePoolUndefine(virStoragePoolPtr pool)
{
    int rv = -1;
    struct private_data *priv = pool->conn->storagePrivateData;
    remote_storage_pool_undefine_args args;

    remoteDriverLock(priv);

    make_nonnull_storage_pool(&args.pool, pool);

    if (call(pool->conn, priv, 0, REMOTE_PROC_STORAGE_POOL_UNDEFINE,
             (xdrproc_t)xdr_remote_storage_pool_undefine_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static virStorageVolPtr
remoteStorageVolCreateXML(virStoragePoolPtr pool, const char *xml, unsigned int flags)
{
    virStorageVolPtr rv = NULL;
    struct private_data *priv = pool->conn->storagePrivateData;
    remote_storage_vol_create_xml_args args;
    remote_storage_vol_create_xml_ret ret;

    remoteDriverLock(priv);

    make_nonnull_storage_pool(&args.pool, pool);
    args.xml = (char *)xml;
    args.flags = flags;

    memset(&ret, 0, sizeof(ret));

    if (call(pool->conn, priv, 0, REMOTE_PROC_STORAGE_VOL_CREATE_XML,
             (xdrproc_t)xdr_remote_storage_vol_create_xml_args, (char *)&args,
             (xdrproc_t)xdr_remote_storage_vol_create_xml_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = get_nonnull_storage_vol(pool->conn, ret.vol);
    xdr_free((xdrproc_t)xdr_remote_storage_vol_create_xml_ret, (char *)&ret);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static virStorageVolPtr
remoteStorageVolCreateXMLFrom(virStoragePoolPtr pool, const char *xml, virStorageVolPtr clonevol, unsigned int flags)
{
    virStorageVolPtr rv = NULL;
    struct private_data *priv = pool->conn->storagePrivateData;
    remote_storage_vol_create_xml_from_args args;
    remote_storage_vol_create_xml_from_ret ret;

    remoteDriverLock(priv);

    make_nonnull_storage_pool(&args.pool, pool);
    args.xml = (char *)xml;
    make_nonnull_storage_vol(&args.clonevol, clonevol);
    args.flags = flags;

    memset(&ret, 0, sizeof(ret));

    if (call(pool->conn, priv, 0, REMOTE_PROC_STORAGE_VOL_CREATE_XML_FROM,
             (xdrproc_t)xdr_remote_storage_vol_create_xml_from_args, (char *)&args,
             (xdrproc_t)xdr_remote_storage_vol_create_xml_from_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = get_nonnull_storage_vol(pool->conn, ret.vol);
    xdr_free((xdrproc_t)xdr_remote_storage_vol_create_xml_from_ret, (char *)&ret);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteStorageVolDelete(virStorageVolPtr vol, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = vol->conn->storagePrivateData;
    remote_storage_vol_delete_args args;

    remoteDriverLock(priv);

    make_nonnull_storage_vol(&args.vol, vol);
    args.flags = flags;

    if (call(vol->conn, priv, 0, REMOTE_PROC_STORAGE_VOL_DELETE,
             (xdrproc_t)xdr_remote_storage_vol_delete_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteStorageVolDownload(virStorageVolPtr vol, virStreamPtr st, unsigned long long offset, unsigned long long length, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = vol->conn->storagePrivateData;
    remote_storage_vol_download_args args;
    virNetClientStreamPtr netst = NULL;

    remoteDriverLock(priv);

    if (!(netst = virNetClientStreamNew(priv->remoteProgram, REMOTE_PROC_STORAGE_VOL_DOWNLOAD, priv->counter)))
        goto done;

    if (virNetClientAddStream(priv->client, netst) < 0) {
        virNetClientStreamFree(netst);
        goto done;
    }
    st->driver = &remoteStreamDrv;
    st->privateData = netst;

    make_nonnull_storage_vol(&args.vol, vol);
    args.offset = offset;
    args.length = length;
    args.flags = flags;

    if (call(vol->conn, priv, 0, REMOTE_PROC_STORAGE_VOL_DOWNLOAD,
             (xdrproc_t)xdr_remote_storage_vol_download_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        virNetClientRemoveStream(priv->client, netst);
        virNetClientStreamFree(netst);
        st->driver = NULL;
        st->privateData = NULL;
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteStorageVolGetInfo(virStorageVolPtr vol, virStorageVolInfoPtr result)
{
    int rv = -1;
    struct private_data *priv = vol->conn->storagePrivateData;
    remote_storage_vol_get_info_args args;
    remote_storage_vol_get_info_ret ret;

    remoteDriverLock(priv);

    make_nonnull_storage_vol(&args.vol, vol);

    memset(&ret, 0, sizeof(ret));

    if (call(vol->conn, priv, 0, REMOTE_PROC_STORAGE_VOL_GET_INFO,
             (xdrproc_t)xdr_remote_storage_vol_get_info_args, (char *)&args,
             (xdrproc_t)xdr_remote_storage_vol_get_info_ret, (char *)&ret) == -1) {
        goto done;
    }

    result->type = ret.type;
    result->capacity = ret.capacity;
    result->allocation = ret.allocation;
    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static char *
remoteStorageVolGetPath(virStorageVolPtr vol)
{
    char *rv = NULL;
    struct private_data *priv = vol->conn->storagePrivateData;
    remote_storage_vol_get_path_args args;
    remote_storage_vol_get_path_ret ret;

    remoteDriverLock(priv);

    make_nonnull_storage_vol(&args.vol, vol);

    memset(&ret, 0, sizeof(ret));

    if (call(vol->conn, priv, 0, REMOTE_PROC_STORAGE_VOL_GET_PATH,
             (xdrproc_t)xdr_remote_storage_vol_get_path_args, (char *)&args,
             (xdrproc_t)xdr_remote_storage_vol_get_path_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = ret.name;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static char *
remoteStorageVolGetXMLDesc(virStorageVolPtr vol, unsigned int flags)
{
    char *rv = NULL;
    struct private_data *priv = vol->conn->storagePrivateData;
    remote_storage_vol_get_xml_desc_args args;
    remote_storage_vol_get_xml_desc_ret ret;

    remoteDriverLock(priv);

    make_nonnull_storage_vol(&args.vol, vol);
    args.flags = flags;

    memset(&ret, 0, sizeof(ret));

    if (call(vol->conn, priv, 0, REMOTE_PROC_STORAGE_VOL_GET_XML_DESC,
             (xdrproc_t)xdr_remote_storage_vol_get_xml_desc_args, (char *)&args,
             (xdrproc_t)xdr_remote_storage_vol_get_xml_desc_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = ret.xml;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static virStorageVolPtr
remoteStorageVolLookupByKey(virConnectPtr conn, const char *key)
{
    virStorageVolPtr rv = NULL;
    struct private_data *priv = conn->storagePrivateData;
    remote_storage_vol_lookup_by_key_args args;
    remote_storage_vol_lookup_by_key_ret ret;

    remoteDriverLock(priv);

    args.key = (char *)key;

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_STORAGE_VOL_LOOKUP_BY_KEY,
             (xdrproc_t)xdr_remote_storage_vol_lookup_by_key_args, (char *)&args,
             (xdrproc_t)xdr_remote_storage_vol_lookup_by_key_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = get_nonnull_storage_vol(conn, ret.vol);
    xdr_free((xdrproc_t)xdr_remote_storage_vol_lookup_by_key_ret, (char *)&ret);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static virStorageVolPtr
remoteStorageVolLookupByName(virStoragePoolPtr pool, const char *name)
{
    virStorageVolPtr rv = NULL;
    struct private_data *priv = pool->conn->storagePrivateData;
    remote_storage_vol_lookup_by_name_args args;
    remote_storage_vol_lookup_by_name_ret ret;

    remoteDriverLock(priv);

    make_nonnull_storage_pool(&args.pool, pool);
    args.name = (char *)name;

    memset(&ret, 0, sizeof(ret));

    if (call(pool->conn, priv, 0, REMOTE_PROC_STORAGE_VOL_LOOKUP_BY_NAME,
             (xdrproc_t)xdr_remote_storage_vol_lookup_by_name_args, (char *)&args,
             (xdrproc_t)xdr_remote_storage_vol_lookup_by_name_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = get_nonnull_storage_vol(pool->conn, ret.vol);
    xdr_free((xdrproc_t)xdr_remote_storage_vol_lookup_by_name_ret, (char *)&ret);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static virStorageVolPtr
remoteStorageVolLookupByPath(virConnectPtr conn, const char *path)
{
    virStorageVolPtr rv = NULL;
    struct private_data *priv = conn->storagePrivateData;
    remote_storage_vol_lookup_by_path_args args;
    remote_storage_vol_lookup_by_path_ret ret;

    remoteDriverLock(priv);

    args.path = (char *)path;

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_STORAGE_VOL_LOOKUP_BY_PATH,
             (xdrproc_t)xdr_remote_storage_vol_lookup_by_path_args, (char *)&args,
             (xdrproc_t)xdr_remote_storage_vol_lookup_by_path_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = get_nonnull_storage_vol(conn, ret.vol);
    xdr_free((xdrproc_t)xdr_remote_storage_vol_lookup_by_path_ret, (char *)&ret);

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteStorageVolResize(virStorageVolPtr vol, unsigned long long capacity, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = vol->conn->storagePrivateData;
    remote_storage_vol_resize_args args;

    remoteDriverLock(priv);

    make_nonnull_storage_vol(&args.vol, vol);
    args.capacity = capacity;
    args.flags = flags;

    if (call(vol->conn, priv, 0, REMOTE_PROC_STORAGE_VOL_RESIZE,
             (xdrproc_t)xdr_remote_storage_vol_resize_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteStorageVolUpload(virStorageVolPtr vol, virStreamPtr st, unsigned long long offset, unsigned long long length, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = vol->conn->storagePrivateData;
    remote_storage_vol_upload_args args;
    virNetClientStreamPtr netst = NULL;

    remoteDriverLock(priv);

    if (!(netst = virNetClientStreamNew(priv->remoteProgram, REMOTE_PROC_STORAGE_VOL_UPLOAD, priv->counter)))
        goto done;

    if (virNetClientAddStream(priv->client, netst) < 0) {
        virNetClientStreamFree(netst);
        goto done;
    }
    st->driver = &remoteStreamDrv;
    st->privateData = netst;

    make_nonnull_storage_vol(&args.vol, vol);
    args.offset = offset;
    args.length = length;
    args.flags = flags;

    if (call(vol->conn, priv, 0, REMOTE_PROC_STORAGE_VOL_UPLOAD,
             (xdrproc_t)xdr_remote_storage_vol_upload_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        virNetClientRemoveStream(priv->client, netst);
        virNetClientStreamFree(netst);
        st->driver = NULL;
        st->privateData = NULL;
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteStorageVolWipe(virStorageVolPtr vol, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = vol->conn->storagePrivateData;
    remote_storage_vol_wipe_args args;

    remoteDriverLock(priv);

    make_nonnull_storage_vol(&args.vol, vol);
    args.flags = flags;

    if (call(vol->conn, priv, 0, REMOTE_PROC_STORAGE_VOL_WIPE,
             (xdrproc_t)xdr_remote_storage_vol_wipe_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteStorageVolWipePattern(virStorageVolPtr vol, unsigned int algorithm, unsigned int flags)
{
    int rv = -1;
    struct private_data *priv = vol->conn->storagePrivateData;
    remote_storage_vol_wipe_pattern_args args;

    remoteDriverLock(priv);

    make_nonnull_storage_vol(&args.vol, vol);
    args.algorithm = algorithm;
    args.flags = flags;

    if (call(vol->conn, priv, 0, REMOTE_PROC_STORAGE_VOL_WIPE_PATTERN,
             (xdrproc_t)xdr_remote_storage_vol_wipe_pattern_args, (char *)&args,
             (xdrproc_t)xdr_void, (char *)NULL) == -1) {
        goto done;
    }

    rv = 0;

done:
    remoteDriverUnlock(priv);
    return rv;
}

static int
remoteSupportsFeature(virConnectPtr conn, int feature)
{
    int rv = -1;
    struct private_data *priv = conn->privateData;
    remote_supports_feature_args args;
    remote_supports_feature_ret ret;

    remoteDriverLock(priv);

    if (feature == VIR_DRV_FEATURE_REMOTE) {
        rv = 1;
        goto done;
    }

    args.feature = feature;

    memset(&ret, 0, sizeof(ret));

    if (call(conn, priv, 0, REMOTE_PROC_SUPPORTS_FEATURE,
             (xdrproc_t)xdr_remote_supports_feature_args, (char *)&args,
             (xdrproc_t)xdr_remote_supports_feature_ret, (char *)&ret) == -1) {
        goto done;
    }

    rv = ret.supported;

done:
    remoteDriverUnlock(priv);
    return rv;
}
