From 2dbc685719001fbd44cde48a0eab5d07763b8179 Mon Sep 17 00:00:00 2001 From: Michael Hanselmann <hansmi@google.com> Date: Thu, 8 Dec 2011 11:23:38 +0100 Subject: [PATCH] =?UTF-8?q?utils.ListVisibleFiles:=20Hide=20=E2=80=9Clost+?= =?UTF-8?q?found=E2=80=9D=20directories?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If a βlost+foundβ directory is found at a filesystem's root path it is ignored. In all other cases directory entries named βlost+foundβ are treated normally. Unittests are included. Fixes issue 153. Signed-off-by: Michael Hanselmann <hansmi@google.com> Reviewed-by: Iustin Pop <iustin@google.com> --- lib/utils/io.py | 24 +++++++++++++++++++++--- test/ganeti.utils.io_unittest.py | 21 +++++++++++++++++++++ 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/lib/utils/io.py b/lib/utils/io.py index cec8a7dca..80dc1f0d3 100644 --- a/lib/utils/io.py +++ b/lib/utils/io.py @@ -38,6 +38,10 @@ from ganeti.utils import filelock #: Path generating random UUID _RANDOM_UUID_FILE = "/proc/sys/kernel/random/uuid" +#: Directory used by fsck(8) to store recovered data, usually at a file +#: system's root directory +_LOST_AND_FOUND = "lost+found" + def ReadFile(file_name, size=-1, preread=None): """Reads a file. @@ -467,7 +471,7 @@ def CreateBackup(file_name): return backup_name -def ListVisibleFiles(path): +def ListVisibleFiles(path, _is_mountpoint=os.path.ismount): """Returns a list of visible files in a directory. @type path: str @@ -480,8 +484,22 @@ def ListVisibleFiles(path): if not IsNormAbsPath(path): raise errors.ProgrammerError("Path passed to ListVisibleFiles is not" " absolute/normalized: '%s'" % path) - files = [i for i in os.listdir(path) if not i.startswith(".")] - return files + + mountpoint = _is_mountpoint(path) + + def fn(name): + """File name filter. + + Ignores files starting with a dot (".") as by Unix convention they're + considered hidden. The "lost+found" directory found at the root of some + filesystems is also hidden. + + """ + return not (name.startswith(".") or + (mountpoint and name == _LOST_AND_FOUND and + os.path.isdir(os.path.join(path, name)))) + + return filter(fn, os.listdir(path)) def EnsureDirs(dirs): diff --git a/test/ganeti.utils.io_unittest.py b/test/ganeti.utils.io_unittest.py index a383203df..46bb009d7 100755 --- a/test/ganeti.utils.io_unittest.py +++ b/test/ganeti.utils.io_unittest.py @@ -239,6 +239,27 @@ class TestListVisibleFiles(unittest.TestCase): self.failUnlessRaises(errors.ProgrammerError, utils.ListVisibleFiles, "/bin/../tmp") + def testMountpoint(self): + lvfmp_fn = compat.partial(utils.ListVisibleFiles, + _is_mountpoint=lambda _: True) + self.assertEqual(lvfmp_fn(self.path), []) + + # Create "lost+found" as a regular file + self._CreateFiles(["foo", "bar", ".baz", "lost+found"]) + self.assertEqual(set(lvfmp_fn(self.path)), + set(["foo", "bar", "lost+found"])) + + # Replace "lost+found" with a directory + laf_path = utils.PathJoin(self.path, "lost+found") + utils.RemoveFile(laf_path) + os.mkdir(laf_path) + self.assertEqual(set(lvfmp_fn(self.path)), set(["foo", "bar"])) + + def testLostAndFoundNoMountpoint(self): + files = ["foo", "bar", ".Hello World", "lost+found"] + expected = ["foo", "bar", "lost+found"] + self._test(files, expected) + class TestWriteFile(unittest.TestCase): def setUp(self): -- GitLab