def op_lock(self, op): print " CURRENT FILEHANDLE %s" % repr(self.curr_fh) try: replay = None if op.oplock.locker.new_lock_owner: owner = op.oplock.locker.open_owner.lock_owner seqid = op.oplock.locker.open_owner.lock_seqid openstateid = op.oplock.locker.open_owner.open_stateid openseqid = op.oplock.locker.open_owner.open_seqid replay = self.state.check_seqid(openstateid, openseqid) else: owner = op.oplock.locker.lock_owner.lock_stateid seqid = op.oplock.locker.lock_owner.lock_seqid openstateid = None replay = self.state.check_seqid(owner, seqid) if replay: self.curr_fh, args = self.check_replay(op, replay) return simple_error(*args) # Note must cache response, so need to call raise instead of return if not self.curr_fh: raise NFS4Error(NFS4ERR_NOFILEHANDLE) if op.oplock.reclaim: raise NFS4Error(NFS4ERR_NO_GRACE) if op.oplock.locker.new_lock_owner: self.state.new_lockowner(op.oplock.locker.open_owner) stateid = self.state.lock(self.curr_fh, owner, op.oplock.locktype, op.oplock.offset, op.oplock.length) except NFS4Error, e: if op.oplock.locker.new_lock_owner: # FIXME - a bug? compare with replay=check_seqid() above self.state.advance_seqid(openstateid, op, (e.code, )) self.state.advance_seqid(owner, op, (e.code, None, e.lock_denied)) return simple_error(e.code, None, e.lock_denied)
def op_open_downgrade(self, op): print " CURRENT FILEHANDLE: %s" % repr(self.curr_fh) stateid = op.opopen_downgrade.open_stateid try: replay = self.state.check_seqid(stateid, op.opopen_downgrade.seqid) if replay: self.curr_fh, args = self.check_replay(op, replay) return simple_error(*args) # Note must cache response, so need to call raise instead of return if not self.curr_fh: raise NFS4Error(NFS4ERR_NOFILEHANDLE) if self.curr_fh.get_type() != NF4REG: raise NFS4Error(NFS4ERR_INVAL) sid = self.state.downgrade(self.curr_fh, stateid, op.opopen_downgrade.share_access, op.opopen_downgrade.share_deny) except NFS4Error, e: self.state.advance_seqid(stateid, op, (e.code, )) return simple_error(e.code)
def op_open_confirm(self, op): print " CURRENT FILEHANDLE: %s" % repr(self.curr_fh) print " SEQID: %i" % op.opopen_confirm.seqid stateid = op.opopen_confirm.open_stateid try: replay = self.state.check_seqid(stateid, op.opopen_confirm.seqid, open_confirm=True) if replay: self.curr_fh, args = self.check_replay(op, replay) return simple_error(*args) # Note must cache response, so need to call raise instead of return if not self.curr_fh: raise NFS4Error(NFS4ERR_NOFILEHANDLE) if self.curr_fh.get_type() == NF4DIR: raise NFS4Error(NFS4ERR_ISDIR) if self.curr_fh.get_type() != NF4REG: raise NFS4Error(NFS4ERR_INVAL) sid = self.state.confirm(self.curr_fh, stateid) except NFS4Error, e: self.state.advance_seqid(stateid, op, (e.code, )) return simple_error(e.code)
def op_locku(self, op): print " CURRENT FILEHANDLE %s" % repr(self.curr_fh) stateid = op.oplocku.lock_stateid try: replay = self.state.check_seqid(stateid, op.oplocku.seqid) if replay: self.curr_fh, args = self.check_replay(op, replay) return simple_error(*args) # Note must cache response, so need to call raise instead of return if not self.curr_fh: raise NFS4Error(NFS4ERR_NOFILEHANDLE) sid = self.state.unlock(self.curr_fh, stateid, op.oplocku.locktype, op.oplocku.offset, op.oplocku.length) except NFS4Error, e: self.state.advance_seqid(stateid, op, (e.code, )) return simple_error(e.code)
def op_close(self, op): print " CURRENT FILEHANDLE: %s" % repr(self.curr_fh) print " SEQID: %i" % op.opclose.seqid stateid = op.opclose.open_stateid try: replay = self.state.check_seqid(stateid, op.opclose.seqid) if replay: self.curr_fh, args = self.check_replay(op, replay) print "Replay args = %s" % str(args) return simple_error(*args) # Note must cache response, so need to call raise instead of return if not self.curr_fh: raise NFS4Error(NFS4ERR_NOFILEHANDLE) print " CLOSE fh", self.curr_fh.handle self.state.close(stateid) except NFS4Error, e: self.state.advance_seqid(stateid, op, (e.code, )) return simple_error(e.code)
def op_open(self, op): print(" CURRENT FILEHANDLE: %s" % repr(self.curr_fh)) print(" SEQID: %i" % op.opopen.seqid) owner = op.opopen.owner print(" CLIENTID: %d" % owner.clientid) print(" OWNER: '%s'" % repr(owner.owner)) try: if not self.state.confirmed.exists(c=owner.clientid): if self.state.unconfirmed.exists(c=owner.clientid): raise NFS4Error(NFS4ERR_STALE_CLIENTID) else: raise NFS4Error(NFS4ERR_BADOWNER) replay = self.state.check_seqid(owner, op.opopen.seqid, False) if replay: self.curr_fh, args = self.check_replay(op, replay) return simple_error(*args) # Note must cache response, so need to call raise instead of return if not self.curr_fh: raise NFS4Error(NFS4ERR_NOFILEHANDLE) if op.opopen.claim.claim == CLAIM_PREVIOUS: raise NFS4Error(NFS4ERR_NO_GRACE) if op.opopen.claim.claim in [CLAIM_DELEGATE_CUR, CLAIM_DELEGATE_PREV]: raise NFS4Error(NFS4ERR_NOTSUPP) if self.curr_fh.get_type() != NF4DIR: raise NFS4Error(NFS4ERR_NOTDIR) filename = op.opopen.claim.file print(" FILE %s" % filename) e = verify_name(filename) if e: raise NFS4Error(e) # At this point we know it is CLAIM_NULL with valid filename and cfh attrset = 0 ci_old = self.curr_fh.fattr4_change if op.opopen.openhow.opentype == OPEN4_CREATE: print(" CREATING FILE.") type_reg = createtype4(NF4REG) existing = self.curr_fh.lookup(filename) if existing is not None: if existing.get_type() == NF4DIR: raise NFS4Error(NFS4ERR_ISDIR) if existing.get_type() == NF4LNK: raise NFS4Error(NFS4ERR_SYMLINK) if existing.get_type() != NF4REG: raise NFS4Error(NFS4ERR_INVAL) if op.opopen.openhow.how.mode == EXCLUSIVE4: if existing is not None: if not existing.match_create_verf(op.opopen.openhow.how.createverf): raise NFS4Error(NFS4ERR_EXIST) # Now break out and use existing as is else: # Create file with no attrs and set verifier attrset = self.curr_fh.create(filename, type_reg) existing = self.curr_fh.lookup(filename) existing.create_verf = op.opopen.openhow.how.createverf else: attrs = op.opopen.openhow.how.createattrs if existing is not None: if op.opopen.openhow.how.mode == GUARDED4: raise NFS4Error(NFS4ERR_EXIST) # with an existing file ignore attrs except size=0 if FATTR4_SIZE in attrs and attrs[FATTR4_SIZE]==0: attrset = existing.set_attributes(attrdict={FATTR4_SIZE:0}) # Now break out and use existing as is else: attrset = self.curr_fh.create(filename, type_reg, attrs) existing = self.curr_fh.lookup(filename) else: print(" OPENING EXISTING FILE.") existing = self.curr_fh.lookup(filename) if existing is None: raise NFS4Error(NFS4ERR_NOENT) if existing.get_type() == NF4DIR: raise NFS4Error(NFS4ERR_ISDIR) if existing.get_type() == NF4LNK: raise NFS4Error(NFS4ERR_SYMLINK) if existing.get_type() != NF4REG: raise NFS4Error(NFS4ERR_INVAL) # 'existing' now points to a valid file, so check and set shares sid, flags = self.state.open(existing, owner, op.opopen.share_access, op.opopen.share_deny) except NFS4Error as e: print("Open error") self.state.advance_seqid(owner, op, (e.code,)) return simple_error(e.code) ci_new = self.curr_fh.fattr4_change cif4 = change_info4(1, ci_old, ci_new) od4 = open_delegation4(delegation_type=OPEN_DELEGATE_NONE) o4rok = OPEN4resok(stateid=sid, cinfo=cif4, rflags=flags, attrset=attrset, delegation=od4) self.curr_fh = self.curr_fh.lookup(filename) self.state.advance_seqid(owner, op, (NFS4_OK, o4rok), self.curr_fh) return simple_error(NFS4_OK, o4rok)