virNodeDevCapSCSITargetParseXML(xmlXPathContextPtr ctxt,
                                virNodeDeviceDefPtr def,
                                xmlNodePtr node,
                                virNodeDevCapSCSITargetPtr scsi_target)
{
    VIR_XPATH_NODE_AUTORESTORE(ctxt)
    xmlNodePtr *nodes = NULL;
    int ret = -1, n = 0;
    size_t i;
    char *type = NULL;

    ctxt->node = node;

    scsi_target->name = virXPathString("string(./target[1])", ctxt);
    if (!scsi_target->name) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("no target name supplied for '%s'"),
                       def->name);
        goto out;
    }

    if ((n = virXPathNodeSet("./capability", ctxt, &nodes)) < 0)
        goto out;

    for (i = 0; i < n; ++i) {
        type = virXMLPropString(nodes[i], "type");

        if (!type) {
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("missing type for SCSI target capability for '%s'"),
                           def->name);
            goto out;
        }

        if (STREQ(type, "fc_remote_port")) {
            scsi_target->flags |= VIR_NODE_DEV_CAP_FLAG_FC_RPORT;

            ctxt->node = nodes[i];

            if (virNodeDevCapsDefParseString("string(./rport[1])",
                                             ctxt,
                                             &scsi_target->rport) < 0) {
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("missing rport name for '%s'"), def->name);
                goto out;
            }

            if (virNodeDevCapsDefParseString("string(./wwpn[1])",
                                             ctxt, &scsi_target->wwpn) < 0) {
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("missing wwpn identifier for '%s'"),
                               def->name);
                goto out;
            }
        } else {
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("unknown SCSI target capability type '%s' for '%s'"),
                           type, def->name);
            goto out;
        }

        VIR_FREE(type);
    }

    ret = 0;

 out:
    VIR_FREE(type);
    VIR_FREE(nodes);
    return ret;
}
virNodeDevCapSCSITargetParseXML(xmlXPathContextPtr ctxt,
                                virNodeDeviceDefPtr def,
                                xmlNodePtr node,
                                virNodeDevCapSCSITargetPtr scsi_target)
{
    VIR_XPATH_NODE_AUTORESTORE(ctxt)
    xmlNodePtr *nodes = NULL;
    int ret = -1, n = 0;
    size_t i;
    char *type = NULL;

    ctxt->node = node;

    scsi_target->name = virXPathString("string(./target[1])", ctxt);
    if (!scsi_target->name) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("no target name supplied for '%s'"),
                       def->name);
        goto out;
    }

    if ((n = virXPathNodeSet("./capability", ctxt, &nodes)) < 0)
        goto out;

    for (i = 0; i < n; ++i) {
        type = virXMLPropString(nodes[i], "type");

        if (!type) {
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("missing type for SCSI target capability for '%s'"),
                           def->name);
            goto out;
        }

        if (STREQ(type, "fc_remote_port")) {
            scsi_target->flags |= VIR_NODE_DEV_CAP_FLAG_FC_RPORT;

            ctxt->node = nodes[i];

            if (virNodeDevCapsDefParseString("string(./rport[1])",
                                             ctxt,
                                             &scsi_target->rport) < 0) {
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("missing rport name for '%s'"), def->name);
                goto out;
            }

            if (virNodeDevCapsDefParseString("string(./wwpn[1])",
                                             ctxt, &scsi_target->wwpn) < 0) {
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("missing wwpn identifier for '%s'"),
                               def->name);
                goto out;
            }
        } else {
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("unknown SCSI target capability type '%s' for '%s'"),
                           type, def->name);
            goto out;
        }

        VIR_FREE(type);
    }

    ret = 0;

 out:
    VIR_FREE(type);
    VIR_FREE(nodes);
    return ret;
}