util: new virFileRelLinkPointsTo function

When checking if two filenames point to the same inode (whether
by hardlink or symlink), sometimes one of the names might be
relative.  This convenience function makes it easier to check.

* src/util/virfile.h (virFileRelLinkPointsTo): New prototype.
* src/util/virfile.c (virFileRelLinkPointsTo): New function.
* src/libvirt_private.syms (virfile.h): Export it.
* src/xen/xm_internal.c (xenXMDomainGetAutostart): Use it.

Signed-off-by: Eric Blake <eblake@redhat.com>
This commit is contained in:
Eric Blake 2014-04-10 17:36:06 -06:00
parent 367cd69d0d
commit 91f349d8fd
4 changed files with 43 additions and 8 deletions

View File

@ -1255,6 +1255,7 @@ virFilePrintf;
virFileReadAll;
virFileReadHeaderFD;
virFileReadLimFD;
virFileRelLinkPointsTo;
virFileResolveAllLinks;
virFileResolveLink;
virFileRewrite;

View File

@ -1368,7 +1368,8 @@ virFileHasSuffix(const char *str,
&& (Stat_buf_1).st_dev == (Stat_buf_2).st_dev)
/* Return nonzero if checkLink and checkDest
refer to the same file. Otherwise, return 0. */
* refer to the same file. Otherwise, return 0.
*/
int
virFileLinkPointsTo(const char *checkLink,
const char *checkDest)
@ -1382,6 +1383,35 @@ virFileLinkPointsTo(const char *checkLink,
}
/* Return positive if checkLink (residing within directory if not
* absolute) and checkDest refer to the same file. Otherwise, return
* -1 on allocation failure (error reported), or 0 if not the same
* (silent).
*/
int
virFileRelLinkPointsTo(const char *directory,
const char *checkLink,
const char *checkDest)
{
char *candidate;
int ret;
if (*checkLink == '/')
return virFileLinkPointsTo(checkLink, checkDest);
if (!directory) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("cannot resolve '%s' without starting directory"),
checkLink);
return -1;
}
if (virAsprintf(&candidate, "%s/%s", directory, checkLink) < 0)
return -1;
ret = virFileLinkPointsTo(candidate, checkDest);
VIR_FREE(candidate);
return ret;
}
static int
virFileResolveLinkHelper(const char *linkpath,
bool intermediatePaths,

View File

@ -143,7 +143,12 @@ int virFileStripSuffix(char *str,
const char *suffix) ATTRIBUTE_RETURN_CHECK;
int virFileLinkPointsTo(const char *checkLink,
const char *checkDest);
const char *checkDest)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
int virFileRelLinkPointsTo(const char *directory,
const char *checkLink,
const char *checkDest)
ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
int virFileResolveLink(const char *linkpath,
char **resultpath) ATTRIBUTE_RETURN_CHECK;

View File

@ -1427,25 +1427,24 @@ int
xenXMDomainGetAutostart(virDomainDefPtr def,
int *autostart)
{
char *linkname = xenXMAutostartLinkName(def);
char *config = xenXMDomainConfigName(def);
int ret = -1;
if (!linkname || !config)
if (!config)
goto cleanup;
*autostart = virFileLinkPointsTo(linkname, config);
*autostart = virFileRelLinkPointsTo("/etc/xen/auto/", def->name, config);
if (*autostart < 0) {
virReportSystemError(errno,
_("cannot check link %s points to config %s"),
linkname, config);
_("cannot check link /etc/xen/auto/%s points "
"to config %s"),
def->name, config);
goto cleanup;
}
ret = 0;
cleanup:
VIR_FREE(linkname);
VIR_FREE(config);
return ret;
}