Add helper APIs to track if libvirtd or loadable modules have changed

The future QEMU capabilities cache needs to be able to invalidate
itself if the libvirtd binary or any loadable modules are changed
on disk. Record the 'ctime' value for these binaries and provide
helper APIs to query it. This approach assumes that if libvirt.so
is changed, then libvirtd will also change, which should usually
be the case with libtool's wrapper scripts that cause libvirtd to
get re-linked

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
This commit is contained in:
Daniel P. Berrange 2014-03-05 17:20:50 +00:00
parent f5796b61cc
commit 10ec072545
5 changed files with 33 additions and 0 deletions

View File

@ -1152,6 +1152,8 @@ int main(int argc, char **argv) {
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
virUpdateSelfLastChanged(argv[0]);
if (strstr(argv[0], "lt-libvirtd") || if (strstr(argv[0], "lt-libvirtd") ||
strstr(argv[0], "/daemon/.libs/libvirtd")) { strstr(argv[0], "/daemon/.libs/libvirtd")) {
char *tmp = strrchr(argv[0], '/'); char *tmp = strrchr(argv[0], '/');

View File

@ -74,6 +74,8 @@ virDriverLoadModule(const char *name)
goto cleanup; goto cleanup;
} }
virUpdateSelfLastChanged(modfile);
handle = dlopen(modfile, RTLD_NOW | RTLD_GLOBAL); handle = dlopen(modfile, RTLD_NOW | RTLD_GLOBAL);
if (!handle) { if (!handle) {
VIR_ERROR(_("failed to load module %s %s"), modfile, dlerror()); VIR_ERROR(_("failed to load module %s %s"), modfile, dlerror());

View File

@ -1954,6 +1954,7 @@ virGetGroupID;
virGetGroupList; virGetGroupList;
virGetGroupName; virGetGroupName;
virGetHostname; virGetHostname;
virGetSelfLastChanged;
virGetUnprivSGIOSysfsPath; virGetUnprivSGIOSysfsPath;
virGetUserCacheDirectory; virGetUserCacheDirectory;
virGetUserConfigDirectory; virGetUserConfigDirectory;
@ -1983,6 +1984,7 @@ virSetNonBlock;
virSetUIDGID; virSetUIDGID;
virSetUIDGIDWithCaps; virSetUIDGIDWithCaps;
virStrIsPrint; virStrIsPrint;
virUpdateSelfLastChanged;
virValidateWWN; virValidateWWN;

View File

@ -2173,3 +2173,26 @@ bool virIsSUID(void)
{ {
return getuid() != geteuid(); return getuid() != geteuid();
} }
static time_t selfLastChanged;
time_t virGetSelfLastChanged(void)
{
return selfLastChanged;
}
void virUpdateSelfLastChanged(const char *path)
{
struct stat sb;
if (stat(path, &sb) < 0)
return;
if (sb.st_ctime > selfLastChanged) {
VIR_DEBUG("Setting self last changed to %lld for '%s'",
(long long)sb.st_ctime, path);
selfLastChanged = sb.st_ctime;
}
}

View File

@ -194,4 +194,8 @@ const char *virGetEnvBlockSUID(const char *name);
const char *virGetEnvAllowSUID(const char *name); const char *virGetEnvAllowSUID(const char *name);
bool virIsSUID(void); bool virIsSUID(void);
time_t virGetSelfLastChanged(void);
void virUpdateSelfLastChanged(const char *path);
#endif /* __VIR_UTIL_H__ */ #endif /* __VIR_UTIL_H__ */