From a2e195df3e5ba28ef9a7a2f096616af9a77a342a Mon Sep 17 00:00:00 2001
From: Brian Warner <warner@allmydata.com>
Date: Thu, 30 Oct 2008 14:54:47 -0700
Subject: [PATCH] debug catalog-shares: tolerate even more errors on bad
 files/directories

---
 src/allmydata/scripts/debug.py | 41 +++++++++++++++++++++++-----------
 src/allmydata/test/test_cli.py |  2 ++
 2 files changed, 30 insertions(+), 13 deletions(-)

diff --git a/src/allmydata/scripts/debug.py b/src/allmydata/scripts/debug.py
index 39e5f97f..0ac7cd8a 100644
--- a/src/allmydata/scripts/debug.py
+++ b/src/allmydata/scripts/debug.py
@@ -617,7 +617,6 @@ def describe_share(abs_sharefile, si_s, shnum_s, now, out):
 
     f.close()
 
-
 def catalog_shares(options):
     out = options.stdout
     err = options.stderr
@@ -634,20 +633,36 @@ def catalog_shares(options):
                 if abbrevdir == "incoming":
                     continue
                 abbrevdir = os.path.join(d, abbrevdir)
-                for si_s in os.listdir(abbrevdir):
-                    si_dir = os.path.join(abbrevdir, si_s)
-                    for shnum_s in os.listdir(si_dir):
-                        abs_sharefile = os.path.join(si_dir, shnum_s)
-                        abs_sharefile = os.path.abspath(abs_sharefile)
-                        assert os.path.isfile(abs_sharefile)
-                        try:
-                            describe_share(abs_sharefile, si_s, shnum_s, now,
-                                           out)
-                        except:
-                            print >>err, "Error processing %s" % abs_sharefile
-                            failure.Failure().printTraceback(err)
+                # this tool may get run against bad disks, so we can't assume
+                # that os.listdir will always succeed. Try to catalog as much
+                # as possible.
+                try:
+                    sharedirs = os.listdir(abbrevdir)
+                    for si_s in sharedirs:
+                        si_dir = os.path.join(abbrevdir, si_s)
+                        catalog_shares_one_abbrevdir(si_s, si_dir, now, out,err)
+                except:
+                    print >>err, "Error processing %s" % abbrevdir
+                    failure.Failure().printTraceback(err)
+
     return 0
 
+def catalog_shares_one_abbrevdir(si_s, si_dir, now, out, err):
+    try:
+        for shnum_s in os.listdir(si_dir):
+            abs_sharefile = os.path.join(si_dir, shnum_s)
+            abs_sharefile = os.path.abspath(abs_sharefile)
+            assert os.path.isfile(abs_sharefile)
+            try:
+                describe_share(abs_sharefile, si_s, shnum_s, now,
+                               out)
+            except:
+                print >>err, "Error processing %s" % abs_sharefile
+                failure.Failure().printTraceback(err)
+    except:
+        print >>err, "Error processing %s" % si_dir
+        failure.Failure().printTraceback(err)
+
 class CorruptShareOptions(usage.Options):
     def getSynopsis(self):
         return "Usage: tahoe debug corrupt-share SHARE_FILENAME"
diff --git a/src/allmydata/test/test_cli.py b/src/allmydata/test/test_cli.py
index 4de6740b..cd19f3f4 100644
--- a/src/allmydata/test/test_cli.py
+++ b/src/allmydata/test/test_cli.py
@@ -232,12 +232,14 @@ class CLI(unittest.TestCase):
         sharedir = os.path.join(nodedir1, "storage", "shares", "mq", "mqfblse6m5a6dh45isu2cg7oji")
         fileutil.make_dirs(sharedir)
         f = open(os.path.join(sharedir, "8"), "wb")
+        open("cli/test_catalog_shares/node1/storage/shares/mq/not-a-dir", "wb").close()
         # write a bogus share that looks a little bit like CHK
         f.write("\x00\x00\x00\x01" + "\xff" * 200) # this triggers an assert
         f.close()
 
         nodedir2 = "cli/test_catalog_shares/node2"
         fileutil.make_dirs(nodedir2)
+        open("cli/test_catalog_shares/node1/storage/shares/not-a-dir", "wb").close()
 
         # now make sure that the 'catalog-shares' commands survives the error
         out, err = self._catalog_shares(nodedir1, nodedir2)
-- 
2.45.2