virStorageFileBackendPtr virStorageFileBackendForTypeInternal(int type, int protocol, bool report) { size_t i; for (i = 0; i < virStorageFileBackendsCount; i++) { if (virStorageFileBackends[i]->type == type) { if (type == VIR_STORAGE_TYPE_NETWORK && virStorageFileBackends[i]->protocol != protocol) continue; return virStorageFileBackends[i]; } } if (!report) return NULL; if (type == VIR_STORAGE_TYPE_NETWORK) { virReportError(VIR_ERR_INTERNAL_ERROR, _("missing storage backend for network files " "using %s protocol"), virStorageNetProtocolTypeToString(protocol)); } else { virReportError(VIR_ERR_INTERNAL_ERROR, _("missing storage backend for '%s' storage"), virStorageTypeToString(type)); } return NULL; }
int virStorageFileBackendRegister(virStorageFileBackendPtr backend) { VIR_DEBUG("Registering storage file backend '%s' protocol '%s'", virStorageTypeToString(backend->type), virStorageNetProtocolTypeToString(backend->protocol)); if (virStorageFileBackendsCount >= VIR_STORAGE_BACKENDS_MAX) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Too many drivers, cannot register storage file " "backend '%s'"), virStorageTypeToString(backend->type)); return -1; } virStorageFileBackends[virStorageFileBackendsCount] = backend; virStorageFileBackendsCount++; return 0; }
int virStorageFileBackendForType(int type, int protocol, bool required, virStorageFileBackendPtr *backend) { size_t i; *backend = NULL; if (virStorageFileBackendInitialize() < 0) return -1; for (i = 0; i < virStorageFileBackendsCount; i++) { if (virStorageFileBackends[i]->type == type) { if (type == VIR_STORAGE_TYPE_NETWORK && virStorageFileBackends[i]->protocol != protocol) continue; *backend = virStorageFileBackends[i]; return 0; } } if (!required) return 0; if (type == VIR_STORAGE_TYPE_NETWORK) { virReportError(VIR_ERR_INTERNAL_ERROR, _("missing storage backend for network files " "using %s protocol"), virStorageNetProtocolTypeToString(protocol)); } else { virReportError(VIR_ERR_INTERNAL_ERROR, _("missing storage backend for '%s' storage"), virStorageTypeToString(type)); } return -1; }
static char * xenFormatXLDiskSrcNet(virStorageSourcePtr src) { char *ret = NULL; virBuffer buf = VIR_BUFFER_INITIALIZER; size_t i; switch ((virStorageNetProtocol) src->protocol) { case VIR_STORAGE_NET_PROTOCOL_NBD: case VIR_STORAGE_NET_PROTOCOL_HTTP: case VIR_STORAGE_NET_PROTOCOL_HTTPS: case VIR_STORAGE_NET_PROTOCOL_FTP: case VIR_STORAGE_NET_PROTOCOL_FTPS: case VIR_STORAGE_NET_PROTOCOL_TFTP: case VIR_STORAGE_NET_PROTOCOL_ISCSI: case VIR_STORAGE_NET_PROTOCOL_GLUSTER: case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG: case VIR_STORAGE_NET_PROTOCOL_LAST: case VIR_STORAGE_NET_PROTOCOL_NONE: virReportError(VIR_ERR_NO_SUPPORT, _("Unsupported network block protocol '%s'"), virStorageNetProtocolTypeToString(src->protocol)); goto cleanup; case VIR_STORAGE_NET_PROTOCOL_RBD: if (strchr(src->path, ':')) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("':' not allowed in RBD source volume name '%s'"), src->path); goto cleanup; } virBufferStrcat(&buf, "rbd:", src->path, NULL); virBufferAddLit(&buf, ":auth_supported=none"); if (src->nhosts > 0) { virBufferAddLit(&buf, ":mon_host="); for (i = 0; i < src->nhosts; i++) { if (i) virBufferAddLit(&buf, "\\\\;"); /* assume host containing : is ipv6 */ if (strchr(src->hosts[i].name, ':')) virBufferEscape(&buf, '\\', ":", "[%s]", src->hosts[i].name); else virBufferAsprintf(&buf, "%s", src->hosts[i].name); if (src->hosts[i].port) virBufferAsprintf(&buf, "\\\\:%s", src->hosts[i].port); } } if (virBufferCheckError(&buf) < 0) goto cleanup; ret = virBufferContentAndReset(&buf); break; } cleanup: virBufferFreeAndReset(&buf); return ret; }
static int testStorageChain(const void *args) { const struct testChainData *data = args; int ret = -1; virStorageSourcePtr meta; virStorageSourcePtr elt; size_t i = 0; char *broken = NULL; meta = testStorageFileGetMetadata(data->start, data->format, -1, -1, (data->flags & ALLOW_PROBE) != 0); if (!meta) { if (data->flags & EXP_FAIL) { virResetLastError(); ret = 0; } goto cleanup; } else if (data->flags & EXP_FAIL) { fprintf(stderr, "call should have failed\n"); goto cleanup; } if (data->flags & EXP_WARN) { if (!virGetLastError()) { fprintf(stderr, "call should have warned\n"); goto cleanup; } virResetLastError(); if (virStorageFileChainGetBroken(meta, &broken) || !broken) { fprintf(stderr, "call should identify broken part of chain\n"); goto cleanup; } } else { if (virGetLastError()) { fprintf(stderr, "call should not have warned\n"); goto cleanup; } if (virStorageFileChainGetBroken(meta, &broken) || broken) { fprintf(stderr, "chain should not be identified as broken\n"); goto cleanup; } } elt = meta; while (elt) { char *expect = NULL; char *actual = NULL; if (i == data->nfiles) { fprintf(stderr, "probed chain was too long\n"); goto cleanup; } if (virAsprintf(&expect, testStorageChainFormat, i, NULLSTR(data->files[i]->path), NULLSTR(data->files[i]->expBackingStoreRaw), data->files[i]->expCapacity, data->files[i]->expEncrypted, NULLSTR(data->files[i]->pathRel), data->files[i]->type, data->files[i]->format, virStorageNetProtocolTypeToString(data->files[i]->protocol), NULLSTR(data->files[i]->hostname), NULLSTR(data->files[i]->secret)) < 0 || virAsprintf(&actual, testStorageChainFormat, i, NULLSTR(elt->path), NULLSTR(elt->backingStoreRaw), elt->capacity, !!elt->encryption, NULLSTR(elt->relPath), elt->type, elt->format, virStorageNetProtocolTypeToString(elt->protocol), NULLSTR(elt->nhosts ? elt->hosts[0].name : NULL), NULLSTR(elt->auth ? elt->auth->username : NULL)) < 0) { VIR_FREE(expect); VIR_FREE(actual); goto cleanup; } if (STRNEQ(expect, actual)) { virtTestDifference(stderr, expect, actual); VIR_FREE(expect); VIR_FREE(actual); goto cleanup; } VIR_FREE(expect); VIR_FREE(actual); elt = elt->backingStore; i++; } if (i != data->nfiles) { fprintf(stderr, "probed chain was too short\n"); goto cleanup; } ret = 0; cleanup: VIR_FREE(broken); virStorageSourceFree(meta); return ret; }