Beispiel #1
0
    def cancel_lease(self, cancel_secret):
        """Remove a lease with the given cancel_secret. If the last lease is
        cancelled, the file will be removed. Return the number of bytes that
        were freed (by truncating the list of leases, and possibly by
        deleting the file. Raise IndexError if there was no lease with the
        given cancel_secret.
        """

        leases = list(self.get_leases())
        num_leases_removed = 0
        for i,lease in enumerate(leases):
            if constant_time_compare(lease.cancel_secret, cancel_secret):
                leases[i] = None
                num_leases_removed += 1
        if not num_leases_removed:
            raise IndexError("unable to find matching lease to cancel")
        if num_leases_removed:
            # pack and write out the remaining leases. We write these out in
            # the same order as they were added, so that if we crash while
            # doing this, we won't lose any non-cancelled leases.
            leases = [l for l in leases if l] # remove the cancelled leases
            f = open(self.home, 'rb+')
            for i,lease in enumerate(leases):
                self._write_lease_record(f, i, lease)
            self._write_num_leases(f, len(leases))
            self._truncate_leases(f, len(leases))
            f.close()
        space_freed = self.LEASE_SIZE * num_leases_removed
        if not len(leases):
            space_freed += os.stat(self.home)[stat.ST_SIZE]
            self.unlink()
        return space_freed
Beispiel #2
0
    def cancel_lease(self, cancel_secret):
        """Remove a lease with the given cancel_secret. If the last lease is
        cancelled, the file will be removed. Return the number of bytes that
        were freed (by truncating the list of leases, and possibly by
        deleting the file. Raise IndexError if there was no lease with the
        given cancel_secret.
        """

        leases = list(self.get_leases())
        num_leases_removed = 0
        for i, lease in enumerate(leases):
            if constant_time_compare(lease.cancel_secret, cancel_secret):
                leases[i] = None
                num_leases_removed += 1
        if not num_leases_removed:
            raise IndexError("unable to find matching lease to cancel")
        if num_leases_removed:
            # pack and write out the remaining leases. We write these out in
            # the same order as they were added, so that if we crash while
            # doing this, we won't lose any non-cancelled leases.
            leases = [l for l in leases if l]  # remove the cancelled leases
            f = open(self.home, 'rb+')
            for i, lease in enumerate(leases):
                self._write_lease_record(f, i, lease)
            self._write_num_leases(f, len(leases))
            self._truncate_leases(f, len(leases))
            f.close()
        space_freed = self.LEASE_SIZE * num_leases_removed
        if not len(leases):
            space_freed += os.stat(self.home)[stat.ST_SIZE]
            self.unlink()
        return space_freed
Beispiel #3
0
 def renew_lease(self, renew_secret, new_expire_time):
     for i,lease in enumerate(self.get_leases()):
         if constant_time_compare(lease.renew_secret, renew_secret):
             # yup. See if we need to update the owner time.
             if new_expire_time > lease.expiration_time:
                 # yes
                 lease.expiration_time = new_expire_time
                 f = open(self.home, 'rb+')
                 self._write_lease_record(f, i, lease)
                 f.close()
             return
     raise IndexError("unable to renew non-existent lease")
Beispiel #4
0
 def renew_lease(self, renew_secret, new_expire_time):
     for i, lease in enumerate(self.get_leases()):
         if constant_time_compare(lease.renew_secret, renew_secret):
             # yup. See if we need to update the owner time.
             if new_expire_time > lease.expiration_time:
                 # yes
                 lease.expiration_time = new_expire_time
                 f = open(self.home, 'rb+')
                 self._write_lease_record(f, i, lease)
                 f.close()
             return
     raise IndexError("unable to renew non-existent lease")
Beispiel #5
0
 def check_write_enabler(self, write_enabler, si_s):
     f = open(self.home, 'rb+')
     (real_write_enabler, write_enabler_nodeid) = \
                          self._read_write_enabler_and_nodeid(f)
     f.close()
     # avoid a timing attack
     #if write_enabler != real_write_enabler:
     if not constant_time_compare(write_enabler, real_write_enabler):
         # accomodate share migration by reporting the nodeid used for the
         # old write enabler.
         self.log(format="bad write enabler on SI %(si)s,"
                  " recorded by nodeid %(nodeid)s",
                  facility="tahoe.storage",
                  level=log.WEIRD, umid="cE1eBQ",
                  si=si_s, nodeid=idlib.nodeid_b2a(write_enabler_nodeid))
         msg = "The write enabler was recorded by nodeid '%s'." % \
               (idlib.nodeid_b2a(write_enabler_nodeid),)
         raise BadWriteEnablerError(msg)
Beispiel #6
0
 def check_write_enabler(self, write_enabler, si_s):
     f = open(self.home, 'rb+')
     (real_write_enabler, write_enabler_nodeid) = \
                          self._read_write_enabler_and_nodeid(f)
     f.close()
     # avoid a timing attack
     #if write_enabler != real_write_enabler:
     if not constant_time_compare(write_enabler, real_write_enabler):
         # accomodate share migration by reporting the nodeid used for the
         # old write enabler.
         self.log(format="bad write enabler on SI %(si)s,"
                  " recorded by nodeid %(nodeid)s",
                  facility="tahoe.storage",
                  level=log.WEIRD,
                  umid="cE1eBQ",
                  si=si_s,
                  nodeid=idlib.nodeid_b2a(write_enabler_nodeid))
         msg = "The write enabler was recorded by nodeid '%s'." % \
               (idlib.nodeid_b2a(write_enabler_nodeid),)
         raise BadWriteEnablerError(msg)
