mirror of
https://github.com/Retropex/bitcoin.git
synced 2025-05-12 19:20:42 +02:00
Merge branch 'ionice' into ionice_win
This commit is contained in:
commit
45fa891549
40
configure.ac
40
configure.ac
@ -943,6 +943,46 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
|
||||
[ AC_MSG_RESULT([no])]
|
||||
)
|
||||
|
||||
AC_MSG_CHECKING(for macOS iopolicy functions)
|
||||
AC_COMPILE_IFELSE([
|
||||
AC_LANG_PROGRAM([[
|
||||
#include <sys/resource.h>
|
||||
]],[[
|
||||
int x = getiopolicy_np(IOPOL_TYPE_DISK, IOPOL_SCOPE_THREAD);
|
||||
setiopolicy_np(IOPOL_TYPE_DISK, IOPOL_SCOPE_THREAD, x);
|
||||
]])
|
||||
],[
|
||||
AC_MSG_RESULT([yes])
|
||||
HAVE_IOPOLICY=1
|
||||
],[
|
||||
AC_MSG_RESULT([no])
|
||||
HAVE_IOPOLICY=0
|
||||
])
|
||||
AC_DEFINE_UNQUOTED([HAVE_IOPOLICY], [$HAVE_IOPOLICY], [Define to 1 if macOS iopolicy functions are usable.])
|
||||
|
||||
if test x$HAVE_IOPOLICY = x0; then
|
||||
AC_MSG_CHECKING(for Linux ioprio syscalls)
|
||||
AC_COMPILE_IFELSE([
|
||||
AC_LANG_PROGRAM([[
|
||||
#define _GNU_SOURCE
|
||||
#include <unistd.h>
|
||||
#include <sys/syscall.h>
|
||||
]],[[
|
||||
int x = syscall(SYS_ioprio_get, 1, 0);
|
||||
syscall(SYS_ioprio_set, 1, 0, x);
|
||||
]])
|
||||
],[
|
||||
AC_MSG_RESULT([yes])
|
||||
HAVE_IOPRIO_SYSCALL=1
|
||||
],[
|
||||
AC_MSG_RESULT([no])
|
||||
HAVE_IOPRIO_SYSCALL=0
|
||||
])
|
||||
else
|
||||
HAVE_IOPRIO_SYSCALL=0
|
||||
fi
|
||||
AC_DEFINE_UNQUOTED([HAVE_IOPRIO_SYSCALL], [$HAVE_IOPRIO_SYSCALL], [Define to 1 if Linux ioprio syscalls are usable.])
|
||||
|
||||
dnl Check for different ways of gathering OS randomness
|
||||
AC_MSG_CHECKING([for Linux getrandom function])
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
|
||||
|
@ -312,6 +312,7 @@ BITCOIN_CORE_H = \
|
||||
util/hash_type.h \
|
||||
util/hasher.h \
|
||||
util/insert.h \
|
||||
util/ioprio.h \
|
||||
util/macros.h \
|
||||
util/moneystr.h \
|
||||
util/overflow.h \
|
||||
@ -745,6 +746,7 @@ libbitcoin_util_a_SOURCES = \
|
||||
util/fs.cpp \
|
||||
util/fs_helpers.cpp \
|
||||
util/hasher.cpp \
|
||||
util/ioprio.cpp \
|
||||
util/sock.cpp \
|
||||
util/syserror.cpp \
|
||||
util/moneystr.cpp \
|
||||
|
@ -2516,7 +2516,7 @@ void PeerManagerImpl::ProcessGetBlockData(CNode& pfrom, Peer& peer, const CInv&
|
||||
// Fast-path: in this case it is possible to serve the block directly from disk,
|
||||
// as the network format matches the format on disk
|
||||
std::vector<uint8_t> block_data;
|
||||
if (!m_chainman.m_blockman.ReadRawBlockFromDisk(block_data, block_pos)) {
|
||||
if (!m_chainman.m_blockman.ReadRawBlockFromDisk(block_data, block_pos, /*lowprio=*/true)) {
|
||||
if (WITH_LOCK(m_chainman.GetMutex(), return m_chainman.m_blockman.IsBlockPruned(*pindex))) {
|
||||
LogPrint(BCLog::NET, "Block was pruned before it could be read, disconnect peer=%s\n", pfrom.GetId());
|
||||
} else {
|
||||
@ -2530,7 +2530,7 @@ void PeerManagerImpl::ProcessGetBlockData(CNode& pfrom, Peer& peer, const CInv&
|
||||
} else {
|
||||
// Send block from disk
|
||||
std::shared_ptr<CBlock> pblockRead = std::make_shared<CBlock>();
|
||||
if (!m_chainman.m_blockman.ReadBlockFromDisk(*pblockRead, block_pos)) {
|
||||
if (!m_chainman.m_blockman.ReadBlockFromDisk(*pblockRead, block_pos, /*lowprio=*/true)) {
|
||||
if (WITH_LOCK(m_chainman.GetMutex(), return m_chainman.m_blockman.IsBlockPruned(*pindex))) {
|
||||
LogPrint(BCLog::NET, "Block was pruned before it could be read, disconnect peer=%s\n", pfrom.GetId());
|
||||
} else {
|
||||
@ -4434,7 +4434,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
||||
|
||||
if (!block_pos.IsNull()) {
|
||||
CBlock block;
|
||||
const bool ret{m_chainman.m_blockman.ReadBlockFromDisk(block, block_pos)};
|
||||
const bool ret{m_chainman.m_blockman.ReadBlockFromDisk(block, block_pos, /*lowprio=*/true)};
|
||||
// If height is above MAX_BLOCKTXN_DEPTH then this block cannot get
|
||||
// pruned after we release cs_main above, so this read should never fail.
|
||||
assert(ret);
|
||||
@ -6052,7 +6052,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
|
||||
PushMessage(*pto, std::move(cached_cmpctblock_msg.value()));
|
||||
} else {
|
||||
CBlock block;
|
||||
const bool ret{m_chainman.m_blockman.ReadBlockFromDisk(block, *pBestIndex)};
|
||||
const bool ret{m_chainman.m_blockman.ReadBlockFromDisk(block, *pBestIndex, /*lowprio=*/true)};
|
||||
assert(ret);
|
||||
CBlockHeaderAndShortTxIDs cmpctblock{block, m_rng.rand64()};
|
||||
MakeAndPushMessage(*pto, NetMsgType::CMPCTBLOCK, cmpctblock);
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include <util/batchpriority.h>
|
||||
#include <util/check.h>
|
||||
#include <util/fs.h>
|
||||
#include <util/ioprio.h>
|
||||
#include <util/signalinterrupt.h>
|
||||
#include <util/strencodings.h>
|
||||
#include <util/translation.h>
|
||||
@ -1034,10 +1035,13 @@ bool BlockManager::WriteUndoDataForBlock(const CBlockUndo& blockundo, BlockValid
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BlockManager::ReadBlockFromDisk(CBlock& block, const FlatFilePos& pos) const
|
||||
bool BlockManager::ReadBlockFromDisk(CBlock& block, const FlatFilePos& pos, const bool lowprio) const
|
||||
{
|
||||
block.SetNull();
|
||||
|
||||
{
|
||||
IOPRIO_IDLER(lowprio);
|
||||
|
||||
// Open history file to read
|
||||
AutoFile filein{OpenBlockFile(pos, true)};
|
||||
if (filein.IsNull()) {
|
||||
@ -1053,6 +1057,8 @@ bool BlockManager::ReadBlockFromDisk(CBlock& block, const FlatFilePos& pos) cons
|
||||
return false;
|
||||
}
|
||||
|
||||
} // end IOPRIO_IDLER scope
|
||||
|
||||
// Check the header
|
||||
if (!CheckProofOfWork(block.GetHash(), block.nBits, GetConsensus())) {
|
||||
LogError("%s: Errors in block header at %s\n", __func__, pos.ToString());
|
||||
@ -1068,11 +1074,11 @@ bool BlockManager::ReadBlockFromDisk(CBlock& block, const FlatFilePos& pos) cons
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BlockManager::ReadBlockFromDisk(CBlock& block, const CBlockIndex& index) const
|
||||
bool BlockManager::ReadBlockFromDisk(CBlock& block, const CBlockIndex& index, const bool lowprio) const
|
||||
{
|
||||
const FlatFilePos block_pos{WITH_LOCK(cs_main, return index.GetBlockPos())};
|
||||
|
||||
if (!ReadBlockFromDisk(block, block_pos)) {
|
||||
if (!ReadBlockFromDisk(block, block_pos, lowprio)) {
|
||||
return false;
|
||||
}
|
||||
if (block.GetHash() != index.GetBlockHash()) {
|
||||
@ -1082,7 +1088,7 @@ bool BlockManager::ReadBlockFromDisk(CBlock& block, const CBlockIndex& index) co
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BlockManager::ReadRawBlockFromDisk(std::vector<uint8_t>& block, const FlatFilePos& pos) const
|
||||
bool BlockManager::ReadRawBlockFromDisk(std::vector<uint8_t>& block, const FlatFilePos& pos, const bool lowprio) const
|
||||
{
|
||||
FlatFilePos hpos = pos;
|
||||
// If nPos is less than 8 the pos is null and we don't have the block data
|
||||
@ -1092,6 +1098,9 @@ bool BlockManager::ReadRawBlockFromDisk(std::vector<uint8_t>& block, const FlatF
|
||||
return false;
|
||||
}
|
||||
hpos.nPos -= 8; // Seek back 8 bytes for meta header
|
||||
|
||||
IOPRIO_IDLER(lowprio);
|
||||
|
||||
AutoFile filein{OpenBlockFile(hpos, true)};
|
||||
if (filein.IsNull()) {
|
||||
LogError("%s: OpenBlockFile failed for %s\n", __func__, pos.ToString());
|
||||
|
@ -420,9 +420,9 @@ public:
|
||||
void UnlinkPrunedFiles(const std::set<int>& setFilesToPrune) const;
|
||||
|
||||
/** Functions for disk access for blocks */
|
||||
bool ReadBlockFromDisk(CBlock& block, const FlatFilePos& pos) const;
|
||||
bool ReadBlockFromDisk(CBlock& block, const CBlockIndex& index) const;
|
||||
bool ReadRawBlockFromDisk(std::vector<uint8_t>& block, const FlatFilePos& pos) const;
|
||||
bool ReadBlockFromDisk(CBlock& block, const FlatFilePos& pos, bool lowprio = false) const;
|
||||
bool ReadBlockFromDisk(CBlock& block, const CBlockIndex& index, bool lowprio = false) const;
|
||||
bool ReadRawBlockFromDisk(std::vector<uint8_t>& block, const FlatFilePos& pos, bool lowprio = false) const;
|
||||
|
||||
bool UndoReadFromDisk(CBlockUndo& blockundo, const CBlockIndex& index) const;
|
||||
|
||||
|
57
src/util/ioprio.cpp
Normal file
57
src/util/ioprio.cpp
Normal file
@ -0,0 +1,57 @@
|
||||
// Copyright (c) 2016 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
#include <config/bitcoin-config.h>
|
||||
#endif
|
||||
|
||||
#include <util/ioprio.h>
|
||||
|
||||
#if HAVE_IOPRIO_SYSCALL
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
#include <unistd.h>
|
||||
#include <sys/syscall.h>
|
||||
|
||||
#ifndef IOPRIO_WHO_PROCESS
|
||||
#define IOPRIO_WHO_PROCESS 1
|
||||
#endif
|
||||
#ifndef IOPRIO_CLASS_IDLE
|
||||
#define IOPRIO_CLASS_IDLE 3
|
||||
#endif
|
||||
#ifndef IOPRIO_CLASS_SHIFT
|
||||
#define IOPRIO_CLASS_SHIFT 13
|
||||
#endif
|
||||
|
||||
int ioprio_get() {
|
||||
return syscall(SYS_ioprio_get, IOPRIO_WHO_PROCESS, 0);
|
||||
}
|
||||
|
||||
int ioprio_set(const int ioprio) {
|
||||
return syscall(SYS_ioprio_set, IOPRIO_WHO_PROCESS, 0, ioprio);
|
||||
}
|
||||
|
||||
int ioprio_set_idle() {
|
||||
return ioprio_set(7 | (IOPRIO_CLASS_IDLE << IOPRIO_CLASS_SHIFT));
|
||||
}
|
||||
|
||||
#elif HAVE_IOPOLICY
|
||||
|
||||
#include <sys/resource.h>
|
||||
|
||||
int ioprio_get() {
|
||||
return getiopolicy_np(IOPOL_TYPE_DISK, IOPOL_SCOPE_THREAD);
|
||||
}
|
||||
|
||||
int ioprio_set(const int ioprio) {
|
||||
return setiopolicy_np(IOPOL_TYPE_DISK, IOPOL_SCOPE_THREAD, ioprio);
|
||||
}
|
||||
|
||||
int ioprio_set_idle() {
|
||||
return ioprio_set(IOPOL_UTILITY);
|
||||
}
|
||||
|
||||
#endif
|
57
src/util/ioprio.h
Normal file
57
src/util/ioprio.h
Normal file
@ -0,0 +1,57 @@
|
||||
// Copyright (c) 2016 Satoshi Nakamoto
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_UTIL_IOPRIO_H
|
||||
#define BITCOIN_UTIL_IOPRIO_H
|
||||
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
#include <config/bitcoin-config.h>
|
||||
#endif
|
||||
|
||||
#include <logging.h>
|
||||
|
||||
#if HAVE_IOPRIO_SYSCALL || HAVE_IOPOLICY
|
||||
int ioprio_get();
|
||||
int ioprio_set(int ioprio);
|
||||
int ioprio_set_idle();
|
||||
|
||||
class ioprio_idler {
|
||||
private:
|
||||
int orig;
|
||||
|
||||
public:
|
||||
ioprio_idler(const bool lowprio) {
|
||||
if (!lowprio) {
|
||||
orig = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
orig = ioprio_get();
|
||||
if (orig == -1) {
|
||||
return;
|
||||
}
|
||||
if (ioprio_set_idle() == -1) {
|
||||
orig = -1;
|
||||
}
|
||||
}
|
||||
|
||||
~ioprio_idler() {
|
||||
if (orig == -1) {
|
||||
return;
|
||||
}
|
||||
if (ioprio_set(orig) == -1) {
|
||||
LogPrintf("failed to restore ioprio\n");
|
||||
}
|
||||
}
|
||||
};
|
||||
#define IOPRIO_IDLER(lowprio) ioprio_idler ioprio_idler_(lowprio)
|
||||
|
||||
#else
|
||||
#define ioprio_get() ((void)-1)
|
||||
#define ioprio_set(ioprio) ((void)-1)
|
||||
#define ioprio_set_idle() ((void)-1)
|
||||
#define IOPRIO_IDLER(lowprio) (void)lowprio;
|
||||
#endif
|
||||
|
||||
#endif // BITCOIN_UTIL_IOPRIO_H
|
@ -52,6 +52,7 @@
|
||||
#include <util/fs.h>
|
||||
#include <util/fs_helpers.h>
|
||||
#include <util/hasher.h>
|
||||
#include <util/ioprio.h>
|
||||
#include <util/moneystr.h>
|
||||
#include <util/rbf.h>
|
||||
#include <util/result.h>
|
||||
@ -4743,7 +4744,7 @@ VerifyDBResult CVerifyDB::VerifyDB(
|
||||
}
|
||||
CBlock block;
|
||||
// check level 0: read from disk
|
||||
if (!chainstate.m_blockman.ReadBlockFromDisk(block, *pindex)) {
|
||||
if (!chainstate.m_blockman.ReadBlockFromDisk(block, *pindex, /*lowprio=*/true)) {
|
||||
LogPrintf("Verification error: ReadBlockFromDisk failed at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
|
||||
return VerifyDBResult::CORRUPTED_BLOCK_DB;
|
||||
}
|
||||
@ -4809,7 +4810,7 @@ VerifyDBResult CVerifyDB::VerifyDB(
|
||||
m_notifications.progress(_("Verifying blocks…"), percentageDone, false);
|
||||
pindex = chainstate.m_chain.Next(pindex);
|
||||
CBlock block;
|
||||
if (!chainstate.m_blockman.ReadBlockFromDisk(block, *pindex)) {
|
||||
if (!chainstate.m_blockman.ReadBlockFromDisk(block, *pindex, /*lowprio=*/true)) {
|
||||
LogPrintf("Verification error: ReadBlockFromDisk failed at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
|
||||
return VerifyDBResult::CORRUPTED_BLOCK_DB;
|
||||
}
|
||||
@ -4838,7 +4839,7 @@ bool Chainstate::RollforwardBlock(const CBlockIndex* pindex, CCoinsViewCache& in
|
||||
AssertLockHeld(cs_main);
|
||||
// TODO: merge with ConnectBlock
|
||||
CBlock block;
|
||||
if (!m_blockman.ReadBlockFromDisk(block, *pindex)) {
|
||||
if (!m_blockman.ReadBlockFromDisk(block, *pindex, /*lowprio=*/true)) {
|
||||
LogError("ReplayBlock(): ReadBlockFromDisk failed at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
|
||||
return false;
|
||||
}
|
||||
@ -4896,7 +4897,7 @@ bool Chainstate::ReplayBlocks()
|
||||
while (pindexOld != pindexFork) {
|
||||
if (pindexOld->nHeight > 0) { // Never disconnect the genesis block.
|
||||
CBlock block;
|
||||
if (!m_blockman.ReadBlockFromDisk(block, *pindexOld)) {
|
||||
if (!m_blockman.ReadBlockFromDisk(block, *pindexOld, /*lowprio=*/true)) {
|
||||
LogError("RollbackBlock(): ReadBlockFromDisk() failed at %d, hash=%s\n", pindexOld->nHeight, pindexOld->GetBlockHash().ToString());
|
||||
return false;
|
||||
}
|
||||
@ -5036,6 +5037,8 @@ void ChainstateManager::LoadExternalBlockFile(
|
||||
|
||||
int nLoaded = 0;
|
||||
try {
|
||||
IOPRIO_IDLER(/*lowprio=*/true);
|
||||
|
||||
BufferedFile blkdat{file_in, 2 * MAX_BLOCK_SERIALIZED_SIZE, MAX_BLOCK_SERIALIZED_SIZE + 8};
|
||||
// nRewind indicates where to resume scanning in case something goes wrong,
|
||||
// such as a block fails to deserialize.
|
||||
|
Loading…
Reference in New Issue
Block a user