Starting from libvirt-1.2.4, network state XML files moved to another
directory (see commit b9e95491) and libvirt automatically migrates the
network state files to a new location. However, the code used
dirent.dt_type which is not supported by all filesystems. Thus, when
libvirt is upgraded on a host which uses such filesystem, network state
XMLs were not properly moved and running networks disappeared from
libvirt.
This patch falls back to stat() whenever dirent.dt_type is DT_UNKNOWN to
fix this issue.
https://bugzilla.redhat.com/show_bug.cgi?id=1167145
Signed-off-by: Jiri Denemark <jdenemar(a)redhat.com>
---
src/network/bridge_driver.c | 23 +++++++++++++++++++++--
1 file changed, 21 insertions(+), 2 deletions(-)
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 6cb421c..7066dfe 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -499,15 +499,34 @@ networkMigrateStateFiles(void)
}
while ((direrr = virDirRead(dir, &entry, oldStateDir)) > 0) {
+ if (entry->d_type != DT_UNKNOWN &&
+ entry->d_type != DT_REG)
+ continue;
- if (entry->d_type != DT_REG ||
- STREQ(entry->d_name, ".") ||
+ if (STREQ(entry->d_name, ".") ||
STREQ(entry->d_name, ".."))
continue;
if (virAsprintf(&oldPath, "%s/%s",
oldStateDir, entry->d_name) < 0)
goto cleanup;
+
+ if (entry->d_type == DT_UNKNOWN) {
+ struct stat st;
+
+ if (stat(oldPath, &st) < 0) {
+ virReportSystemError(errno,
+ _("failed to stat network status file
'%s'"),
+ oldPath);
+ goto cleanup;
+ }
+
+ if (!S_ISREG(st.st_mode)) {
+ VIR_FREE(oldPath);
+ continue;
+ }
+ }
+
if (virFileReadAll(oldPath, 1024*1024, &contents) < 0)
goto cleanup;
--
2.1.3