On Mon 29 Jul 2013 02:51:15 PM CEST, Guannan Ren wrote:
> *src/util/virstoragefile.c: Add a helper function to get
> the first name of missing backing files, if the name is NULL,
> it means the diskchain is not broken.
> *src/qemu/qemu_domain.c: qemuDiskChainCheckBroken(disk) to
> check if its chain is broken
> ---
>  src/libvirt_private.syms  |  1 +
>  src/qemu/qemu_domain.c    | 22 ++++++++++++++++++++++
>  src/qemu/qemu_domain.h    |  3 +++
>  src/util/virstoragefile.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
>  src/util/virstoragefile.h |  2 ++
>  5 files changed, 74 insertions(+)
>
> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> index d9615ea..f7166d6 100644
> --- a/src/libvirt_private.syms
> +++ b/src/libvirt_private.syms
> @@ -1882,6 +1882,7 @@ virSocketAddrSetPort;
>
>
>  # util/virstoragefile.h
> +virStorageFileChainGetBroken;
>  virStorageFileChainLookup;
>  virStorageFileFeatureTypeFromString;
>  virStorageFileFeatureTypeToString;
> diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
> index 03a2aa6..be77991 100644
> --- a/src/qemu/qemu_domain.c
> +++ b/src/qemu/qemu_domain.c
> @@ -2187,6 +2187,28 @@ qemuDomainCleanupRun(virQEMUDriverPtr driver,
>  }
>
>  int
> +qemuDiskChainCheckBroken(virDomainDiskDefPtr disk)
> +{
> +    char *brokenFile = NULL;
> +
> +    if (!disk->src || !disk->backingChain)
> +        return 0;
> +
> +    if (virStorageFileChainGetBroken(disk->backingChain, &brokenFile) < 0)
> +        return -1;
> +
> +    if (brokenFile) {
> +        virReportError(VIR_ERR_INVALID_ARG,
> +                       _("Backing file '%s' of image '%s' is missing."),
> +                       brokenFile, disk->src);
> +        VIR_FREE(brokenFile);
> +        return -1;
> +    }
> +
> +    return 0;
> +}
> +
> +int
>  qemuDomainDetermineDiskChain(virQEMUDriverPtr driver,
>                               virDomainDiskDefPtr disk,
>                               bool force)
> diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
> index 9a959d6..0a4a51e 100644
> --- a/src/qemu/qemu_domain.h
> +++ b/src/qemu/qemu_domain.h
> @@ -347,6 +347,9 @@ bool qemuDomainJobAllowed(qemuDomainObjPrivatePtr priv,
>  int qemuDomainCheckDiskPresence(virQEMUDriverPtr driver,
>                                  virDomainObjPtr vm,
>                                  bool start_with_state);
> +
> +int qemuDiskChainCheckBroken(virDomainDiskDefPtr disk);
> +
>  int qemuDomainDetermineDiskChain(virQEMUDriverPtr driver,
>                                   virDomainDiskDefPtr disk,
>                                   bool force);
> diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
> index cb6df91..0b9cec3 100644
> --- a/src/util/virstoragefile.c
> +++ b/src/util/virstoragefile.c
> @@ -572,6 +572,13 @@ virFindBackingFile(const char *start, bool start_is_dir, 
> const char *path,
>          goto cleanup;
>      }
>
> +    if (virFileAccessibleAs(combined, F_OK, getuid(), getgid()) < 0) {
> +        virReportSystemError(errno,
> +                             _("Cannot access backing file '%s'"),
> +                             combined);
> +        goto cleanup;
> +    }
> +
>      if (!(*canonical = canonicalize_file_name(combined))) {
>          virReportSystemError(errno,
>                               _("Can't canonicalize path '%s'"), path);
> @@ -1097,6 +1104,45 @@ virStorageFileGetMetadata(const char *path, int format,
>  }
>
>  /**
> + * virStorageFileChainCheckBroken
> + *
> + * If CHAIN is broken, set *brokenFile to the broken file name,
> + * otherwise set it to NULL. Caller MUST free *brokenFile after use.
> + * Return 0 on success, negative on error.
> + */
> +int
> +virStorageFileChainGetBroken(virStorageFileMetadataPtr chain,
> +                             char **brokenFile)
> +{
> +    virStorageFileMetadataPtr tmp;
> +    int ret = -1;
> +
> +    if (!chain)
> +        return 0;
> +
> +    *brokenFile = NULL;
> +
> +    tmp = chain;
> +    while (tmp) {
> +        /* Break if no backing store or backing store is not file */
> +       if (!tmp->backingStoreRaw)
> +           break;
> +       if (!tmp->backingStore) {
> +           if (VIR_STRDUP(*brokenFile, tmp->backingStoreRaw) < 0)
> +               goto error;
> +           break;
> +       }
> +       tmp = tmp->backingMeta;
> +    }
> +
> +    ret = 0;
> +
> +error:
> +    return ret;
> +}
> +
> +
> +/**
>   * virStorageFileFreeMetadata:
>   *
>   * Free pointers in passed structure and structure itself.
> diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h
> index 4cb47e6..1f89839 100644
> --- a/src/util/virstoragefile.h
> +++ b/src/util/virstoragefile.h
> @@ -90,6 +90,8 @@ virStorageFileMetadataPtr virStorageFileGetMetadata(const 
> char *path,
>  virStorageFileMetadataPtr virStorageFileGetMetadataFromFD(const char *path,
>                                                            int fd,
>                                                            int format);
> +int virStorageFileChainGetBroken(virStorageFileMetadataPtr chain,
> +                                 char **broken_file);
>
>  const char *virStorageFileChainLookup(virStorageFileMetadataPtr chain,
>                                        const char *start,

ACK,

Martin

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to