void PowerTray::monitorLid() { bool do_suspend = false; QStringList lids; lids << "/proc/acpi/button/lid/LID/state" << "/proc/acpi/button/lid/LID0/state"; for (int i = 0; i < lids.size(); ++i) { QFile lid(lids.at(i)); if (lid.exists()) { if (lid.open(QIODevice::ReadOnly)) { QString line; QTextStream textStream(&lid); line = textStream.readAll().simplified(); if (line == "state: closed") { do_suspend = true; } lid.close(); } } } if (do_suspend) { QDBusConnection conn = QDBusConnection::systemBus(); QDBusInterface computer("org.freedesktop.Hal","/org/freedesktop/Hal/devices/computer","org.freedesktop.Hal.Device.SystemPowerManagement",conn); computer.call("Suspend",1); } QTimer::singleShot(1000,this,SLOT(monitorLid())); // loop }
/****************************************************************************************** * @brief sendAlarm * * purpose: send a trap and log the process information * ******************************************************************************************/ void ServerMonitor::sendAlarm(string alarmItem, ALARMS alarmID, int action, float sensorValue) { ServerMonitor serverMonitor; Oam oam; //Log this event LoggingID lid(SERVER_MONITOR_LOG_ID); MessageLog ml(lid); Message msg; Message::Args args; args.add(alarmItem); args.add(", sensor value out-of-range: "); args.add(sensorValue); // get current server name string moduleName; oamModuleInfo_t st; try { st = oam.getModuleInfo(); moduleName = boost::get<0>(st); } catch (...) { moduleName = "Unknown Server"; } // check if there is an active alarm above the reporting theshold // that needs to be cleared serverMonitor.checkAlarm(alarmItem, alarmID); // check if Alarm is already active, don't resend if ( !( oam.checkActiveAlarm(alarmID, moduleName, alarmItem)) ) { SNMPManager alarmMgr; // send alarm alarmMgr.sendAlarmReport(alarmItem.c_str(), alarmID, action); args.add(", Alarm set: "); args.add(alarmID); } // output log msg.format(args); ml.logWarningMessage(msg); return; }
/****************************************************************************************** * @brief clearAlarm * * purpose: clear Alarm that was previously set * ******************************************************************************************/ void ServerMonitor::clearAlarm(string alarmItem, ALARMS alarmID) { SNMPManager alarmMgr; alarmMgr.sendAlarmReport(alarmItem.c_str(), alarmID, CLEAR); //Log this event LoggingID lid(SERVER_MONITOR_LOG_ID); MessageLog ml(lid); Message msg; Message::Args args; args.add(alarmItem); args.add(" alarm #"); args.add(alarmID); args.add("cleared"); msg.format(args); ml.logWarningMessage(msg); }
Chunk::Chunk(uint32_t id, const void * buffer, size_t len, bool skipcrc) : _id(id), _nextOffset(0), _lastSerial(static_cast<uint64_t>(-1l)), _format(ChunkFormat::deserialize(buffer, len, skipcrc)) { vespalib::nbostream &os = getData(); while (os.size() > sizeof(_lastSerial)) { uint32_t sz(0); uint32_t lid(0); ssize_t oldRp(os.rp()); os >> lid >> sz; os.adjustReadPos(sz); _lids.push_back(Entry(lid, sz, oldRp)); } os >> _lastSerial; }
Controller::ledid Controller::getPortPinFromString(const QString& channel) const { Controller::ledid lid(-1,0); if (channel.size()<3) { qWarning() << m_plugin->pluginid() << "getPortPinFromChannel failed. Right syntax: e.g. A:0 or 2:7" << channel; return lid; } char port = channel[0].toAscii(); lid.pin = channel[2].toAscii()-'0'; switch (port) { case 'A': case '0': lid.port = 0; break; case 'B': case '1': lid.port = 1; break; case 'C': case '2': lid.port = 2; break; case 'D': case '3': lid.port = 3; break; case 'E': case '4': lid.port = 4; break; case 'F': case '5': lid.port = 5; break; default: lid.port = 250; } if (lid.port == 250 || lid.pin >= 8) { qWarning() << m_plugin->pluginid() << "getPortPinFromChannel failed. Port range (A-F) or Pin range (0-7) wrong!" << channel; } return lid; }
/****************************************************************************************** * @brief sendResourceAlarm * * purpose: send a trap and log the process information * ******************************************************************************************/ bool ServerMonitor::sendResourceAlarm(string alarmItem, ALARMS alarmID, int action, int usage) { ServerMonitor serverMonitor; Oam oam; //Log this event LoggingID lid(SERVER_MONITOR_LOG_ID); MessageLog ml(lid); Message msg; Message::Args args; args.add(alarmItem); args.add(" usage at percentage of "); args.add(usage); // get current module name string moduleName; oamModuleInfo_t st; try { st = oam.getModuleInfo(); moduleName = boost::get<0>(st); } catch (...) { moduleName = "Unknown Server"; } // check if there is an active alarm above the reporting theshold // that needs to be cleared if (alarmItem == "CPU") serverMonitor.checkCPUAlarm(alarmItem, alarmID); else if (alarmItem == "Local Disk" || alarmItem == "External") serverMonitor.checkDiskAlarm(alarmItem, alarmID); else if (alarmItem == "Local Memory") serverMonitor.checkMemoryAlarm(alarmItem, alarmID); else if (alarmItem == "Local Swap") serverMonitor.checkSwapAlarm(alarmItem, alarmID); // don't issue an alarm on thge dbroots is already issued by this or another server if ( alarmItem.find(startup::StartUp::installDir() + "/data") == 0 ) { // check if Alarm is already active from any module, don't resend if ( !( oam.checkActiveAlarm(alarmID, "*", alarmItem)) ) { SNMPManager alarmMgr; // send alarm alarmMgr.sendAlarmReport(alarmItem.c_str(), alarmID, action); args.add(", Alarm set: "); args.add(alarmID); msg.format(args); ml.logInfoMessage(msg); return true; } else return false; } else { // check if Alarm is already active from this module, don't resend if ( !( oam.checkActiveAlarm(alarmID, moduleName, alarmItem)) ) { SNMPManager alarmMgr; // send alarm alarmMgr.sendAlarmReport(alarmItem.c_str(), alarmID, action); args.add(", Alarm set: "); args.add(alarmID); msg.format(args); ml.logInfoMessage(msg); return true; } else return false; } return true; }
//! Returns true if the GID passed in belongs to the calling processor in this map, otherwise returns false. bool myGID( size_type GID ) const { return( lid( GID )!=invalid_size_type_value ); }
//------------------------------------------------------------------------------ // Main entry point to this program //------------------------------------------------------------------------------ int main(int argc, char** argv) { int c; bool clearLockOnly = false; bool rollbackOnly = false; uint32_t tableOID = 0; while ((c = getopt(argc, argv, "hlr:")) != EOF) { switch (c) { case 'l': clearLockOnly = true; break; //Only allow '-r' option for development/debugging #if 1 case 'r': // hidden option to rollback specified table w/o a lock rollbackOnly = true; tableOID = ::strtoull(optarg, 0, 10); break; #endif case 'h': case '?': default: usage(); return (c == 'h' ? 0 : 1); break; } } if ((argc - optind) != 1 ) { usage(); return 1; } // Get the table lock ID specified by the user uint64_t lockID = ::strtoull(argv[optind], 0, 10); // If user specified both clearlock and rollback then we need to do both if (clearLockOnly && rollbackOnly) { clearLockOnly = false; rollbackOnly = false; } //-------------------------------------------------------------------------- // Verify that BRM is up and in a read/write state //-------------------------------------------------------------------------- BRM::DBRM brm; int brmRc = brm.isReadWrite(); if (brmRc != BRM::ERR_OK) { std::string brmErrMsg; BRM::errString(brmRc, brmErrMsg); std::cout << "BRM error: " << brmErrMsg << std::endl; std::cout << "Table lock " << lockID << " is not cleared." << std::endl; return 1; } if (brm.getSystemReady() < 1) { std::cout << "System is not ready. Verify that EryDB " "is up and ready before running this program" << std::endl; return 1; } //-------------------------------------------------------------------------- //@Bug 3711 Check whether the table is locked; does the table lock exist. //-------------------------------------------------------------------------- execplan::erydbSystemCatalog::TableName tblName; BRM::TableLockInfo tInfo; std::string task; std::vector<uint32_t> pmList; int rc; const std::string taskSysCat("getting system catalog information"); try { if (rollbackOnly) { tInfo.id = lockID; tInfo.tableOID = tableOID; tInfo.ownerPID = 0; tInfo.ownerSessionID = 1; tInfo.state = BRM::LOADING; // Construct PM list using all PMs, since we don't have a table // lock with the list of applicable DBRoots. task = "constructing total PM list"; rc = constructPMList( pmList ); if (rc != 0) { return 1; } } else { task = "getting table lock"; bool lockExists = brm.getTableLockInfo( lockID, &tInfo ); if (!lockExists) { std::cout << "Table lock " << lockID << " does not exist." << std::endl; return 1; } // Construct PM list based on list of affected DBRoots task = "mapping DBRoots to PMs"; rc = constructPMList( tInfo.dbrootList, pmList ); if (rc != 0) { return 1; } } uint32_t sessionID = 1; task = taskSysCat; boost::shared_ptr<execplan::erydbSystemCatalog> systemCatalogPtr = execplan::erydbSystemCatalog::makeerydbSystemCatalog( sessionID ); systemCatalogPtr->identity(execplan::erydbSystemCatalog::EC); tblName = systemCatalogPtr->tableName( tInfo.tableOID ); } catch (std::exception& ex) { std::cout << "Error " << task << ". " << ex.what() << std::endl; if (clearLockOnly && (task == taskSysCat)) { tblName.schema= "[unknown name]"; tblName.table.clear(); std::cout << "Will still try to clear table lock." << std::endl; } else { std::cout << "Table lock " << lockID << " is not cleared." << std::endl; return 1; } } catch (...) { std::cout << "Error " << task << ". " << std::endl; if (clearLockOnly && (task == taskSysCat)) { tblName.schema= "[unknown name]"; tblName.table.clear(); std::cout << "Will still try to clear table lock." << std::endl; } else { std::cout << "Table lock " << lockID << " is not cleared." << std::endl; return 1; } } logInitStatus( tblName.toString(), lockID ); if (rollbackOnly) { std::cout << "Rolling back table " << tblName.toString() << std::endl << std::endl; } else if (clearLockOnly) { std::cout << "Clearing table lock " << lockID << " for table " << tblName.toString() << std::endl << std::endl; } else { std::cout << "Rolling back and clearing table lock for table " << tblName.toString() << "; table lock " << lockID << std::endl << std::endl; } //-------------------------------------------------------------------------- // Perform bulk rollback //-------------------------------------------------------------------------- std::string errMsg; if (!clearLockOnly) { std::vector<boost::shared_ptr<messageqcpp::MessageQueueClient> > msgQueClts; rc = createMsgQueClts(pmList, msgQueClts, errMsg); if (rc != 0) { logFinalStatus( tblName.toString(), lockID, errMsg ); std::cout << errMsg << std::endl; std::cout << "Table lock " << lockID << " for table " << tblName.toString() << " is not cleared." << std::endl; return rc; } rc = execBulkRollbackReq( msgQueClts, pmList, &brm, tInfo, tblName.toString(), rollbackOnly, errMsg ); if (rc != 0) { logFinalStatus( tblName.toString(), lockID, errMsg ); std::cout << "Rollback error: " << errMsg << std::endl; std::cout << "Table lock " << lockID << " for table " << tblName.toString() << " is not cleared." << std::endl; return rc; } //---------------------------------------------------------------------- // Change the state of the table lock to cleanup state. // We ignore the return stateChange flag. //---------------------------------------------------------------------- if (!rollbackOnly) { try { brm.changeState( tInfo.id, BRM::CLEANUP ); } catch (std::exception& ex) { std::ostringstream oss; oss << "Error changing state. " << ex.what(); logFinalStatus( tblName.toString(), lockID, oss.str() ); std::cout << oss.str() << std::endl; std::cout << "Table lock " << lockID << " is not cleared." << std::endl; return 1; } catch (...) { std::ostringstream oss; oss << "Error changing state. " << std::endl; logFinalStatus( tblName.toString(), lockID, oss.str() ); std::cout << oss.str() << std::endl; std::cout << "Table lock " << lockID << " is not cleared." << std::endl; return 1; } } //---------------------------------------------------------------------- // Delete the meta data files //---------------------------------------------------------------------- rc = execFileCleanupReq( msgQueClts, pmList, &brm, tInfo, tblName.toString(), errMsg ); if (rc != 0) { //@Bug 4517. Release tablelock if remove meta files failed const std::string APPLNAME("cleartablelock command"); const int SUBSYSTEM_ID = 19; // writeengine? const int COMP_MSG_NUM = logging::M0089; logging::Message::Args msgArgs; logging::Message logMsg( COMP_MSG_NUM ); msgArgs.add( APPLNAME ); msgArgs.add( tblName.toString() ); msgArgs.add( lockID ); msgArgs.add( errMsg ); logMsg.format( msgArgs ); logging::LoggingID lid( SUBSYSTEM_ID ); logging::MessageLog ml( lid ); ml.logWarningMessage( logMsg ); std::cout << "File cleanup error: " << errMsg << std::endl; } } // end of: if (!clearLockOnly) //-------------------------------------------------------------------------- // Finally, release the actual table lock //-------------------------------------------------------------------------- std::cout << std::endl; if (rollbackOnly) { logFinalStatus( tblName.toString(), lockID, std::string() ); std::cout << "Bulk Rollback Only for table " << tblName.toString() << " completed successfully." << std::endl; } else { try { brm.releaseTableLock( lockID ); // ignore boolean return value } catch (std::exception& ex) { logFinalStatus( tblName.toString(), lockID, ex.what() ); std::cout << "Error releasing table lock " << lockID << " for table " << tblName.toString() << std::endl; std::cout << ex.what() << std::endl; return 1; } catch (...) { std::string unknownErr("Unknown exception"); logFinalStatus( tblName.toString(), lockID, unknownErr ); std::cout << "Error releasing table lock " << lockID << " for table " << tblName.toString() << std::endl; std::cout << unknownErr << std::endl; return 1; } logFinalStatus( tblName.toString(), lockID, std::string() ); std::cout << "Table lock " << lockID << " for table " << tblName.toString() << " is cleared." << std::endl; } return 0; }
rc_t bt_cursor_t::_advance_one_slot(btree_page_h &p, bool &eof) { w_assert1(p.is_fixed()); w_assert1(_slot <= p.nrecs()); if(_forward) { ++_slot; } else { --_slot; } eof = false; // keep following the next page. // because we might see empty pages to skip consecutively! while (true) { bool time2move = _forward ? (_slot >= p.nrecs()) : _slot < 0; if (time2move) { // Move to right(left) sibling bool reached_end = _forward ? p.is_fence_high_supremum() : p.is_fence_low_infimum(); if (reached_end) { eof = true; return RCOK; } // now, use fence keys to tell where the neighboring page exists w_keystr_t neighboring_fence; btree_impl::traverse_mode_t traverse_mode; bool only_low_fence_exact_match = false; if (_forward) { p.copy_fence_high_key(neighboring_fence); traverse_mode = btree_impl::t_fence_low_match; int d = _upper.compare(neighboring_fence); if (d < 0 || (d == 0 && !_upper_inclusive)) { eof = true; return RCOK; } if (d == 0 && _upper_inclusive) { // we will check the next page, but the only // possible matching is an entry with // the low-fence.. only_low_fence_exact_match = true; } } else { // if we are going backwards, the current page had // low = [current-fence-low], high = [current-fence-high] // and the previous page should have // low = [?], high = [current-fence-low]. p.copy_fence_low_key(neighboring_fence); // let's find a page which has this value as high-fence traverse_mode = btree_impl::t_fence_high_match; int d = _lower.compare(neighboring_fence); if (d >= 0) { eof = true; return RCOK; } } p.unfix(); // take lock for the fence key if (_needs_lock) { lockid_t lid (_store, (const unsigned char*) neighboring_fence.buffer_as_keystr(), neighboring_fence.get_length_as_keystr()); okvl_mode lock_mode; if (only_low_fence_exact_match) { lock_mode = _ex_lock ? ALL_X_GAP_N: ALL_S_GAP_N; } else { lock_mode = _ex_lock ? ALL_X_GAP_X : ALL_S_GAP_S; } // we can unconditionally request lock because we already released latch W_DO(ss_m::lm->lock(lid.hash(), lock_mode, true, true, true)); } // TODO this part should check if we find an exact match of fence keys. // because we unlatch above, it's possible to not find exact match. // in that case, we should change the traverse_mode to fence_contains and continue W_DO(btree_impl::_ux_traverse(_store, neighboring_fence, traverse_mode, LATCH_SH, p)); _slot = _forward ? 0 : p.nrecs() - 1; _set_current_page(p); continue; } // take lock on the next key. // NOTE: until we get locks, we aren't sure the key really becomes // the next key. So, we use the temporary variable _tmp_next_key_buf. const okvl_mode *mode = NULL; { p.get_key(_slot, _tmp_next_key_buf); if (_forward) { int d = _tmp_next_key_buf.compare(_upper); if (d < 0) { mode = _ex_lock ? &ALL_X_GAP_X : &ALL_S_GAP_S; } else if (d == 0 && _upper_inclusive) { mode = _ex_lock ? &ALL_X_GAP_N : &ALL_S_GAP_N; } else { eof = true; mode = &ALL_N_GAP_N; } } else { int d = _tmp_next_key_buf.compare(_lower); if (d > 0) { mode = _ex_lock ? &ALL_X_GAP_X : &ALL_S_GAP_S; } else if (d == 0 && _lower_inclusive) { mode = _ex_lock ? &ALL_X_GAP_X : &ALL_S_GAP_S; } else { eof = true; mode = _ex_lock ? &ALL_N_GAP_X : &ALL_N_GAP_S; } } } if (_needs_lock && !mode->is_empty()) { rc_t rc = btree_impl::_ux_lock_key (_store, p, _tmp_next_key_buf, LATCH_SH, *mode, false); if (rc.is_error()) { if (rc.err_num() == eLOCKRETRY) { W_DO(_check_page_update(p)); continue; } else { return rc; } } } // okay, now we are sure the _tmp_next_key_buf is the key we want to use _key = _tmp_next_key_buf; return RCOK; // found a record! (or eof) } return RCOK; }
rc_t btree_impl::_ux_lock_key( const StoreID& store, btree_page_h& leaf, const void* keystr, size_t keylen, latch_mode_t latch_mode, const okvl_mode& lock_mode, bool check_only ) { // Callers: // 1. Top level _ux_lock_key() - I/U/D and search operations, lock conflict is possible // 2. _ux_lock_range() - lock conflict is possible // // Lock conflict: // 1. Deadlock - the asking lock is held by another transaction currently, and the // current transaction is holding other locks already, failed // 2. Timeout - the asking lock is held by another transaction currently, but the // current transaction does not hold other locks, okay to retry // For restart operation using lock re-acquisition: // 1. On_demand or mixed UNDO - when lock conflict. it triggers UNDO transaction rollback // this is a blocking operation, meaning the other concurrent // transactions asking for the same lock are blocked, no deadlock // 2. Traditional UNDO - original behavior, either deadlock error or timeout and retry lockid_t lid (store, (const unsigned char*) keystr, keylen); // first, try conditionally. we utilize the inserted lock entry even if it fails RawLock* entry = nullptr; // The lock request does the following: // If the lock() failed to acquire lock (trying to acquire lock while holding the latch) and // if the transaction doesn't have any other locks, because 'condition' is true, lock() // returns immediatelly with eCONDLOCKTIMEOUT which indicates it failed to // acquire lock but no deadlock worry and the lock entry has been created already. // In this case caller (this function) releases latch and try again using retry_lock() // which is a blocking operation, this is because it is safe to forever retry without // risking deadlock // If the lock() returns eDEADLOCK, it means lock acquisition failed and // the current transaction already held other locks, it is not safe to retry (will cause // further deadlocks) therefore caller must abort the current transaction rc_t lock_rc = lm->lock(lid.hash(), lock_mode, true /*check */, false /* wait */, !check_only /* acquire */, smthread_t::xct(),timeout_t::WAIT_IMMEDIATE, &entry); if (!lock_rc.is_error()) { // lucky! we got it immediately. just return. return RCOK; } else { // if it caused deadlock and it was chosen to be victim, give up! (not retry) if (lock_rc.err_num() == eDEADLOCK) { // The user transaction will abort and rollback itself upon deadlock detection. // Because Express does not have a deadlock monitor and policy to determine // which transaction to rollback during a deadlock (should abort the cheaper // transaction), the user transaction which detects deadlock will be aborted. w_assert1(entry == nullptr); return lock_rc; } // couldn't immediately get it. then we unlatch the page and wait. w_assert1(lock_rc.err_num() == eCONDLOCKTIMEOUT); w_assert1(entry != nullptr); // we release the latch here. However, we increment the pin count before that // to prevent the page from being evicted. pin_for_refix_holder pin_holder(leaf.pin_for_refix()); // automatically releases the pin lsn_t prelsn = leaf.get_page_lsn(); // to check if it's modified after this unlatch leaf.unfix(); // then, we try it unconditionally (this will block) W_DO(lm->retry_lock(&entry, !check_only /* acquire */)); // now we got the lock.. but it might be changed because we unlatched. w_rc_t refix_rc = leaf.refix_direct(pin_holder._idx, latch_mode); if (refix_rc.is_error() || leaf.get_page_lsn() != prelsn) { // release acquired lock if (entry != nullptr) { w_assert1(!check_only); lm->unlock(entry); } else { w_assert1(check_only); } if (refix_rc.is_error()) { return refix_rc; } else { w_assert1(leaf.get_page_lsn() != prelsn); // unluckily, it's the case return RC(eLOCKRETRY); // retry! } } return RCOK; } }
void chkpt_t::acquire_lock(logrec_t& r) { w_assert1(is_xct_active(r.tid())); w_assert1(!r.is_single_sys_xct()); w_assert1(!r.is_multi_page()); w_assert1(!r.is_cpsn()); w_assert1(r.is_page_update()); switch (r.type()) { case logrec_t::t_btree_insert: case logrec_t::t_btree_insert_nonghost: { btree_insert_t* dp = (btree_insert_t*) r.data(); w_keystr_t key; key.construct_from_keystr(dp->data, dp->klen); okvl_mode mode = btree_impl::create_part_okvl(okvl_mode::X, key); lockid_t lid (r.stid(), (const unsigned char*) key.buffer_as_keystr(), key.get_length_as_keystr()); add_lock(r.tid(), mode, lid.hash()); } break; case logrec_t::t_btree_update: { btree_update_t* dp = (btree_update_t*) r.data(); w_keystr_t key; key.construct_from_keystr(dp->_data, dp->_klen); okvl_mode mode = btree_impl::create_part_okvl(okvl_mode::X, key); lockid_t lid (r.stid(), (const unsigned char*) key.buffer_as_keystr(), key.get_length_as_keystr()); add_lock(r.tid(), mode, lid.hash()); } break; case logrec_t::t_btree_overwrite: { btree_overwrite_t* dp = (btree_overwrite_t*) r.data(); w_keystr_t key; key.construct_from_keystr(dp->_data, dp->_klen); okvl_mode mode = btree_impl::create_part_okvl(okvl_mode::X, key); lockid_t lid (r.stid(), (const unsigned char*) key.buffer_as_keystr(), key.get_length_as_keystr()); add_lock(r.tid(), mode, lid.hash()); } break; case logrec_t::t_btree_ghost_mark: { btree_ghost_t* dp = (btree_ghost_t*) r.data(); for (size_t i = 0; i < dp->cnt; ++i) { w_keystr_t key (dp->get_key(i)); okvl_mode mode = btree_impl::create_part_okvl(okvl_mode::X, key); lockid_t lid (r.stid(), (const unsigned char*) key.buffer_as_keystr(), key.get_length_as_keystr()); add_lock(r.tid(), mode, lid.hash()); } } break; case logrec_t::t_btree_ghost_reserve: { btree_ghost_reserve_t* dp = (btree_ghost_reserve_t*) r.data(); w_keystr_t key; key.construct_from_keystr(dp->data, dp->klen); okvl_mode mode = btree_impl::create_part_okvl(okvl_mode::X, key); lockid_t lid (r.stid(), (const unsigned char*) key.buffer_as_keystr(), key.get_length_as_keystr()); add_lock(r.tid(), mode, lid.hash()); } break; default: w_assert0(r.type() == logrec_t::t_page_img_format); break; } return; }