LiteralFileURI instance has no attribute 'storage_index' #948

Closed
opened 2010-02-14 09:43:51 +00:00 by francois · 34 comments
francois commented 2010-02-14 09:43:51 +00:00
Owner

A daily cronjob is running 'tahoe deep-check --repair' on files which were created by 'tahoe backup'. It began to fail with the following exception sometimes around the implementation of immutable directories.

As soon as this failure occurs, the deep-check operation is aborted. This might be dangerous because the remaining files are not being correctly checked.

$ tahoe deep-check -v --repair --add-lease tahoe:
[...]
ERROR: AttributeError(LiteralFileURI instance has no attribute 'storage_index')
[Failure instance: Traceback: <type 'exceptions.AttributeError'>: LiteralFileURI instance has no attribute 'storage_index'
/usr/lib/python2.5/site-packages/twisted/internet/defer.py:285:unpause
/usr/lib/python2.5/site-packages/twisted/internet/defer.py:328:_runCallbacks
/home/francois/dev/tahoe/src/allmydata/dirnode.py:676:<lambda>
/home/francois/dev/tahoe/src/allmydata/dirnode.py:631:_deep_traverse_dirnode
--- <exception caught here> ---
/usr/lib/python2.5/site-packages/twisted/internet/defer.py:106:maybeDeferred
/home/francois/dev/tahoe/src/allmydata/web/directory.py:1114:add_node
/home/francois/dev/tahoe/src/allmydata/dirnode.py:349:get_storage_index
$ tahoe --version
allmydata-tahoe: 1.5.0-r4228, foolscap: 0.4.2, pycryptopp: 0.5.15, zfec: 1.4.5, Twisted: 8.1.0, Nevow: 0.9.33-r17222, zope.interface: 3.3.1, python: 2.5.2, platform: Linux-debian_5.0.4-i686-32bit, sqlite: 3.5.9, simplejson: 1.9.2, argparse: 0.9.1, pyOpenSSL: 0.7, pyutil: 1.3.34, zbase32: 1.1.1, setuptools: 0.6c12dev, pysqlite: 2.3.2
A daily cronjob is running 'tahoe deep-check --repair' on files which were created by 'tahoe backup'. It began to fail with the following exception sometimes around the implementation of immutable directories. As soon as this failure occurs, the deep-check operation is aborted. This might be dangerous because the remaining files are not being correctly checked. ``` $ tahoe deep-check -v --repair --add-lease tahoe: [...] ERROR: AttributeError(LiteralFileURI instance has no attribute 'storage_index') [Failure instance: Traceback: <type 'exceptions.AttributeError'>: LiteralFileURI instance has no attribute 'storage_index' /usr/lib/python2.5/site-packages/twisted/internet/defer.py:285:unpause /usr/lib/python2.5/site-packages/twisted/internet/defer.py:328:_runCallbacks /home/francois/dev/tahoe/src/allmydata/dirnode.py:676:<lambda> /home/francois/dev/tahoe/src/allmydata/dirnode.py:631:_deep_traverse_dirnode --- <exception caught here> --- /usr/lib/python2.5/site-packages/twisted/internet/defer.py:106:maybeDeferred /home/francois/dev/tahoe/src/allmydata/web/directory.py:1114:add_node /home/francois/dev/tahoe/src/allmydata/dirnode.py:349:get_storage_index ``` ``` $ tahoe --version allmydata-tahoe: 1.5.0-r4228, foolscap: 0.4.2, pycryptopp: 0.5.15, zfec: 1.4.5, Twisted: 8.1.0, Nevow: 0.9.33-r17222, zope.interface: 3.3.1, python: 2.5.2, platform: Linux-debian_5.0.4-i686-32bit, sqlite: 3.5.9, simplejson: 1.9.2, argparse: 0.9.1, pyOpenSSL: 0.7, pyutil: 1.3.34, zbase32: 1.1.1, setuptools: 0.6c12dev, pysqlite: 2.3.2 ```
tahoe-lafs added the
code-mutable
critical
defect
1.6.0
labels 2010-02-14 09:43:51 +00:00
tahoe-lafs added this to the undecided milestone 2010-02-14 09:43:51 +00:00
davidsarah commented 2010-02-14 22:46:16 +00:00
Author
Owner

[get_storage_index on DirectoryNode]source:src/allmydata/dirnode.py?rev=4195#L348 is implemented like this:

    def get_storage_index(self):
        return self._uri._filenode_uri.storage_index

which makes unwarranted assumptions about attributes of URI objects. It should be

    def get_storage_index(self):
        return self._uri.get_storage_index()

(This delegates to [get_storage_index on _DirectoryBaseURI]source:src/allmydata/uri.py?rev=4194#L448, which delegates to [get_storage_index on LiteralFileURI]source:src/allmydata/uri.py?rev=4194#L228, which correctly returns None. The bug probably occurred as a result of trying to skip one of these delegation steps, violating abstraction.)

Please check whether this is sufficient to fix the problem -- I haven't checked whether tahoe check handles a storage index of None correctly, although it should if it handles LIT files.

[get_storage_index on [DirectoryNode](wiki/DirectoryNode)]source:src/allmydata/dirnode.py?rev=4195#L348 is implemented like this: ``` def get_storage_index(self): return self._uri._filenode_uri.storage_index ``` which makes unwarranted assumptions about attributes of URI objects. It should be ``` def get_storage_index(self): return self._uri.get_storage_index() ``` (This delegates to [get_storage_index on _DirectoryBaseURI]source:src/allmydata/uri.py?rev=4194#L448, which delegates to [get_storage_index on [LiteralFile](wiki/LiteralFile)URI]source:src/allmydata/uri.py?rev=4194#L228, which correctly returns None. The bug probably occurred as a result of trying to skip one of these delegation steps, violating abstraction.) Please check whether this is sufficient to fix the problem -- I haven't checked whether `tahoe check` handles a storage index of None correctly, although it should if it handles LIT files.
tahoe-lafs added
code-dirnodes
and removed
code-mutable
labels 2010-02-14 22:46:16 +00:00
tahoe-lafs modified the milestone from undecided to 1.7.0 2010-02-14 22:46:16 +00:00
davidsarah commented 2010-02-14 22:51:03 +00:00
Author
Owner

(I meant tahoe deep-check, not tahoe check.)

This is a regression relative to 1.5.0, since tahoe backup didn't use immutable directories then, and only immutable directories can wrap a LiteralFileURI.

(I meant `tahoe deep-check`, not `tahoe check`.) This is a regression relative to 1.5.0, since `tahoe backup` didn't use immutable directories then, and only immutable directories can wrap a [LiteralFile](wiki/LiteralFile)URI.
davidsarah commented 2010-02-14 23:32:31 +00:00
Author
Owner

Looking at where get_storage_index, it seems that several other operations on empty immutable directories that are small enough to fit in a LIT file are likely to fail. Viewing them in the WUI certainly provokes the same error:

We should probably put out a point release (although there's time to fix other stuff and perhaps include #778.)

Looking at where `get_storage_index`, it seems that several other operations on empty immutable directories that are small enough to fit in a LIT file are likely to fail. Viewing them in the WUI certainly provokes the same error: * <http://testgrid.allmydata.org:3567/uri/URI:DIR2-LIT:ge3dumj2mewdcotyfqydulbshj5x2lbm/> * <http://testgrid.allmydata.org:3567/uri/URI:DIR2-LIT:/> We should probably put out a point release (although there's time to fix other stuff and perhaps include #778.)

In general, a storage_index of None is used to indicate a "non-distributed file", which the Checker ought to skip entirely (non-distributed files are always healthy). I'd guess that we used to have about 90% support for these (i.e. of the code that I wrote, I probably made it tolerate LITs about 90% of the time, and/or we have test coverage of this for about 90% of the code paths). But it sounds like something changed recently.

In general, a storage_index of None is used to indicate a "non-distributed file", which the Checker ought to skip entirely (non-distributed files are always healthy). I'd guess that we used to have about 90% support for these (i.e. of the code that I wrote, I probably made it tolerate LITs about 90% of the time, and/or we have test coverage of this for about 90% of the code paths). But it sounds like something changed recently.
tahoe-lafs modified the milestone from 1.7.0 to 1.6.1 2010-02-15 19:25:09 +00:00
davidsarah commented 2010-02-15 19:28:39 +00:00
Author
Owner

As far as I can see, we have no tests for DIR2-LIT URIs, which is why this escaped notice in the 1.6.0 release cycle.

As far as I can see, we have no tests for DIR2-LIT URIs, which is why this escaped notice in the 1.6.0 release cycle.

I'm writing tests.

I'm writing tests.
davidsarah commented 2010-02-22 02:07:32 +00:00
Author
Owner

Zooko is writing tests for test_dirnode.py. I'll write them for test_web.py, and write the actual fix. Note that there are other cases -- lots in test code and a few in non-test code -- where we directly access .storage_index on an URI object rather than calling .get_storage_index().

Zooko is writing tests for test_dirnode.py. I'll write them for test_web.py, and write the actual fix. Note that there are other cases -- lots in test code and a few in non-test code -- where we directly access `.storage_index` on an URI object rather than calling `.get_storage_index()`.
davidsarah commented 2010-02-22 03:01:44 +00:00
Author
Owner

Attachment fix-948-darcspatch.txt (71091 bytes) added

Change direct accesses to an_uri.storage_index to calls to .get_storage_index() (fixes #948)

**Attachment** fix-948-darcspatch.txt (71091 bytes) added Change direct accesses to an_uri.storage_index to calls to .get_storage_index() (fixes #948)
davidsarah commented 2010-02-22 03:02:34 +00:00
Author
Owner

Attachment test-web-948-darcspatch.txt (58273 bytes) added

Additions to test_web.py for #948

**Attachment** test-web-948-darcspatch.txt (58273 bytes) added Additions to test_web.py for #948
davidsarah commented 2010-02-22 03:45:29 +00:00
Author
Owner

Attachment all-948-darcspatch.txt (78728 bytes) added

Additional fix for abbrev_si, with test (includes previous two patches)

**Attachment** all-948-darcspatch.txt (78728 bytes) added Additional fix for abbrev_si, with test (includes previous two patches)

Attachment test-dirnode-lit.darcspatch.txt (10695 bytes) added

add tests of literal dirnodes (the current code already passes these tests) This patch replaces the previous patch by the same name, which was buggy.

**Attachment** test-dirnode-lit.darcspatch.txt (10695 bytes) added add tests of literal dirnodes (the current code already passes these tests) This patch replaces the previous patch by the same name, which was buggy.

We should add a test of deepcheck (where this issue was first detected). I think all we need to do is add a DIR2:LIT to [DeepCheckWebGood.set_up_tree()]source:src/allmydata/test/test_deepcheck.py@4164#L206.

We should add a test of deepcheck (where this issue was first detected). I think all we need to do is add a `DIR2:LIT` to [DeepCheckWebGood.set_up_tree()]source:src/allmydata/test/test_deepcheck.py@4164#L206.
davidsarah commented 2010-02-23 04:29:04 +00:00
Author
Owner

DeepCheckWebGood.set_up_tree: agreed. I also want to check the WUI output for a DIR2:LIT, which is in test_web.py.

[DeepCheckWebGood](wiki/DeepCheckWebGood).set_up_tree: agreed. I also want to check the WUI output for a DIR2:LIT, which is in test_web.py.
davidsarah commented 2010-02-24 04:44:46 +00:00
Author
Owner

Attachment test-dirnode-lit-2-darcspatch.txt (68099 bytes) added

dirnode: add tests of literal dirnodes (current and fix for #948)

**Attachment** test-dirnode-lit-2-darcspatch.txt (68099 bytes) added dirnode: add tests of literal dirnodes (current and fix for #948)
davidsarah commented 2010-02-24 05:41:51 +00:00
Author
Owner

Attachment More Info for DIR2-LIT directory.html (18550 bytes) added

Nevow traceback showing bug when following More Info link of a DIR2-LIT directory (http://127.0.0.1:3456/uri/URI%3ADIR2-LIT%3Agqytunj2onug64tufqzdcosvkjetutcjkq5gw4tvm5vwszdgnz5hgyzufqydulbshj5x2lbm/?t=info)

**Attachment** More Info for DIR2-LIT directory.html (18550 bytes) added Nevow traceback showing bug when following More Info link of a DIR2-LIT directory (<http://127.0.0.1:3456/uri/URI%3ADIR2-LIT%3Agqytunj2onug64tufqzdcosvkjetutcjkq5gw4tvm5vwszdgnz5hgyzufqydulbshj5x2lbm/?t=info>)

Attachment test-dirnode-lit-in-deep-check.darcspatch.txt (17755 bytes) added

add tests of literal dirnodes to test_deepcheck.py (the current trunk fails these tests and so does the current all-948-darcspatch.txt! Of course I'm not sure if it is the tests or the code that is wrong)

**Attachment** test-dirnode-lit-in-deep-check.darcspatch.txt (17755 bytes) added add tests of literal dirnodes to test_deepcheck.py (the current trunk fails these tests and so does the current all-948-darcspatch.txt! Of course I'm not sure if it is the tests or the code that is wrong)
davidsarah commented 2010-02-24 08:07:55 +00:00
Author
Owner

Attachment test-dirnode-lit-in-deep-check-2-darcspatch.txt (71825 bytes) added

directories: add DIR2-LIT directories to test_deepcheck.py (#948) -- fixes test bugs

**Attachment** test-dirnode-lit-in-deep-check-2-darcspatch.txt (71825 bytes) added directories: add DIR2-LIT directories to test_deepcheck.py (#948) -- fixes test bugs
davidsarah commented 2010-02-24 08:16:09 +00:00
Author
Owner

Attachment additional-fixes-for-948-darcspatch.txt (59841 bytes) added

Additional fixes for DIR2-LIT More Info page and deep-check/manifest operations (#948)

**Attachment** additional-fixes-for-948-darcspatch.txt (59841 bytes) added Additional fixes for DIR2-LIT More Info page and deep-check/manifest operations (#948)
davidsarah commented 2010-02-24 08:21:07 +00:00
Author
Owner

The patch bundles that need review are:

  • all-948-darcspatch.txt
  • test-dirnode-lit-2-darcspatch.txt
  • test-dirnode-lit-in-deep-check-2-darcspatch.txt
  • additional-fixes-for-948-darcspatch.txt

This does not include the test of WUI output, which is currently failing (the functionality seems to work, so I think it's a test problem -- will investigate tomorrow).

The patch bundles that need review are: * all-948-darcspatch.txt * test-dirnode-lit-2-darcspatch.txt * test-dirnode-lit-in-deep-check-2-darcspatch.txt * additional-fixes-for-948-darcspatch.txt This does not include the test of WUI output, which is currently failing (the functionality seems to work, so I think it's a test problem -- will investigate tomorrow).
davidsarah commented 2010-02-24 08:24:52 +00:00
Author
Owner

Attachment updates-to-NEWS-darcspatch.txt (55471 bytes) added

Updates to NEWS relevant to this ticket and #577

**Attachment** updates-to-NEWS-darcspatch.txt (55471 bytes) added Updates to NEWS relevant to this ticket and #577

I think we need to add to some of these tests -- at least to test_deepcheck.py -- a large immutable directory. Large enough so that it isn't a LIT.

I think we need to add to some of these tests -- at least to test_deepcheck.py -- a large immutable directory. Large enough so that it isn't a LIT.
davidsarah commented 2010-02-25 03:02:16 +00:00
Author
Owner

Replying to zooko:

I think we need to add to some of these tests -- at least to test_deepcheck.py -- a large immutable directory. Large enough so that it isn't a LIT.

I agree that would be useful, but strictly speaking this ticket is about DIR2-LITs, so let's get these patches reviewed first.

Replying to [zooko](/tahoe-lafs/trac-2024-07-25/issues/948#issuecomment-75405): > I think we need to add to some of these tests -- at least to test_deepcheck.py -- a large immutable directory. Large enough so that it isn't a LIT. I agree that would be useful, but strictly speaking this ticket is about DIR2-LITs, so let's get these patches reviewed first.
davidsarah commented 2010-02-25 04:28:35 +00:00
Author
Owner

Attachment test-dirnode-lit-in-wui-darcspatch.txt (57850 bytes) added

Additional test for DIR2-LIT directories in test_web.py, fixed version (#948). Corrects a mistake in the use of Deferreds.

**Attachment** test-dirnode-lit-in-wui-darcspatch.txt (57850 bytes) added Additional test for DIR2-LIT directories in test_web.py, fixed version (#948). Corrects a mistake in the use of Deferreds.

Okay I'm reviewing

  • test-dirnode-lit-in-wui-darcspatch.txt
  • updates-to-NEWS-darcspatch.txt
  • all-948-darcspatch.txt
  • test-dirnode-lit-2-darcspatch.txt
  • test-dirnode-lit-in-deep-check-2-darcspatch.txt
  • additional-fixes-for-948-darcspatch.txt
    Is that the right set to review?
Okay I'm reviewing * test-dirnode-lit-in-wui-darcspatch.txt * updates-to-NEWS-darcspatch.txt * all-948-darcspatch.txt * test-dirnode-lit-2-darcspatch.txt * test-dirnode-lit-in-deep-check-2-darcspatch.txt * additional-fixes-for-948-darcspatch.txt Is that the right set to review?
zooko self-assigned this 2010-02-27 03:26:59 +00:00

I reviewed test-dirnode-lit-in-wui-darcspatch.txt and it looks good.

I reviewed [test-dirnode-lit-in-wui-darcspatch.txt](/tahoe-lafs/trac-2024-07-25/attachments/000078ac-0a6b-d727-548a-54433f3cd4d9) and it looks good.
I reviewed [test-dirnode-lit-in-deep-check-2-darcspatch.txt](/tahoe-lafs/trac-2024-07-25/attachments/000078ac-0a6b-d727-548a-9f34cacee2a9) and it is good.
Replying to [zooko](/tahoe-lafs/trac-2024-07-25/issues/948#issuecomment-75410): > I reviewed [test-dirnode-lit-in-deep-check-2-darcspatch.txt](/tahoe-lafs/trac-2024-07-25/attachments/000078ac-0a6b-d727-548a-9f34cacee2a9) and it is good. Whoops, sorry I meant [updates-to-NEWS-darcspatch.txt](/tahoe-lafs/trac-2024-07-25/attachments/000078ac-0a6b-d727-548a-59fe96296cd2) not [test-dirnode-lit-in-deep-check-2-darcspatch.txt](/tahoe-lafs/trac-2024-07-25/attachments/000078ac-0a6b-d727-548a-9f34cacee2a9).

Okay, now I've reviewed test-dirnode-lit-in-deep-check-2-darcspatch.txt and approved it. Technically, it would be better if someone else reviewed test-dirnode-lit-in-deep-check-2-darcspatch.txt since I'm part author of it, but Brian's not around on IRC right now and I'm hoping to announce v1.6.1 tomorrow! :-) If Kevan or anyone else is reading this and wants to read over test-dirnode-lit-in-deep-check-2-darcspatch.txt and look for goofs, that would be great. It will probably take only a few minutes, especially if you don't mind being uncertain about exactly what all the tests do and just look for things that look suspiciously like mistakes to you. If you develop a confident understanding of what the tests actually do here, all the better!

Okay, *now* I've reviewed [test-dirnode-lit-in-deep-check-2-darcspatch.txt](/tahoe-lafs/trac-2024-07-25/attachments/000078ac-0a6b-d727-548a-9f34cacee2a9) and approved it. Technically, it would be better if someone else reviewed [test-dirnode-lit-in-deep-check-2-darcspatch.txt](/tahoe-lafs/trac-2024-07-25/attachments/000078ac-0a6b-d727-548a-9f34cacee2a9) since I'm part author of it, but Brian's not around on IRC right now and I'm hoping to announce v1.6.1 tomorrow! :-) If Kevan or anyone else is reading this and wants to read over [test-dirnode-lit-in-deep-check-2-darcspatch.txt](/tahoe-lafs/trac-2024-07-25/attachments/000078ac-0a6b-d727-548a-9f34cacee2a9) and look for goofs, that would be great. It will probably take only a few minutes, especially if you don't mind being uncertain about exactly what all the tests do and just look for things that look suspiciously like mistakes to you. If you develop a confident understanding of what the tests actually do here, all the better!

Okay, I've reviewed test-dirnode-lit-2-darcspatch.txt and I like it. Again, I'm not the perfect reviewer since I'm the author of most of this one, so if you are reading this and you can double-check that patch, that would be great.

Okay, I've reviewed [test-dirnode-lit-2-darcspatch.txt](/tahoe-lafs/trac-2024-07-25/attachments/000078ac-0a6b-d727-548a-ce6728439d47) and I like it. Again, I'm not the perfect reviewer since I'm the author of most of this one, so if you are reading this and you can double-check that patch, that would be great.

Okay, I've reviewed all-948-darcspatch.txt and could find nothing in it to change!

Okay, I've reviewed [all-948-darcspatch.txt](/tahoe-lafs/trac-2024-07-25/attachments/000078ac-0a6b-d727-548a-35fcbf3d6d17) and could find nothing in it to change!

Okay I'm looking at additional-fixes-for-948-darcspatch.txt, which is the last patch from the set of six patches that constitute the fix for this ticket (per comment:75407). For this one I have some questions:

  • Is this correct:
+            self.root_storage_index_s = "<none>"  # is this correct?

(Elsewhere we use either "" or "<LIT>" to be the string encoding of a null storage index.)

  • Should we add tests of the changes in this patch, mainly the changes to emit "" when a storage index is None, or there already unit tests that fail when those changes are not applied?
  • The construction base32.b2a(m.origin_si or "") feels slightly weird to me because it feels like a type error—we really mean that the expression should evaluate to "" not that the argument to b2a() should be "". However, the alternative is bigger and uglier: m.origin_si and base32.b2a(m.origin_si) or "". Maybe we should define a function:
def b2a_or_empty(si):
    if si:
        return base32.b2a(si)
    else:
        return ""
Okay I'm looking at [additional-fixes-for-948-darcspatch.txt](/tahoe-lafs/trac-2024-07-25/attachments/000078ac-0a6b-d727-548a-7daa5162ac9c), which is the last patch from the set of six patches that constitute the fix for this ticket (per [comment:75407](/tahoe-lafs/trac-2024-07-25/issues/948#issuecomment-75407)). For this one I have some questions: * Is this correct: ``` + self.root_storage_index_s = "<none>" # is this correct? ``` (Elsewhere we use either `""` or `"<LIT>"` to be the string encoding of a null storage index.) * Should we add tests of the changes in this patch, mainly the changes to emit `""` when a storage index is `None`, or there already unit tests that fail when those changes are not applied? * The construction `base32.b2a(m.origin_si or "")` feels slightly weird to me because it feels like a type error—we really mean that the expression should evaluate to `""` not that the argument to `b2a()` should be `""`. However, the alternative is bigger and uglier: `m.origin_si and base32.b2a(m.origin_si) or ""`. Maybe we should define a function: ``` def b2a_or_empty(si): if si: return base32.b2a(si) else: return "" ```
davidsarah commented 2010-02-27 07:08:51 +00:00
Author
Owner

Attachment all-darcspatch.txt (125875 bytes) added

All patches to be applied for #948

**Attachment** all-darcspatch.txt (125875 bytes) added All patches to be applied for #948
davidsarah commented 2010-02-27 07:34:34 +00:00
Author
Owner

all-darcspatch.txt includes a change to avoid base32.b2a(... or ""), although not using a separate function. This change has been reviewed by bigpig.

The changes to emit "" when the storage index is None are tested by test_deepcheck.py. We decided not to change "" for 1.6.1.

all-darcspatch.txt includes a change to avoid `base32.b2a(... or "")`, although not using a separate function. This change has been reviewed by bigpig. The changes to emit `""` when the storage index is `None` are tested by `test_deepcheck.py`. We decided not to change "<none>" for 1.6.1.
davidsarah commented 2010-02-27 07:38:48 +00:00
Author
Owner

Committed as changeset:973f0afdd32285a7, changeset:d29ec184a6e67623, changeset:fec9185f2a866523, changeset:187d837c1db532f6, changeset:e6aee33bb77f6f88, changeset:d7b50a3b86acf8c6, changeset:f8e2bab41ea6c38d, changeset:a2ed17f2a0d69ec3, changeset:40edf8f419947b80.

Committed as changeset:973f0afdd32285a7, changeset:d29ec184a6e67623, changeset:fec9185f2a866523, changeset:187d837c1db532f6, changeset:e6aee33bb77f6f88, changeset:d7b50a3b86acf8c6, changeset:f8e2bab41ea6c38d, changeset:a2ed17f2a0d69ec3, changeset:40edf8f419947b80.
tahoe-lafs added the
fixed
label 2010-02-27 07:38:48 +00:00
Sign in to join this conversation.
No Milestone
No Assignees
3 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Reference: tahoe-lafs/trac-2024-07-25#948
No description provided.