Beispiel #7
0
 def renew_lease(self, renew_secret, new_expire_time):
     accepting_nodeids = set()
     f = open(self.home, 'rb+')
     for (leasenum, lease) in self._enumerate_leases(f):
         if constant_time_compare(lease.renew_secret, renew_secret):
             # yup. See if we need to update the owner time.
             if new_expire_time > lease.expiration_time:
                 # yes
                 lease.expiration_time = new_expire_time
                 self._write_lease_record(f, leasenum, lease)
             f.close()
             return
         accepting_nodeids.add(lease.nodeid)
     f.close()
     # Return the accepting_nodeids set, to give the client a chance to
     # update the leases on a share which has been migrated from its
     # original server to a new one.
     msg = ("Unable to renew non-existent lease. I have leases accepted by"
            " nodeids: ")
     msg += ",".join([("'%s'" % idlib.nodeid_b2a(anid))
                      for anid in accepting_nodeids])
     msg += " ."
     raise IndexError(msg)
Beispiel #8
0
 def renew_lease(self, renew_secret, new_expire_time):
     accepting_nodeids = set()
     f = open(self.home, 'rb+')
     for (leasenum,lease) in self._enumerate_leases(f):
         if constant_time_compare(lease.renew_secret, renew_secret):
             # yup. See if we need to update the owner time.
             if new_expire_time > lease.expiration_time:
                 # yes
                 lease.expiration_time = new_expire_time
                 self._write_lease_record(f, leasenum, lease)
             f.close()
             return
         accepting_nodeids.add(lease.nodeid)
     f.close()
     # Return the accepting_nodeids set, to give the client a chance to
     # update the leases on a share which has been migrated from its
     # original server to a new one.
     msg = ("Unable to renew non-existent lease. I have leases accepted by"
            " nodeids: ")
     msg += ",".join([("'%s'" % idlib.nodeid_b2a(anid))
                      for anid in accepting_nodeids])
     msg += " ."
     raise IndexError(msg)
Beispiel #9
0
    def cancel_lease(self, cancel_secret):
        """Remove any leases with the given cancel_secret. If the last lease
        is cancelled, the file will be removed. Return the number of bytes
        that were freed (by truncating the list of leases, and possibly by
        deleting the file. Raise IndexError if there was no lease with the
        given cancel_secret."""

        accepting_nodeids = set()
        modified = 0
        remaining = 0
        blank_lease = LeaseInfo(owner_num=0,
                                renew_secret="\x00" * 32,
                                cancel_secret="\x00" * 32,
                                expiration_time=0,
                                nodeid="\x00" * 20)
        f = open(self.home, 'rb+')
        for (leasenum, lease) in self._enumerate_leases(f):
            accepting_nodeids.add(lease.nodeid)
            if constant_time_compare(lease.cancel_secret, cancel_secret):
                self._write_lease_record(f, leasenum, blank_lease)
                modified += 1
            else:
                remaining += 1
        if modified:
            freed_space = self._pack_leases(f)
            f.close()
            if not remaining:
                freed_space += os.stat(self.home)[stat.ST_SIZE]
                self.unlink()
            return freed_space

        msg = ("Unable to cancel non-existent lease. I have leases "
               "accepted by nodeids: ")
        msg += ",".join([("'%s'" % idlib.nodeid_b2a(anid))
                         for anid in accepting_nodeids])
        msg += " ."
        raise IndexError(msg)
Beispiel #10
0
    def cancel_lease(self, cancel_secret):
        """Remove any leases with the given cancel_secret. If the last lease
        is cancelled, the file will be removed. Return the number of bytes
        that were freed (by truncating the list of leases, and possibly by
        deleting the file. Raise IndexError if there was no lease with the
        given cancel_secret."""

        accepting_nodeids = set()
        modified = 0
        remaining = 0
        blank_lease = LeaseInfo(owner_num=0,
                                renew_secret="\x00"*32,
                                cancel_secret="\x00"*32,
                                expiration_time=0,
                                nodeid="\x00"*20)
        f = open(self.home, 'rb+')
        for (leasenum,lease) in self._enumerate_leases(f):
            accepting_nodeids.add(lease.nodeid)
            if constant_time_compare(lease.cancel_secret, cancel_secret):
                self._write_lease_record(f, leasenum, blank_lease)
                modified += 1
            else:
                remaining += 1
        if modified:
            freed_space = self._pack_leases(f)
            f.close()
            if not remaining:
                freed_space += os.stat(self.home)[stat.ST_SIZE]
                self.unlink()
            return freed_space

        msg = ("Unable to cancel non-existent lease. I have leases "
               "accepted by nodeids: ")
        msg += ",".join([("'%s'" % idlib.nodeid_b2a(anid))
                         for anid in accepting_nodeids])
        msg += " ."
        raise IndexError(msg)