]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
Avoid freezing mount points for same device.
authorOliver Kurth <okurth@vmware.com>
Fri, 2 Aug 2019 18:07:21 +0000 (11:07 -0700)
committerOliver Kurth <okurth@vmware.com>
Fri, 2 Aug 2019 18:07:21 +0000 (11:07 -0700)
Loopback device setup could cause a cyclic dependency
between 2 mount points. In order to break the cycle,
avoid freezing the mount points to the same device.

This change also skips some system mount points for 'tmpfs'
and 'cgroup' etc as those share the same device/FS name.
This is fine because we can't quiese those mount points
anyway (system mount points don't support quiescing).

open-vm-tools/lib/syncDriver/syncDriverPosix.c

index 839cb6dd986ae4b8d5e683c1a16582c484842f86..7b6132baedfa654d610888b43da5c15da6da1e29 100644 (file)
@@ -1,5 +1,5 @@
 /*********************************************************
- * Copyright (C) 2005-2018 VMware, Inc. All rights reserved.
+ * Copyright (C) 2005-2019 VMware, Inc. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published
@@ -140,6 +140,7 @@ static GSList *
 SyncDriverLocalMounts(void)
 {
    GSList *paths = NULL;
+   GHashTable *devices;
    MNTHANDLE mounts;
    DECLARE_MNTINFO(mntinfo);
 
@@ -148,19 +149,39 @@ SyncDriverLocalMounts(void)
       return NULL;
    }
 
+   devices = g_hash_table_new_full(g_str_hash, g_str_equal, free, free);
+
    while (GETNEXT_MNTINFO(mounts, mntinfo)) {
-      char *path;
+      const char *device;
+      const char *path;
+      const char *prevDevicePath;
+
+      device = MNTINFO_NAME(mntinfo);
+      path = MNTINFO_MNTPT(mntinfo);
+
       /*
        * Skip remote mounts because they are not freezable and opening them
        * could lead to hangs. See PR 1196785.
        */
       if (SyncDriverIsRemoteFS(mntinfo)) {
          Debug(LGPFX "Skipping remote file system, name=%s, mntpt=%s.\n",
-               MNTINFO_NAME(mntinfo), MNTINFO_MNTPT(mntinfo));
+               device, path);
+         continue;
+      }
+
+      /*
+       * Avoid adding a path to the list, if we have already got
+       * a path mounting the same device path.
+       */
+      prevDevicePath = g_hash_table_lookup(devices, device);
+      if (prevDevicePath != NULL) {
+         Debug(LGPFX "Skipping duplicate file system, name=%s, mntpt=%s "
+               "(existing path=%s).\n", device, path, prevDevicePath);
          continue;
       }
 
-      path = Util_SafeStrdup(MNTINFO_MNTPT(mntinfo));
+      g_hash_table_insert(devices, Util_SafeStrdup(device),
+                          Util_SafeStrdup(path));
 
       /*
        * A mount point could depend on existence of a previous mount
@@ -172,9 +193,10 @@ SyncDriverLocalMounts(void)
        * dependency. So, we need to keep them in reverse order of
        * mount points to achieve the dependency order.
        */
-      paths = g_slist_prepend(paths, path);
+      paths = g_slist_prepend(paths, Util_SafeStrdup(path));
    }
 
+   g_hash_table_destroy(devices);
    (void) CLOSE_MNTFILE(mounts);
    return paths;
 }