upload: don't use servers which can't support the share size we need. This ought to avoid #439 problems. Some day we'll have a storage server which advertises support for a larger share size. No tests yet.

This commit is contained in:
Brian Warner 2008-11-21 20:28:12 -07:00
parent bf06492a90
commit 0fab511be5
2 changed files with 24 additions and 2 deletions

View File

@ -164,8 +164,6 @@ class Tahoe2PeerSelector:
if not peers:
raise NotEnoughSharesError("client gave us zero peers")
# figure out how much space to ask for
# this needed_hashes computation should mirror
# Encoder.send_all_share_hash_trees. We use an IncompleteHashTree
# (instead of a HashTree) because we don't require actual hashing
@ -173,6 +171,24 @@ class Tahoe2PeerSelector:
ht = hashtree.IncompleteHashTree(total_shares)
num_share_hashes = len(ht.needed_hashes(0, include_leaf=True))
# figure out how much space to ask for
allocated_size = layout.allocated_size(share_size,
num_segments,
num_share_hashes,
EXTENSION_SIZE)
# filter the list of peers according to which ones can accomodate
# this request. This excludes older peers (which used a 4-byte size
# field) from getting large shares (for files larger than about
# 12GiB). See #439 for details.
def _get_maxsize(peer):
(peerid, conn) = peer
v1 = conn.version["http://allmydata.org/tahoe/protocols/storage/v1"]
return v1["maximum-immutable-share-size"]
peers = [peer for peer in peers
if _get_maxsize(peer) >= allocated_size]
if not peers:
raise NotEnoughSharesError("no peers could accept an allocated_size of %d" % allocated_size)
# decide upon the renewal/cancel secrets, to include them in the
# allocat_buckets query.
client_renewal_secret = client.get_renewal_secret()

View File

@ -7,6 +7,7 @@ from twisted.python import log
from twisted.internet import defer
from foolscap import eventual
import allmydata
from allmydata import uri, monitor
from allmydata.immutable import upload
from allmydata.interfaces import IFileURI, FileTooLargeError, NotEnoughSharesError
@ -81,6 +82,11 @@ class FakeStorageServer:
self.mode = mode
self.allocated = []
self.queries = 0
self.version = { "http://allmydata.org/tahoe/protocols/storage/v1" :
{ "maximum-immutable-share-size": 2**32 },
"application-version": str(allmydata.__version__),
}
def callRemote(self, methname, *args, **kwargs):
def _call():
meth = getattr(self, methname)