Reviewed-by: Chen Hanxiao <chenhanxiao@xxxxxxxxxxxxxx> > -----Original Message----- > From: libvir-list-bounces@xxxxxxxxxx [mailto:libvir-list-bounces@xxxxxxxxxx] > On Behalf Of Daniel P. Berrange > Sent: Monday, October 07, 2013 9:07 PM > To: libvir-list@xxxxxxxxxx > Subject: [PATCH 1/6] Add virFileIsMountPoint function > > From: "Daniel P. Berrange" <berrange@xxxxxxxxxx> > > Add a function for efficiently checking if a path is a filesystem > mount point. > > NB will not work for bind mounts, only true filesystem mounts. > > Signed-off-by: Daniel P. Berrange <berrange@xxxxxxxxxx> > --- > src/libvirt_private.syms | 1 + > src/util/virfile.c | 58 > ++++++++++++++++++++++++++++++++++++++++++++++++ > src/util/virfile.h | 2 ++ > 3 files changed, 61 insertions(+) > > diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms > index fe40834..31fa604 100644 > --- a/src/libvirt_private.syms > +++ b/src/libvirt_private.syms > @@ -1182,6 +1182,7 @@ virFileIsAbsPath; > virFileIsDir; > virFileIsExecutable; > virFileIsLink; > +virFileIsMountPoint; > virFileLinkPointsTo; > virFileLock; > virFileLoopDeviceAssociate; > diff --git a/src/util/virfile.c b/src/util/virfile.c > index e10de5a..fa21aeb 100644 > --- a/src/util/virfile.c > +++ b/src/util/virfile.c > @@ -1513,6 +1513,64 @@ virFileIsExecutable(const char *file) > return false; > } > > + > +/* > + * Check that a file refers to a mount point. Trick is that for > + * a mount point, the st_dev field will differ from the parent > + * directory. > + * > + * Note that this will not detect bind mounts of dirs/files, > + * only true filesystem mounts. > + */ > +int virFileIsMountPoint(const char *file) > +{ > + char *parent = NULL; > + char *tmp; > + int ret = -1; > + struct stat sb1, sb2; > + > + if (VIR_STRDUP_QUIET(parent, file) < 0) > + goto cleanup; > + > + if (!(tmp = strrchr(parent, '/'))) { > + virReportError(VIR_ERR_INTERNAL_ERROR, > + _("Could not find '/' in '%s'"), > + file); > + goto cleanup; > + } > + > + *tmp = '\0'; > + > + VIR_DEBUG("Comparing '%s' to '%s'", file, parent); > + > + if (stat(file, &sb1) < 0) { > + if (errno == ENOENT) > + ret = 0; > + else > + virReportSystemError(errno, > + _("Cannot stat '%s'"), > + file); > + goto cleanup; > + } > + > + if (stat(parent, &sb2) < 0) { > + virReportSystemError(errno, > + _("Cannot stat '%s'"), > + parent); > + goto cleanup; > + } > + > + if (!S_ISDIR(sb1.st_mode)) > + return false; > + > + ret = sb1.st_dev != sb2.st_dev; > + VIR_DEBUG("Is mount %d", ret); > + > + cleanup: > + VIR_FREE(parent); > + return ret; > +} > + > #ifndef WIN32 > /* Check that a file is accessible under certain > * user & gid. > diff --git a/src/util/virfile.h b/src/util/virfile.h > index 72d35ce..ff84719 100644 > --- a/src/util/virfile.h > +++ b/src/util/virfile.h > @@ -156,6 +156,8 @@ bool virFileIsDir (const char *file) > ATTRIBUTE_NONNULL(1); > bool virFileExists(const char *file) ATTRIBUTE_NONNULL(1); > bool virFileIsExecutable(const char *file) ATTRIBUTE_NONNULL(1); > > +int virFileIsMountPoint(const char *file) ATTRIBUTE_NONNULL(1); > + > char *virFileSanitizePath(const char *path); > > enum { > -- > 1.8.3.1 > > -- > libvir-list mailing list > libvir-list@xxxxxxxxxx > https://www.redhat.com/mailman/listinfo/libvir-list -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list