//============================================================================== // Object Input // - Sends input messages and registers movement in a list //============================================================================== void ObjectHandler::objectInput( boost::uint16_t _id, boost::uint16_t _input, bool _pressed ) { ObjectMove obj_move; // Input obj_move.input.key = _input; obj_move.input.pressed = _pressed; // Time obj_move.time = m_network_handler->getServerTime(MILLISECONDS)/1000.0f; // State boost::mutex::scoped_lock state_lock( m_object_state_mutex ); for( unsigned int i = 0; i < m_object_state_list.size(); i++ ) if( m_object_state_list[i].id == _id ) { obj_move.state = m_object_state_list[i]; break; } state_lock.unlock(); // Send m_network_handler->sendMessage( &obj_move, sizeof(obj_move), m_msg_object_move ); // Adds move to history list if correction is initialized. this->addMoveHistory( obj_move ); }
//============================================================================== // Register Object State // - Registers an object state. //============================================================================== void ObjectHandler::registerObjectState( boost::uint16_t _id, boost::uint16_t _settings, float _x, float _y ) { boost::mutex::scoped_lock state_lock( m_object_state_mutex ); ObjectState obj_state; obj_state.id = _id; obj_state.current_x = _x; obj_state.current_y = _y; m_object_state_list.push_back( obj_state ); ObjectData obj_state_data; obj_state_data.settings = _settings; obj_state_data.final_x = _x; obj_state_data.final_y = _y; obj_state_data.update_timer = NULL; m_object_data_list.push_back( obj_state_data ); if( m_network_handler->isServer() ) { m_object_data_list.back().update_timer = new boost::asio::deadline_timer( *m_io_service, boost::posix_time::milliseconds(m_packet_handler->getPacketSetting(_settings)->send_rate_ms) ); m_object_data_list.back().update_timer->async_wait( boost::bind(&ObjectHandler::sendObjectStateMessages, this, _id) ); } }
bool RedChannel::abort() { clear_outgoing_messages(); Lock lock(_action_lock); if (_state == TERMINATED_STATE) { if (_wait_for_threads) { _wait_for_threads = false; _worker->join(); } return true; } _action = QUIT_ACTION; _action_cond.notify_one(); lock.unlock(); RedPeer::disconnect(); _abort_trigger.trigger(); for (;;) { Lock state_lock(_state_lock); if (_state == TERMINATED_STATE) { break; } uint64_t timout = 1000 * 1000 * 100; // 100ms if (!_state_cond.timed_wait(state_lock, timout)) { return false; } } if (_wait_for_threads) { _wait_for_threads = false; _worker->join(); } return true; }
bool SSLSocketImpl::PresentPeerCertificate() { lock_guard<mutex> state_lock(state_mutex_); if (state_ != Socket::CONNECTED && state_ != Socket::CONNECTING) { return false; } X509* xcert = tv_ssl_get_peer_certificate(reinterpret_cast<tv_ssl_t*>(stream_)); if (xcert == NULL) { return false; } X509_free(xcert); return true; }
Error SSLSocketImpl::GetVerifyResult() { lock_guard<mutex> state_lock(state_mutex_); if (state_ != Socket::CONNECTED && state_ != Socket::CONNECTING) { return Error(LNR_ENOTCONN); } int ret = tv_ssl_get_verify_result(reinterpret_cast<tv_ssl_t*>(stream_)); if (ret) { return Error(ret, stream_->ssl_err); } else { return Error(LNR_OK); } }
//============================================================================== // Remove Object State By ID // - Remove the state. //============================================================================== void ObjectHandler::removeObjectStateByID( boost::uint16_t _id ) { boost::mutex::scoped_lock state_lock( m_object_state_mutex ); for( unsigned int i = 0; i < m_object_state_list.size(); i++ ) { if( m_object_state_list[i].id == _id ) { m_object_state_list.erase(m_object_state_list.begin()+i); m_object_data_list.erase(m_object_data_list.begin()+i); break; } } }
//============================================================================== // Get Object State By ID // - Get the state. //============================================================================== ObjectState* ObjectHandler::getObjectStateByID( boost::uint16_t _id ) { boost::mutex::scoped_lock state_lock( m_object_state_mutex ); for( unsigned int i = 0; i < m_object_state_list.size(); i++ ) { if( m_object_state_list[i].id == _id ) { return &m_object_state_list[i]; } } return NULL; }
//============================================================================== // Send Object State Messages (Server-side) // - Send object state updates. //============================================================================== void ObjectHandler::sendObjectStateMessages( boost::uint16_t _id ) { boost::mutex::scoped_lock state_lock( m_object_state_mutex ); for( unsigned int i = 0; i < m_object_state_list.size(); i++ ) { if( m_object_state_list[i].id == _id ) { m_network_handler->sendMessage( &m_object_state_list[i], sizeof(m_object_state_list[i]), m_msg_object_state ); m_object_data_list[i].update_timer->expires_at( m_object_data_list[i].update_timer->expires_at() + boost::posix_time::milliseconds(m_packet_handler->getPacketSetting(m_object_data_list[i].settings)->send_rate_ms) ); m_object_data_list.back().update_timer->async_wait( boost::bind(&ObjectHandler::sendObjectStateMessages, this, _id) ); break; } } }
X509Certificate SSLSocketImpl::GetPeerCertificate() { lock_guard<mutex> state_lock(state_mutex_); if (state_ != Socket::CONNECTED && state_ != Socket::CONNECTING) { throw std::runtime_error("peer certificate does not exist"); } // SSL_get_peer_certificate returns a new X509* object X509* xcert = tv_ssl_get_peer_certificate(reinterpret_cast<tv_ssl_t*>(stream_)); if (xcert == NULL) { throw std::runtime_error("peer certificate does not exist"); } X509Certificate cert(xcert); X509_free(xcert); return cert; }
std::vector<X509Certificate> SSLSocketImpl::GetPeerCertificateChain() { lock_guard<mutex> state_lock(state_mutex_); if (state_ != Socket::CONNECTED && state_ != Socket::CONNECTING) { throw std::runtime_error("peer certificate does not exist"); } // SSL_get_peer_cert_chain returns a X509* array and frees them when onclose STACK_OF(X509*) xcerts = tv_ssl_get_peer_certificate_chain(reinterpret_cast<tv_ssl_t*>(stream_)); if (xcerts == NULL) { throw std::runtime_error("peer certificate does not exist"); } // if we use sk_X509_pop, we can't ref them after std::vector<X509Certificate> certs; for (int i = 0; i < sk_X509_num(xcerts); i++) { certs.push_back(X509Certificate(sk_X509_value(xcerts, i))); // NOTICE: DONOT call X509_free( (X509*)sk_X509_value(xcerts, i) ); } return certs; }
bool IoActor_Closing::isPreClosed_subscribe (CallbackDesc<PreClosedCallback> const *cb, unsigned long flags, Ref<GenericInformer::Subscription> *ret_sbn) { if (ret_sbn != NULL) *ret_sbn = NULL; { MutexLock state_lock (state_mutex); if (pre_closed) return true; if (cb != NULL) { if (ret_sbn != NULL) *ret_sbn = getPreClosedInformer ()->subscribe (*cb, flags); else getPreClosedInformer ()->subscribe (*cb, flags); } } return false; }
int nfs4_op_lock(struct nfs_argop4 *op, compound_data_t * data, struct nfs_resop4 *resp) { char __attribute__ ((__unused__)) funcname[] = "nfs4_op_lock"; #ifndef _WITH_NFSV4_LOCKS /* Lock are not supported */ resp->resop = NFS4_OP_LOCK; res_LOCK4.status = NFS4ERR_LOCK_NOTSUPP; return res_LOCK4.status; #else state_status_t state_status; state_data_t candidate_data; state_type_t candidate_type; int rc = 0; seqid4 seqid; state_t * plock_state; /* state for the lock */ state_t * pstate_open; /* state for the open owner */ state_owner_t * plock_owner; state_owner_t * popen_owner; state_owner_t * presp_owner; /* Owner to store response in */ state_owner_t * conflict_owner = NULL; state_nfs4_owner_name_t owner_name; nfs_client_id_t nfs_client_id; state_lock_desc_t lock_desc, conflict_desc; state_blocking_t blocking = STATE_NON_BLOCKING; const char * tag = "LOCK"; LogDebug(COMPONENT_NFS_V4_LOCK, "Entering NFS v4 LOCK handler -----------------------------------------------------"); /* Initialize to sane starting values */ resp->resop = NFS4_OP_LOCK; /* If there is no FH */ if(nfs4_Is_Fh_Empty(&(data->currentFH))) { res_LOCK4.status = NFS4ERR_NOFILEHANDLE; LogDebug(COMPONENT_NFS_V4_LOCK, "LOCK failed nfs4_Is_Fh_Empty"); return res_LOCK4.status; } /* If the filehandle is invalid */ if(nfs4_Is_Fh_Invalid(&(data->currentFH))) { res_LOCK4.status = NFS4ERR_BADHANDLE; LogDebug(COMPONENT_NFS_V4_LOCK, "LOCK failed nfs4_Is_Fh_Invalid"); return res_LOCK4.status; } /* Tests if the Filehandle is expired (for volatile filehandle) */ if(nfs4_Is_Fh_Expired(&(data->currentFH))) { res_LOCK4.status = NFS4ERR_FHEXPIRED; LogDebug(COMPONENT_NFS_V4_LOCK, "LOCK failed nfs4_Is_Fh_Expired"); return res_LOCK4.status; } /* Lock is done only on a file */ if(data->current_filetype != REGULAR_FILE) { /* Type of the entry is not correct */ switch (data->current_filetype) { case DIRECTORY: res_LOCK4.status = NFS4ERR_ISDIR; break; default: res_LOCK4.status = NFS4ERR_INVAL; break; } LogDebug(COMPONENT_NFS_V4_LOCK, "LOCK failed wrong file type"); return res_LOCK4.status; } /* Convert lock parameters to internal types */ switch(arg_LOCK4.locktype) { case READ_LT: lock_desc.sld_type = STATE_LOCK_R; blocking = STATE_NON_BLOCKING; break; case WRITE_LT: lock_desc.sld_type = STATE_LOCK_W; blocking = STATE_NON_BLOCKING; break; case READW_LT: lock_desc.sld_type = STATE_LOCK_R; blocking = STATE_NFSV4_BLOCKING; break; case WRITEW_LT: lock_desc.sld_type = STATE_LOCK_W; blocking = STATE_NFSV4_BLOCKING; break; } lock_desc.sld_offset = arg_LOCK4.offset; if(arg_LOCK4.length != STATE_LOCK_OFFSET_EOF) lock_desc.sld_length = arg_LOCK4.length; else lock_desc.sld_length = 0; if(arg_LOCK4.locker.new_lock_owner) { /* New lock owner, Find the open owner */ tag = "LOCK (new owner)"; /* Check stateid correctness and get pointer to state */ if((rc = nfs4_Check_Stateid(&arg_LOCK4.locker.locker4_u.open_owner.open_stateid, data->current_entry, 0LL, &pstate_open, data, STATEID_SPECIAL_FOR_LOCK, tag)) != NFS4_OK) { res_LOCK4.status = rc; LogDebug(COMPONENT_NFS_V4_LOCK, "LOCK failed nfs4_Check_Stateid for open owner"); return res_LOCK4.status; } popen_owner = pstate_open->state_powner; plock_state = NULL; plock_owner = NULL; presp_owner = popen_owner; seqid = arg_LOCK4.locker.locker4_u.open_owner.open_seqid; LogLock(COMPONENT_NFS_V4_LOCK, NIV_FULL_DEBUG, "LOCK New lock owner from open owner", data->current_entry, data->pcontext, popen_owner, &lock_desc); /* Check is the clientid is known or not */ if(nfs_client_id_get(arg_LOCK4.locker.locker4_u.open_owner.lock_owner.clientid, &nfs_client_id) == CLIENT_ID_NOT_FOUND) { res_LOCK4.status = NFS4ERR_STALE_CLIENTID; LogDebug(COMPONENT_NFS_V4_LOCK, "LOCK failed nfs_client_id_get"); return res_LOCK4.status; } /* The related stateid is already stored in pstate_open */ /* An open state has been found. Check its type */ if(pstate_open->state_type != STATE_TYPE_SHARE) { res_LOCK4.status = NFS4ERR_BAD_STATEID; LogDebug(COMPONENT_NFS_V4_LOCK, "LOCK failed open stateid is not a SHARE"); return res_LOCK4.status; } /* Lock seqid (seqid wanted for new lock) should be 0 (see newpynfs test LOCK8c) */ if(arg_LOCK4.locker.locker4_u.open_owner.lock_seqid != 0) { res_LOCK4.status = NFS4ERR_BAD_SEQID; LogDebug(COMPONENT_NFS_V4_LOCK, "LOCK failed new lock stateid is not 0"); return res_LOCK4.status; } /* Is this lock_owner known ? */ convert_nfs4_lock_owner(&arg_LOCK4.locker.locker4_u.open_owner.lock_owner, &owner_name); } else { /* Existing lock owner * Find the lock stateid * From that, get the open_owner */ tag = "LOCK (existing owner)"; /* There was code here before to handle all-0 stateid, but that * really doesn't apply - when we handle temporary locks for * I/O operations (which is where we will see all-0 or all-1 * stateid, those will not come in through nfs4_op_lock. */ /* Check stateid correctness and get pointer to state */ if((rc = nfs4_Check_Stateid(&arg_LOCK4.locker.locker4_u.lock_owner.lock_stateid, data->current_entry, 0LL, &plock_state, data, STATEID_SPECIAL_FOR_LOCK, tag)) != NFS4_OK) { res_LOCK4.status = rc; LogDebug(COMPONENT_NFS_V4_LOCK, "LOCK failed nfs4_Check_Stateid for existing lock owner"); return res_LOCK4.status; } /* An lock state has been found. Check its type */ if(plock_state->state_type != STATE_TYPE_LOCK) { res_LOCK4.status = NFS4ERR_BAD_STATEID; LogDebug(COMPONENT_NFS_V4_LOCK, "LOCK failed existing lock owner, state type is not LOCK"); return res_LOCK4.status; } /* Get the old lockowner. We can do the following 'cast', in NFSv4 lock_owner4 and open_owner4 * are different types but with the same definition*/ plock_owner = plock_state->state_powner; popen_owner = plock_owner->so_owner.so_nfs4_owner.so_related_owner; pstate_open = plock_state->state_data.lock.popenstate; presp_owner = plock_owner; seqid = arg_LOCK4.locker.locker4_u.lock_owner.lock_seqid; LogLock(COMPONENT_NFS_V4_LOCK, NIV_FULL_DEBUG, "LOCK Existing lock owner", data->current_entry, data->pcontext, plock_owner, &lock_desc); #ifdef _CONFORM_TO_TEST_LOCK8c /* Check validity of the seqid */ if(arg_LOCK4.locker.locker4_u.lock_owner.lock_seqid != 0) { res_LOCK4.status = NFS4ERR_BAD_SEQID; LogDebug(COMPONENT_NFS_V4_LOCK, "LOCK failed existing lock owner, lock seqid != 0"); return res_LOCK4.status; } #endif } /* if( arg_LOCK4.locker.new_lock_owner ) */ /* Check seqid (lock_seqid or open_seqid) */ if(!Check_nfs4_seqid(presp_owner, seqid, op, data, resp, tag)) { /* Response is all setup for us and LogDebug told what was wrong */ return res_LOCK4.status; } /* Lock length should not be 0 */ if(arg_LOCK4.length == 0LL) { res_LOCK4.status = NFS4ERR_INVAL; LogDebug(COMPONENT_NFS_V4_LOCK, "LOCK failed length == 0"); /* Save the response in the lock or open owner */ Copy_nfs4_state_req(presp_owner, seqid, op, data, resp, tag); return res_LOCK4.status; } /* Check for range overflow. * Comparing beyond 2^64 is not possible int 64 bits precision, * but off+len > 2^64-1 is equivalent to len > 2^64-1 - off */ if(lock_desc.sld_length > (STATE_LOCK_OFFSET_EOF - lock_desc.sld_offset)) { res_LOCK4.status = NFS4ERR_INVAL; LogDebug(COMPONENT_NFS_V4_LOCK, "LOCK failed length overflow"); /* Save the response in the lock or open owner */ Copy_nfs4_state_req(presp_owner, seqid, op, data, resp, tag); return res_LOCK4.status; } /* check if open state has correct access for type of lock. * Don't need to check for conflicting states since this open * state assures there are no conflicting states. */ if(((arg_LOCK4.locktype == WRITE_LT || arg_LOCK4.locktype == WRITEW_LT) && ((pstate_open->state_data.share.share_access & OPEN4_SHARE_ACCESS_WRITE) == 0)) || ((arg_LOCK4.locktype == READ_LT || arg_LOCK4.locktype == READW_LT) && ((pstate_open->state_data.share.share_access & OPEN4_SHARE_ACCESS_READ) == 0))) { /* The open state doesn't allow access based on the type of lock */ LogLock(COMPONENT_NFS_V4_LOCK, NIV_DEBUG, "LOCK failed, SHARE doesn't allow access", data->current_entry, data->pcontext, plock_owner, &lock_desc); res_LOCK4.status = NFS4ERR_OPENMODE; /* Save the response in the lock or open owner */ Copy_nfs4_state_req(presp_owner, seqid, op, data, resp, tag); return res_LOCK4.status; } if(arg_LOCK4.locker.new_lock_owner) { /* A lock owner is always associated with a previously made open * which has itself a previously made stateid */ /* Get reference to open owner */ inc_state_owner_ref(popen_owner); if(nfs4_owner_Get_Pointer(&owner_name, &plock_owner)) { /* Lock owner already existsc, check lock_seqid if it's not 0 */ if(!Check_nfs4_seqid(plock_owner, arg_LOCK4.locker.locker4_u.open_owner.lock_seqid, op, data, resp, "LOCK (new owner but owner exists)")) { /* Response is all setup for us and LogDebug told what was wrong */ return res_LOCK4.status; } } else { /* This lock owner is not known yet, allocated and set up a new one */ plock_owner = create_nfs4_owner(data->pclient, &owner_name, STATE_LOCK_OWNER_NFSV4, popen_owner, 0); if(plock_owner == NULL) { res_LOCK4.status = NFS4ERR_RESOURCE; LogLock(COMPONENT_NFS_V4_LOCK, NIV_DEBUG, "LOCK failed to create new lock owner", data->current_entry, data->pcontext, popen_owner, &lock_desc); return res_LOCK4.status; } } /* Prepare state management structure */ memset(&candidate_type, 0, sizeof(candidate_type)); candidate_type = STATE_TYPE_LOCK; candidate_data.lock.popenstate = pstate_open; /* Add the lock state to the lock table */ if(state_add(data->current_entry, candidate_type, &candidate_data, plock_owner, data->pclient, data->pcontext, &plock_state, &state_status) != STATE_SUCCESS) { res_LOCK4.status = NFS4ERR_RESOURCE; LogLock(COMPONENT_NFS_V4_LOCK, NIV_DEBUG, "LOCK failed to add new stateid", data->current_entry, data->pcontext, plock_owner, &lock_desc); dec_state_owner_ref(plock_owner, data->pclient); return res_LOCK4.status; } init_glist(&plock_state->state_data.lock.state_locklist); /* Add lock state to the list of lock states belonging to the open state */ glist_add_tail(&pstate_open->state_data.share.share_lockstates, &plock_state->state_data.lock.state_sharelist); } /* if( arg_LOCK4.locker.new_lock_owner ) */ /* Now we have a lock owner and a stateid. * Go ahead and push lock into SAL (and FSAL). */ if(state_lock(data->current_entry, data->pcontext, plock_owner, plock_state, blocking, NULL, /* No block data for now */ &lock_desc, &conflict_owner, &conflict_desc, data->pclient, &state_status) != STATE_SUCCESS) { if(state_status == STATE_LOCK_CONFLICT) { /* A conflicting lock from a different lock_owner, returns NFS4ERR_DENIED */ Process_nfs4_conflict(&res_LOCK4.LOCK4res_u.denied, conflict_owner, &conflict_desc, data->pclient); } LogDebug(COMPONENT_NFS_V4_LOCK, "LOCK failed with status %s", state_err_str(state_status)); res_LOCK4.status = nfs4_Errno_state(state_status); /* Save the response in the lock or open owner */ if(res_LOCK4.status != NFS4ERR_RESOURCE && res_LOCK4.status != NFS4ERR_BAD_STATEID) Copy_nfs4_state_req(presp_owner, seqid, op, data, resp, tag); if(arg_LOCK4.locker.new_lock_owner) { /* Need to destroy lock owner and state */ if(state_del(plock_state, data->pclient, &state_status) != STATE_SUCCESS) LogDebug(COMPONENT_NFS_V4_LOCK, "state_del failed with status %s", state_err_str(state_status)); } return res_LOCK4.status; } res_LOCK4.status = NFS4_OK; /* Handle stateid/seqid for success */ update_stateid(plock_state, &res_LOCK4.LOCK4res_u.resok4.lock_stateid, data, tag); LogFullDebug(COMPONENT_NFS_V4_LOCK, "LOCK state_seqid = %u, plock_state = %p", plock_state->state_seqid, plock_state); /* Save the response in the lock or open owner */ Copy_nfs4_state_req(presp_owner, seqid, op, data, resp, tag); LogLock(COMPONENT_NFS_V4_LOCK, NIV_FULL_DEBUG, "LOCK applied", data->current_entry, data->pcontext, plock_owner, &lock_desc); return res_LOCK4.status; #endif } /* nfs4_op_lock */
int nfs4_op_lock(struct nfs_argop4 *op, compound_data_t *data, struct nfs_resop4 *resp) { /* Shorter alias for arguments */ LOCK4args * const arg_LOCK4 = &op->nfs_argop4_u.oplock; /* Shorter alias for response */ LOCK4res * const res_LOCK4 = &resp->nfs_resop4_u.oplock; /* Status code from state calls */ state_status_t state_status = STATE_SUCCESS; /* Data for lock state to be created */ union state_data candidate_data; /* Status code for protocol functions */ nfsstat4 nfs_status = 0; /* Created or found lock state */ state_t *lock_state = NULL; /* Associated open state */ state_t *state_open = NULL; /* The lock owner */ state_owner_t *lock_owner = NULL; /* The open owner */ state_owner_t *open_owner = NULL; /* The owner of a conflicting lock */ state_owner_t *conflict_owner = NULL; /* The owner in which to store the response for NFSv4.0 */ state_owner_t *resp_owner = NULL; /* Sequence ID, for NFSv4.0 */ seqid4 seqid = 0; /* The client performing these operations */ nfs_client_id_t *clientid = NULL; /* Name for the lock owner */ state_nfs4_owner_name_t owner_name; /* Description of requrested lock */ fsal_lock_param_t lock_desc; /* Description of conflicting lock */ fsal_lock_param_t conflict_desc; /* Whether to block */ state_blocking_t blocking = STATE_NON_BLOCKING; /* Tracking data for the lock state */ struct state_refer refer; /* Indicate if we let FSAL to handle requests during grace. */ bool_t fsal_grace = false; int rc; LogDebug(COMPONENT_NFS_V4_LOCK, "Entering NFS v4 LOCK handler ----------------------"); /* Initialize to sane starting values */ resp->resop = NFS4_OP_LOCK; res_LOCK4->status = NFS4_OK; /* Record the sequence info */ if (data->minorversion > 0) { memcpy(refer.session, data->session->session_id, sizeof(sessionid4)); refer.sequence = data->sequence; refer.slot = data->slot; } res_LOCK4->status = nfs4_sanity_check_FH(data, REGULAR_FILE, false); if (res_LOCK4->status != NFS4_OK) return res_LOCK4->status; /* Convert lock parameters to internal types */ switch (arg_LOCK4->locktype) { case READW_LT: blocking = STATE_NFSV4_BLOCKING; /* Fall through */ case READ_LT: lock_desc.lock_type = FSAL_LOCK_R; break; case WRITEW_LT: blocking = STATE_NFSV4_BLOCKING; /* Fall through */ case WRITE_LT: lock_desc.lock_type = FSAL_LOCK_W; break; default: LogDebug(COMPONENT_NFS_V4_LOCK, "Invalid lock type"); res_LOCK4->status = NFS4ERR_INVAL; return res_LOCK4->status; } lock_desc.lock_start = arg_LOCK4->offset; lock_desc.lock_sle_type = FSAL_POSIX_LOCK; lock_desc.lock_reclaim = arg_LOCK4->reclaim; if (arg_LOCK4->length != STATE_LOCK_OFFSET_EOF) lock_desc.lock_length = arg_LOCK4->length; else lock_desc.lock_length = 0; if (arg_LOCK4->locker.new_lock_owner) { /* Check stateid correctness and get pointer to state */ nfs_status = nfs4_Check_Stateid( &arg_LOCK4->locker.locker4_u.open_owner.open_stateid, data->current_obj, &state_open, data, STATEID_SPECIAL_FOR_LOCK, arg_LOCK4->locker.locker4_u.open_owner.open_seqid, data->minorversion == 0, lock_tag); if (nfs_status != NFS4_OK) { if (nfs_status == NFS4ERR_REPLAY) { open_owner = get_state_owner_ref(state_open); LogStateOwner("Open: ", open_owner); if (open_owner != NULL) { resp_owner = open_owner; seqid = arg_LOCK4->locker.locker4_u .open_owner.open_seqid; goto check_seqid; } } res_LOCK4->status = nfs_status; LogDebug(COMPONENT_NFS_V4_LOCK, "LOCK failed nfs4_Check_Stateid for open owner"); return res_LOCK4->status; } open_owner = get_state_owner_ref(state_open); LogStateOwner("Open: ", open_owner); if (open_owner == NULL) { /* State is going stale. */ res_LOCK4->status = NFS4ERR_STALE; LogDebug(COMPONENT_NFS_V4_LOCK, "LOCK failed nfs4_Check_Stateid, stale open owner"); goto out2; } lock_state = NULL; lock_owner = NULL; resp_owner = open_owner; seqid = arg_LOCK4->locker.locker4_u.open_owner.open_seqid; LogLock(COMPONENT_NFS_V4_LOCK, NIV_FULL_DEBUG, "LOCK New lock owner from open owner", data->current_obj, open_owner, &lock_desc); /* Check is the clientid is known or not */ rc = nfs_client_id_get_confirmed( data->minorversion == 0 ? arg_LOCK4->locker. locker4_u.open_owner.lock_owner.clientid : data->session->clientid, &clientid); if (rc != CLIENT_ID_SUCCESS) { res_LOCK4->status = clientid_error_to_nfsstat(rc); LogDebug(COMPONENT_NFS_V4_LOCK, "LOCK failed nfs_client_id_get"); goto out2; } if (isDebug(COMPONENT_CLIENTID) && (clientid != open_owner->so_owner.so_nfs4_owner.so_clientrec)) { char str_open[LOG_BUFF_LEN / 2]; struct display_buffer dspbuf_open = { sizeof(str_open), str_open, str_open}; char str_lock[LOG_BUFF_LEN / 2]; struct display_buffer dspbuf_lock = { sizeof(str_lock), str_lock, str_lock}; display_client_id_rec(&dspbuf_open, open_owner->so_owner .so_nfs4_owner.so_clientrec); display_client_id_rec(&dspbuf_lock, clientid); LogDebug(COMPONENT_CLIENTID, "Unexpected, new lock owner clientid {%s} doesn't match open owner clientid {%s}", str_lock, str_open); } /* The related stateid is already stored in state_open */ /* An open state has been found. Check its type */ if (state_open->state_type != STATE_TYPE_SHARE) { res_LOCK4->status = NFS4ERR_BAD_STATEID; LogDebug(COMPONENT_NFS_V4_LOCK, "LOCK failed open stateid is not a SHARE"); goto out2; } /* Is this lock_owner known ? */ convert_nfs4_lock_owner(&arg_LOCK4->locker.locker4_u.open_owner. lock_owner, &owner_name); LogStateOwner("Lock: ", lock_owner); } else { /* Existing lock owner Find the lock stateid From * that, get the open_owner * * There was code here before to handle all-0 stateid, * but that really doesn't apply - when we handle * temporary locks for I/O operations (which is where * we will see all-0 or all-1 stateid, those will not * come in through nfs4_op_lock. * * Check stateid correctness and get pointer to state */ nfs_status = nfs4_Check_Stateid( &arg_LOCK4->locker.locker4_u.lock_owner.lock_stateid, data->current_obj, &lock_state, data, STATEID_SPECIAL_FOR_LOCK, arg_LOCK4->locker.locker4_u.lock_owner.lock_seqid, data->minorversion == 0, lock_tag); if (nfs_status != NFS4_OK) { if (nfs_status == NFS4ERR_REPLAY) { lock_owner = get_state_owner_ref(lock_state); LogStateOwner("Lock: ", lock_owner); if (lock_owner != NULL) { open_owner = lock_owner->so_owner .so_nfs4_owner.so_related_owner; inc_state_owner_ref(open_owner); resp_owner = lock_owner; seqid = arg_LOCK4->locker.locker4_u .lock_owner.lock_seqid; goto check_seqid; } } res_LOCK4->status = nfs_status; LogDebug(COMPONENT_NFS_V4_LOCK, "LOCK failed nfs4_Check_Stateid for existing lock owner"); return res_LOCK4->status; } /* Check if lock state belongs to same export */ if (!state_same_export(lock_state, op_ctx->ctx_export)) { LogEvent(COMPONENT_STATE, "Lock Owner Export Conflict, Lock held for export %" PRIu16" request for export %"PRIu16, state_export_id(lock_state), op_ctx->ctx_export->export_id); res_LOCK4->status = NFS4ERR_INVAL; goto out2; } /* A lock state has been found. Check its type */ if (lock_state->state_type != STATE_TYPE_LOCK) { res_LOCK4->status = NFS4ERR_BAD_STATEID; LogDebug(COMPONENT_NFS_V4_LOCK, "LOCK failed existing lock owner, state type is not LOCK"); goto out2; } /* Get the old lockowner. We can do the following * 'cast', in NFSv4 lock_owner4 and open_owner4 are * different types but with the same definition */ lock_owner = get_state_owner_ref(lock_state); LogStateOwner("Lock: ", lock_owner); if (lock_owner == NULL) { /* State is going stale. */ res_LOCK4->status = NFS4ERR_STALE; LogDebug(COMPONENT_NFS_V4_LOCK, "LOCK failed nfs4_Check_Stateid, stale open owner"); goto out2; } open_owner = lock_owner->so_owner.so_nfs4_owner.so_related_owner; LogStateOwner("Open: ", open_owner); inc_state_owner_ref(open_owner); state_open = lock_state->state_data.lock.openstate; inc_state_t_ref(state_open); resp_owner = lock_owner; seqid = arg_LOCK4->locker.locker4_u.lock_owner.lock_seqid; LogLock(COMPONENT_NFS_V4_LOCK, NIV_FULL_DEBUG, "LOCK Existing lock owner", data->current_obj, lock_owner, &lock_desc); /* Get the client for this open owner */ clientid = open_owner->so_owner.so_nfs4_owner.so_clientrec; inc_client_id_ref(clientid); } check_seqid: /* Check seqid (lock_seqid or open_seqid) */ if (data->minorversion == 0) { if (!Check_nfs4_seqid(resp_owner, seqid, op, data->current_obj, resp, lock_tag)) { /* Response is all setup for us and LogDebug * told what was wrong */ goto out2; } } /* Lock length should not be 0 */ if (arg_LOCK4->length == 0LL) { res_LOCK4->status = NFS4ERR_INVAL; LogDebug(COMPONENT_NFS_V4_LOCK, "LOCK failed length == 0"); goto out; } /* Check for range overflow. Comparing beyond 2^64 is not * possible int 64 bits precision, but off+len > 2^64-1 is * equivalent to len > 2^64-1 - off */ if (lock_desc.lock_length > (STATE_LOCK_OFFSET_EOF - lock_desc.lock_start)) { res_LOCK4->status = NFS4ERR_INVAL; LogDebug(COMPONENT_NFS_V4_LOCK, "LOCK failed length overflow"); goto out; } /* Check if open state has correct access for type of lock. * * Don't need to check for conflicting states since this open * state assures there are no conflicting states. */ if (((arg_LOCK4->locktype == WRITE_LT || arg_LOCK4->locktype == WRITEW_LT) && ((state_open->state_data.share.share_access & OPEN4_SHARE_ACCESS_WRITE) == 0)) || ((arg_LOCK4->locktype == READ_LT || arg_LOCK4->locktype == READW_LT) && ((state_open->state_data.share.share_access & OPEN4_SHARE_ACCESS_READ) == 0))) { /* The open state doesn't allow access based on the * type of lock */ LogLock(COMPONENT_NFS_V4_LOCK, NIV_DEBUG, "LOCK failed, SHARE doesn't allow access", data->current_obj, lock_owner, &lock_desc); res_LOCK4->status = NFS4ERR_OPENMODE; goto out; } /* Do grace period checking (use resp_owner below since a new * lock request with a new lock owner doesn't have a lock owner * yet, but does have an open owner - resp_owner is always one or * the other and non-NULL at this point - so makes for a better log). */ if (nfs_in_grace()) { if (op_ctx->fsal_export->exp_ops. fs_supports(op_ctx->fsal_export, fso_grace_method)) fsal_grace = true; if (!fsal_grace && !arg_LOCK4->reclaim) { LogLock(COMPONENT_NFS_V4_LOCK, NIV_DEBUG, "LOCK failed, non-reclaim while in grace", data->current_obj, resp_owner, &lock_desc); res_LOCK4->status = NFS4ERR_GRACE; goto out; } if (!fsal_grace && arg_LOCK4->reclaim && !clientid->cid_allow_reclaim) { LogLock(COMPONENT_NFS_V4_LOCK, NIV_DEBUG, "LOCK failed, invalid reclaim while in grace", data->current_obj, resp_owner, &lock_desc); res_LOCK4->status = NFS4ERR_NO_GRACE; goto out; } } else { if (arg_LOCK4->reclaim) { LogLock(COMPONENT_NFS_V4_LOCK, NIV_DEBUG, "LOCK failed, reclaim while not in grace", data->current_obj, resp_owner, &lock_desc); res_LOCK4->status = NFS4ERR_NO_GRACE; goto out; } } /* Test if this request is attempting to create a new lock owner */ if (arg_LOCK4->locker.new_lock_owner) { bool_t isnew; /* A lock owner is always associated with a previously made open which has itself a previously made stateid */ /* This lock owner is not known yet, allocated and set up a new one */ lock_owner = create_nfs4_owner(&owner_name, clientid, STATE_LOCK_OWNER_NFSV4, open_owner, 0, &isnew, CARE_ALWAYS); LogStateOwner("Lock: ", lock_owner); if (lock_owner == NULL) { res_LOCK4->status = NFS4ERR_RESOURCE; LogLock(COMPONENT_NFS_V4_LOCK, NIV_EVENT, "LOCK failed to create new lock owner", data->current_obj, open_owner, &lock_desc); goto out2; } if (!isnew) { PTHREAD_MUTEX_lock(&lock_owner->so_mutex); /* Check lock_seqid if it has attached locks. */ if (!glist_empty(&lock_owner->so_lock_list) && (data->minorversion == 0) && !Check_nfs4_seqid(lock_owner, arg_LOCK4->locker.locker4_u. open_owner.lock_seqid, op, data->current_obj, resp, lock_tag)) { LogLock(COMPONENT_NFS_V4_LOCK, NIV_DEBUG, "LOCK failed to create new lock owner, re-use", data->current_obj, open_owner, &lock_desc); dump_all_locks( "All locks (re-use of lock owner)"); PTHREAD_MUTEX_unlock(&lock_owner->so_mutex); /* Response is all setup for us and * LogDebug told what was wrong */ goto out2; } PTHREAD_MUTEX_unlock(&lock_owner->so_mutex); /* Lock owner is known, see if we also already have * a stateid. Do this here since it's impossible for * there to be such a state if the lock owner was * previously unknown. */ lock_state = nfs4_State_Get_Obj(data->current_obj, lock_owner); } if (lock_state == NULL) { /* Prepare state management structure */ memset(&candidate_data, 0, sizeof(candidate_data)); candidate_data.lock.openstate = state_open; /* Add the lock state to the lock table */ state_status = state_add(data->current_obj, STATE_TYPE_LOCK, &candidate_data, lock_owner, &lock_state, data->minorversion > 0 ? &refer : NULL); if (state_status != STATE_SUCCESS) { res_LOCK4->status = NFS4ERR_RESOURCE; LogLock(COMPONENT_NFS_V4_LOCK, NIV_DEBUG, "LOCK failed to add new stateid", data->current_obj, lock_owner, &lock_desc); goto out2; } glist_init(&lock_state->state_data.lock.state_locklist); /* Add lock state to the list of lock states belonging to the open state */ glist_add_tail( &state_open->state_data.share.share_lockstates, &lock_state->state_data.lock.state_sharelist); } } if (data->minorversion == 0) { op_ctx->clientid = &lock_owner->so_owner.so_nfs4_owner.so_clientid; } /* Now we have a lock owner and a stateid. Go ahead and push * lock into SAL (and FSAL). */ state_status = state_lock(data->current_obj, lock_owner, lock_state, blocking, NULL, /* No block data for now */ &lock_desc, &conflict_owner, &conflict_desc); if (state_status != STATE_SUCCESS) { if (state_status == STATE_LOCK_CONFLICT) { /* A conflicting lock from a different lock_owner, returns NFS4ERR_DENIED */ Process_nfs4_conflict(&res_LOCK4->LOCK4res_u.denied, conflict_owner, &conflict_desc); } LogDebug(COMPONENT_NFS_V4_LOCK, "LOCK failed with status %s", state_err_str(state_status)); res_LOCK4->status = nfs4_Errno_state(state_status); /* Save the response in the lock or open owner */ if (res_LOCK4->status != NFS4ERR_RESOURCE && res_LOCK4->status != NFS4ERR_BAD_STATEID && data->minorversion == 0) { Copy_nfs4_state_req(resp_owner, seqid, op, data->current_obj, resp, lock_tag); } if (arg_LOCK4->locker.new_lock_owner) { /* Need to destroy new state */ state_del(lock_state); } goto out2; } if (data->minorversion == 0) op_ctx->clientid = NULL; res_LOCK4->status = NFS4_OK; /* Handle stateid/seqid for success */ update_stateid(lock_state, &res_LOCK4->LOCK4res_u.resok4.lock_stateid, data, lock_tag); if (arg_LOCK4->locker.new_lock_owner) { /* Also save the response in the lock owner */ Copy_nfs4_state_req(lock_owner, arg_LOCK4->locker.locker4_u.open_owner. lock_seqid, op, data->current_obj, resp, lock_tag); } if (isFullDebug(COMPONENT_NFS_V4_LOCK)) { char str[LOG_BUFF_LEN]; struct display_buffer dspbuf = {sizeof(str), str, str}; display_stateid(&dspbuf, lock_state); LogFullDebug(COMPONENT_NFS_V4_LOCK, "LOCK stateid %s", str); } LogLock(COMPONENT_NFS_V4_LOCK, NIV_FULL_DEBUG, "LOCK applied", data->current_obj, lock_owner, &lock_desc); out: if (data->minorversion == 0) { /* Save the response in the lock or open owner */ Copy_nfs4_state_req(resp_owner, seqid, op, data->current_obj, resp, lock_tag); } out2: if (state_open != NULL) dec_state_t_ref(state_open); if (lock_state != NULL) dec_state_t_ref(lock_state); LogStateOwner("Open: ", open_owner); LogStateOwner("Lock: ", lock_owner); if (open_owner != NULL) dec_state_owner_ref(open_owner); if (lock_owner != NULL) dec_state_owner_ref(lock_owner); if (clientid != NULL) dec_client_id_ref(clientid); return res_LOCK4->status; } /* nfs4_op_lock */
int state_store(state *s, int remove) { cfg_t *cfg = cfg_get(); int locked = 0; int ret = 1; assert(!(s->new_key && remove)); if (s->new_key == 1) { /* State musn't be locked already! */ assert(s->lock <= 0); if (s->lock > 0) return STATE_LOCK_ERROR; /* Lock state for this write exclusively */ ret = state_lock(s); if (ret != 0) { print(PRINT_ERROR, "Unable to lock file for writing!\n"); return STATE_LOCK_ERROR; } locked = 1; } if (s->lock <= 0) { print(PRINT_ERROR, "Trying to save state data into DB " "without previously locked DB.\n"); return 2; } s->new_key = 0; switch (cfg->db) { case CONFIG_DB_USER: case CONFIG_DB_GLOBAL: ret = db_file_store(s, remove); break; /* case CONFIG_DB_MYSQL: ret = db_mysql_store(s, remove); break; case CONFIG_DB_LDAP: ret = db_ldap_store(s, remove); break; */ default: assert(0); ret = 1; break; } if (locked) { /* Unlock recently locked state */ if (state_unlock(s) != 0) { print(PRINT_WARN, "Strange error while unlocking the file"); } } return ret; }
//============================================================================== // Update Object State By ID // - Feed with new data. //============================================================================== void ObjectHandler::updateObjectStateByID( boost::uint16_t _id, float& _x, float& _y ) { boost::mutex::scoped_lock state_lock( m_object_state_mutex ); float diff_x, diff_y, distance; for( unsigned int i = 0; i < m_object_state_list.size(); i++ ) { if( m_object_state_list[i].id == _id/* && !(m_correction_id == _id && m_correction)*/ ) { // TEST //if( m_correction_id == _id && m_correction ) //{ // //m_object_data_list[i].final_x += _x - m_object_state_list[i].current_x; // //m_object_data_list[i].final_y += _y - m_object_state_list[i].current_y; // diff_x = _x - m_object_state_list[i].current_x; // diff_y = _y - m_object_state_list[i].current_y; // distance = sqrt( pow(diff_x,2) + pow(diff_y,2) ); // if( distance > MAX_INTERPOLATION_DISTANCE ) // { // m_object_state_list[i].current_x = m_object_data_list[i].final_x; // m_object_state_list[i].current_y = m_object_data_list[i].final_y; // } // else if( distance > MIN_INTERPOLATION_DISTANCE ) // { // m_object_state_list[i].current_x += diff_x*INTERPOLATION_SPEED; // m_object_state_list[i].current_y += diff_y*INTERPOLATION_SPEED; // } // //diff_x = m_object_data_list[i].final_x - _x; // //diff_y = m_object_data_list[i].final_y - _y; // //distance = sqrt( pow(diff_x,2) + pow(diff_y,2) ); // //if( distance > MAX_INTERPOLATION_DISTANCE ) // //{ // // m_object_state_list[i].current_x = m_object_data_list[i].final_x; // // m_object_state_list[i].current_y = m_object_data_list[i].final_y; // //} // //else if( distance > MIN_INTERPOLATION_DISTANCE ) // //{ // // m_object_state_list[i].current_x += diff_x*INTERPOLATION_SPEED; // // m_object_state_list[i].current_y += diff_y*INTERPOLATION_SPEED; // //} // _x = m_object_state_list[i].current_x; // _y = m_object_state_list[i].current_y; // //_x = m_object_data_list[i].final_x; // //_y = m_object_data_list[i].final_y; // return; //} // TEST END m_object_data_list[i].final_x += _x - m_object_state_list[i].current_x; m_object_data_list[i].final_y += _y - m_object_state_list[i].current_y; m_object_state_list[i].current_x = _x; m_object_state_list[i].current_y = _y; diff_x = m_object_data_list[i].final_x -_x; diff_y = m_object_data_list[i].final_y -_y; distance = sqrt( pow(diff_x,2) + pow(diff_y,2) ); if( distance > MAX_INTERPOLATION_DISTANCE ) { m_object_state_list[i].current_x = m_object_data_list[i].final_x; m_object_state_list[i].current_y = m_object_data_list[i].final_y; } else if( distance > MIN_INTERPOLATION_DISTANCE ) { m_object_state_list[i].current_x += diff_x*INTERPOLATION_SPEED; m_object_state_list[i].current_y += diff_x*INTERPOLATION_SPEED; } _x = m_object_state_list[i].current_x; _y = m_object_state_list[i].current_y; return; } } }
int nlm4_Lock(nfs_arg_t * parg /* IN */ , exportlist_t * pexport /* IN */ , fsal_op_context_t * pcontext /* IN */ , cache_inode_client_t * pclient /* INOUT */ , hash_table_t * ht /* INOUT */ , struct svc_req * preq /* IN */ , nfs_res_t * pres /* OUT */ ) { nlm4_lockargs * arg = &parg->arg_nlm4_lock; cache_entry_t * pentry; state_status_t state_status = CACHE_INODE_SUCCESS; char buffer[MAXNETOBJ_SZ * 2]; state_nsm_client_t * nsm_client; state_nlm_client_t * nlm_client; state_owner_t * nlm_owner, * holder; state_lock_desc_t lock, conflict; int rc; state_block_data_t * pblock_data; netobj_to_string(&arg->cookie, buffer, 1024); LogDebug(COMPONENT_NLM, "REQUEST PROCESSING: Calling nlm4_Lock svid=%d off=%llx len=%llx cookie=%s", (int) arg->alock.svid, (unsigned long long) arg->alock.l_offset, (unsigned long long) arg->alock.l_len, buffer); if(!copy_netobj(&pres->res_nlm4test.cookie, &arg->cookie)) { pres->res_nlm4.stat.stat = NLM4_FAILED; LogDebug(COMPONENT_NLM, "REQUEST RESULT: nlm4_Test %s", lock_result_str(pres->res_nlm4.stat.stat)); return NFS_REQ_OK; } /* allow only reclaim lock request during recovery */ if(in_nlm_grace_period() && !arg->reclaim) { pres->res_nlm4.stat.stat = NLM4_DENIED_GRACE_PERIOD; LogDebug(COMPONENT_NLM, "REQUEST RESULT: nlm4_Lock %s", lock_result_str(pres->res_nlm4.stat.stat)); return NFS_REQ_OK; } if(!in_nlm_grace_period() && arg->reclaim) { pres->res_nlm4.stat.stat = NLM4_DENIED_GRACE_PERIOD; LogDebug(COMPONENT_NLM, "REQUEST RESULT: nlm4_Lock %s", lock_result_str(pres->res_nlm4.stat.stat)); return NFS_REQ_OK; } rc = nlm_process_parameters(preq, arg->exclusive, &arg->alock, &lock, ht, &pentry, pcontext, pclient, CARE_MONITOR, &nsm_client, &nlm_client, &nlm_owner, &pblock_data); if(rc >= 0) { /* Present the error back to the client */ pres->res_nlm4.stat.stat = (nlm4_stats)rc; LogDebug(COMPONENT_NLM, "REQUEST RESULT: nlm4_Unlock %s", lock_result_str(pres->res_nlm4.stat.stat)); return NFS_REQ_OK; } /* Cast the state number into a state pointer to protect * locks from a client that has rebooted from the SM_NOTIFY * that will release old locks */ if(state_lock(pentry, pcontext, nlm_owner, (void *) (ptrdiff_t) arg->state, arg->block, pblock_data, &lock, &holder, &conflict, pclient, &state_status) != STATE_SUCCESS) { pres->res_nlm4test.test_stat.stat = nlm_convert_state_error(state_status); if(state_status == STATE_LOCK_CONFLICT) { nlm_process_conflict(&pres->res_nlm4test.test_stat.nlm4_testrply_u.holder, holder, &conflict, pclient); } /* If we didn't block, release the block data */ if(state_status != STATE_LOCK_BLOCKED && pblock_data != NULL) Mem_Free(pblock_data); } else { pres->res_nlm4.stat.stat = NLM4_GRANTED; } /* Release the NLM Client and NLM Owner references we have */ dec_nsm_client_ref(nsm_client); dec_nlm_client_ref(nlm_client); dec_state_owner_ref(nlm_owner, pclient); LogDebug(COMPONENT_NLM, "REQUEST RESULT: nlm4_Lock %s", lock_result_str(pres->res_nlm4.stat.stat)); return NFS_REQ_OK; }