Commit 4a695324 authored by Bernd Lietzow's avatar Bernd Lietzow

updated to release 6.19

parent aee03250
......@@ -9,7 +9,10 @@ Before building BeeGFS, install the following dependency packages:
* Depedencies for RPM packages (Red Hat):
libuuid-devel libibverbs-devel librdmacm-devel libattr-devel redhat-rpm-config
rpm-build xfsprogs-devel cppunit cppunit-devel zlib-devel openssl-devel sqlite
sqlite-devel ant gcc-c++ gcc redhat-lsb-core java-devel
sqlite-devel ant gcc-c++ gcc redhat-lsb-core java-devel kernel-devel elfutils-libelf-devel
The `elfutils-libelf-devel` and `kernel-devel` packages can be omitted if you don't intend to
build the client module.
* Dependencies for DEB packages (Debian):
gcc g++ autoconf automake devscripts debhelper libtool libattr1-dev
......
beegfs_admon
\ No newline at end of file
beegfs_admon_gui
\ No newline at end of file
beegfs_auto_package
\ No newline at end of file
......@@ -107,7 +107,14 @@ print_usage_and_exit()
echo " numbers are shifted by this number. Useful in order to"
echo " have several BeeGFS instances running on the same node."
echo " Default: ${DEFAULT_PORT_SHIFT}"
echo " -f PATH => Path to additional BeeGFS config files."
echo " -f PATH => Directory containing additional beegfs config files."
echo " There can be one file for each service as well as the client."
echo " They must be named in the form beegfs-<service>.conf, where "
echo " <service> can be meta, storage, mgmtd, helperd or client."
echo " Only the options specified within the files are"
echo " set/overwritten, the rest of the defaults will not be"
echo " touched and still be applied. The directory and the "
echo " files need to be present on every node."
echo " -L PATH => Log file directory. If necessary, the directory will be"
echo " created. Default: ${DEFAULT_LOG_PATH}"
echo " -l => Prefer local storage nodes."
......
beegfs_client_devel
\ No newline at end of file
beegfs_client_module
\ No newline at end of file
beegfs_client_tests
\ No newline at end of file
beegfs_common
\ No newline at end of file
beegfs_common_package
\ No newline at end of file
beegfs_ctl
\ No newline at end of file
beegfs_deeper_lib
\ No newline at end of file
......@@ -370,6 +370,7 @@ $(call define_if_matches, KERNEL_HAS_ALLOC_WORKQUEUE, "alloc_workqueue", workque
$(call define_if_matches, KERNEL_HAS_WQ_RESCUER, "WQ_RESCUER", workqueue.h)
$(call define_if_matches, KERNEL_HAS_WAIT_QUEUE_ENTRY_T, "wait_queue_entry_t", wait.h)
$(call define_if_matches, KERNEL_HAS_CURRENT_FS_TIME, "current_fs_time", fs.h)
$(call define_if_matches, KERNEL_HAS_64BIT_TIMESTAMPS, "struct timespec64[[:space:]]\+i_atime;", fs.h)
# inodeChangeRes was changed to setattr_prepare in vanilla 4.9
$(call define_if_matches, KERNEL_HAS_SETATTR_PREPARE, "int setattr_prepare", fs.h)
......
......@@ -32,6 +32,7 @@ connCommRetrySecs = 600
connFallbackExpirationSecs = 900
connInterfacesFile =
connMaxInternodeNum = 12
connMaxConcurrentAttempts = 0
connNetFilterFile =
connUseRDMA = true
......@@ -166,6 +167,16 @@ sysACLsEnabled = false
# The maximum number of simultaneous connections to the same node.
# Default: 12
# [connMaxConcurrentAttempts]
# The maximum number of simultaneous connection attempts. This may help in case
# establishing new connections keeps failing and produces fallbacks.
# It may happen particularly when using RDMA in an Omni-Path setup. If you
# don't have failing connection attempts, tuning this option might still lead
# to a faster connection process. This option is experimental, so there is no
# experience with different values. Setting it to 0 disables it, which means
# concurrent connection attempts are not limited.
# Default: 0
# [connNetFilterFile]
# The path to a text file that specifies allowed IP subnets, which may be used
# for outgoing communication. One subnet per line in classless notation (IP
......@@ -285,7 +296,7 @@ sysACLsEnabled = false
# Values: Set the time (in ms) you want to spend waiting for the servers
# (especially the management daemon) to respond. Use 0 to disable all checks
# and allow mounting even if no servers are reachable.
# Default: 3000
# Default: 11000
# [sysSessionCheckOnClose]
# Checks for a valid session on the storage servers when a file is closed. If
......@@ -307,12 +318,12 @@ sysACLsEnabled = false
# Default: false
# [sysTargetOfflineTimeoutSecs]
# Timeout until all storage targets are considered offline when no target state
# updates can be fetched from the management server.
# Timeout until all storage targets and metadata nodes are considered offline
# when no target state updates can be fetched from the management server.
# If this value is 0, targets will never be set to offline due to an
# unreachable management node and will stay in state probably-offline.
# Note: This must be at least twice as large as the value of
# sysTargetOfflineTimoutSecs in the server config files.
# sysTargetOfflineTimoutSecs in the server config files.
# Values: time in seconds
# Default: 900
......
......@@ -204,6 +204,7 @@ void _Config_loadDefaults(Config* this)
_Config_configMapRedefine(this, "connRDMABufNum", "70");
_Config_configMapRedefine(this, "connRDMATypeOfService", "0");
_Config_configMapRedefine(this, "connNetFilterFile", "");
_Config_configMapRedefine(this, "connMaxConcurrentAttempts", "0");
_Config_configMapRedefine(this, "connAuthFile", "");
_Config_configMapRedefine(this, "connRecvNonIntrTimeoutMS", "5000");
_Config_configMapRedefine(this, "connTcpOnlyFilterFile", "");
......@@ -366,6 +367,11 @@ bool _Config_applyConfigMap(Config* this, bool enableException)
this->connNetFilterFile = StringTk_strDup(valueStr);
}
else
if (!strcmp(keyStr, "connMaxConcurrentAttempts"))
{
this->connMaxConcurrentAttempts = StringTk_strToUInt(valueStr);
}
else
if(!strcmp(keyStr, "connAuthFile") )
{
SAFE_KFREE(this->connAuthFile);
......
......@@ -84,6 +84,7 @@ static inline unsigned Config_getConnRDMABufNum(Config* this);
static inline int Config_getConnRDMATypeOfService(Config* this);
static inline char* Config_getConnNetFilterFile(Config* this);
static inline char* Config_getConnAuthFile(Config* this);
static inline unsigned Config_getConnMaxConcurrentAttempts(Config* this);
static inline uint64_t Config_getConnAuthHash(Config* this);
static inline unsigned Config_getConnRecvNonIntrTimeoutMS(Config* this);
static inline char* Config_getConnTcpOnlyFilterFile(Config* this);
......@@ -185,6 +186,7 @@ struct Config
unsigned connRDMABufNum;
int connRDMATypeOfService;
char* connNetFilterFile; // allowed IP addresses (all IPs allowed, if empty)
unsigned connMaxConcurrentAttempts;
char* connAuthFile;
uint64_t connAuthHash; // implicitly set based on hash of connAuthFile contents
unsigned connRecvNonIntrTimeoutMS; // timeout before allowing interuptions, e.g. SIGINT
......@@ -378,6 +380,11 @@ char* Config_getConnAuthFile(Config* this)
return this->connAuthFile;
}
unsigned Config_getConnMaxConcurrentAttempts(Config* this)
{
return this->connMaxConcurrentAttempts;
}
uint64_t Config_getConnAuthHash(Config* this)
{
return this->connAuthHash;
......
......@@ -162,7 +162,13 @@
typedef wait_queue_entry_t wait_queue_t;
#endif
#if !defined(KERNEL_HAS_CURRENT_FS_TIME)
#if defined(KERNEL_HAS_64BIT_TIMESTAMPS)
static inline struct timespec64 current_fs_time(struct super_block *sb)
{
struct timespec64 now = current_kernel_time64();
return timespec64_trunc(now, sb->s_time_gran);
}
#elif !defined(KERNEL_HAS_CURRENT_FS_TIME)
static inline struct timespec current_fs_time(struct super_block *sb)
{
struct timespec now = current_kernel_time();
......
......@@ -79,7 +79,7 @@ bool __IBVSocket_createNewID(IBVSocket* _this)
{
struct rdma_cm_id* new_cm_id;
#if defined(OFED_HAS_NETNS)
#if defined(OFED_HAS_NETNS) || defined(rdma_create_id)
new_cm_id = rdma_create_id(&init_net, __IBVSocket_cmaHandler, _this, RDMA_PS_TCP, IB_QPT_RC);
#elif defined(OFED_HAS_RDMA_CREATE_QPTYPE)
new_cm_id = rdma_create_id(__IBVSocket_cmaHandler, _this, RDMA_PS_TCP, IB_QPT_RC);
......@@ -1810,7 +1810,7 @@ struct ib_cq* __IBVSocket_createCompletionQueue(struct ib_device* device,
{
#if defined (BEEGFS_OFED_1_2_API) && BEEGFS_OFED_1_2_API >= 1
return ib_create_cq(device, comp_handler, event_handler, cq_context, cqe);
#elif defined OFED_HAS_IB_CREATE_CQATTR
#elif defined OFED_HAS_IB_CREATE_CQATTR || defined ib_create_cq
struct ib_cq_init_attr attrs = {
.cqe = cqe,
.comp_vector = 0,
......
......@@ -39,6 +39,9 @@ void NodeConnPool_init(NodeConnPool* this, struct App* app, struct Node* parentN
this->maxConns = Config_getConnMaxInternodeNum(cfg);
this->fallbackExpirationSecs = Config_getConnFallbackExpirationSecs(cfg);
this->maxConcurrentAttempts = Config_getConnMaxConcurrentAttempts(cfg);
sema_init(&this->connSemaphore, this->maxConcurrentAttempts);
this->parentNode = parentNode;
this->streamPort = streamPort;
......@@ -191,6 +194,12 @@ Socket* NodeConnPool_acquireStreamSocketEx(NodeConnPool* this, bool allowWaiting
Mutex_unlock(&this->mutex); // U N L O C K
if (this->maxConcurrentAttempts > 0)
{
if (down_interruptible(&this->connSemaphore))
return NULL;
}
// walk over all available NICs, create the corresponding socket and try to connect
NicAddressListIter_init(&nicIter, &nicListCopy);
......@@ -314,6 +323,12 @@ Socket* NodeConnPool_acquireStreamSocketEx(NodeConnPool* this, bool allowWaiting
kfree(endpointStr);
}
if (this->maxConcurrentAttempts > 0)
{
up(&this->connSemaphore);
}
Mutex_lock(&this->mutex); // L O C K
if(!NicAddressListIter_end(&nicIter) )
......
......@@ -117,7 +117,8 @@ struct NodeConnPool
unsigned establishedConns; // not equal to connList.size!!
unsigned maxConns;
unsigned fallbackExpirationSecs; // expiration time for conns to fallback interfaces
unsigned maxConcurrentAttempts;
NodeConnPoolStats stats;
NodeConnPoolErrorState errState;
......@@ -125,6 +126,7 @@ struct NodeConnPool
Mutex mutex;
Condition changeCond;
struct semaphore connSemaphore;
};
......
......@@ -47,11 +47,19 @@ void __DatagramListener_listenLoop(DatagramListener* this)
continue;
}
else
if(unlikely(recvRes <= 0) )
{ // error
if(recvRes == 0)
{
char* fromIP = SocketTk_ipaddrToStr(&fromAddr.addr);
Logger_logFormatted(log, Log_NOTICE, logContext,
"Received an empty datagram. IP: %s; port: %d",
fromIP, fromAddr.port);
kfree(fromIP);
//if(errno == -EINTR) // ignore iterruption, because the debugger makes this happen
// continue;
continue;
}
else
if(unlikely(recvRes < 0) )
{ // error
Logger_logErrFormatted(log, logContext,
"Encountered an unrecoverable socket error. ErrCode: %d", recvRes);
......
......@@ -341,6 +341,10 @@ int FhgfsOps_opendirIncremental(struct inode* inode, struct file* file)
__FhgfsOps_setDirInfo(dirInfo, file);
}
#ifdef FMODE_KABI_ITERATE
file->f_mode |= FMODE_KABI_ITERATE;
#endif
return retVal;
}
......
......@@ -465,7 +465,11 @@ struct posix_acl* FhgfsOps_get_acl(struct inode* inode, int type)
FhgfsInode* fhgfsInode = BEEGFS_INODE(inode);
const EntryInfo* entryInfo = FhgfsInode_getEntryInfo(fhgfsInode);
int refreshRes = maybeRefreshInode(inode, true, false, false);
int refreshRes;
forget_cached_acl(inode, type);
refreshRes = maybeRefreshInode(inode, true, false, false);
if (refreshRes)
return ERR_PTR(refreshRes);
......
......@@ -171,7 +171,12 @@ int __FhgfsOps_constructFsInfo(struct super_block* sb, void* rawMountOptions)
#if defined(KERNEL_HAS_SB_BDI)
#if defined(KERNEL_HAS_SUPER_SETUP_BDI_NAME) && !defined(KERNEL_HAS_BDI_SETUP_AND_REGISTER)
res = super_setup_bdi_name(sb, BEEGFS_MODULE_NAME_STR);
{
static atomic_long_t bdi_seq = ATOMIC_LONG_INIT(0);
res = super_setup_bdi_name(sb, BEEGFS_MODULE_NAME_STR "-%ld",
atomic_long_inc_return(&bdi_seq));
}
#else
bdi = &sbInfo->bdi;
......
......@@ -312,4 +312,10 @@ extern void assertMsg(const char* file, unsigned line, const char* condition);
#define USE_READDIR_R 1
#endif
#if __GNUC__ > 6
# define BEEGFS_FALLTHROUGH [[fallthrough]]
#else
# define BEEGFS_FALLTHROUGH
#endif
#endif /*COMMON_H_*/
......@@ -12,10 +12,12 @@
*/
NetMessage* AbstractNetMessageFactory::createFromBuf(char* recvBuf, size_t bufLen)
{
if(unlikely(bufLen < NETMSG_MIN_LENGTH))
return new SimpleMsg(NETMSGTYPE_Invalid);
NetMessageHeader header;
// decode the message header
NetMessage::deserializeHeader(recvBuf, bufLen, &header);
// delegate the rest of the work to another method...
......
......@@ -117,6 +117,8 @@ class NetMessage
{
Deserializer des(buf, bufLen);
des % *outHeader;
if(unlikely(!des.good()))
outHeader->msgType = NETMSGTYPE_Invalid;
}
class ResponseContext
......
......@@ -15,6 +15,7 @@
* @throw SocketException
*/
StandardSocket::StandardSocket(int domain, int type, int protocol)
: isDgramSocket(type == SOCK_DGRAM)
{
this->sockDomain = domain;
......@@ -63,6 +64,7 @@ StandardSocket::StandardSocket(int domain, int type, int protocol)
*/
StandardSocket::StandardSocket(int fd, unsigned short sockDomain, struct in_addr peerIP,
std::string peername)
: isDgramSocket(false)
{
this->sock = fd;
this->sockDomain = sockDomain;
......@@ -426,10 +428,22 @@ ssize_t StandardSocket::recv(void *buf, size_t len, int flags)
}
if(recvRes == 0)
throw SocketDisconnectException(std::string("Soft disconnect from ") + peername);
{
if (isDgramSocket)
{
LOG_TOP(GENERAL, NOTICE, "Received empty UDP datagram.", peername);
return 0;
}
else
{
throw SocketDisconnectException(std::string("Soft disconnect from ") + peername);
}
}
else
{
throw SocketDisconnectException(std::string("Recv(): Hard disconnect from ") +
peername + ". SysErr: " + System::getErrString() );
}
}
/**
......@@ -496,11 +510,25 @@ ssize_t StandardSocket::recvfrom(void *buf, size_t len, int flags,
}
if(recvRes == 0)
throw SocketDisconnectException(std::string("Soft disconnect from ") + peername);
{
if (isDgramSocket)
{
struct sockaddr_in* sin = (struct sockaddr_in*)from;
LOG_TOP(GENERAL, NOTICE, "Received empty UDP datagram.", peername,
as("IP", Socket::ipaddrToStr(&sin->sin_addr)), as("port", ntohs(sin->sin_port)));
return 0;
}
else
{
throw SocketDisconnectException(std::string("Soft disconnect from ") + peername);
}
}
else
{
throw SocketDisconnectException(
std::string("Recvfrom(): Hard disconnect from ") + peername + ": " +
System::getErrString() );
}
}
/**
......
......@@ -48,7 +48,8 @@ class StandardSocket : public PooledSocket
protected:
int sock;
unsigned short sockDomain; // socket domain (aka protocol family) e.g. PF_INET
const bool isDgramSocket;
StandardSocket(int fd, unsigned short sockDomain, struct in_addr peerIP,
std::string peername);
......
......@@ -304,9 +304,23 @@ bool TargetMapper::loadFromFile()
// add to attached states
if ( states )
{
const CombinedTargetState defaultState(TargetReachabilityState_POFFLINE,
TargetConsistencyState_GOOD);
CombinedTargetState ignoredReturnState;
for ( TargetMapCIter iter = targets.begin(); iter != targets.end(); iter++ )
states->addIfNotExists(iter->first,
CombinedTargetState(TargetReachabilityState_POFFLINE, TargetConsistencyState_GOOD) );
{
if (!states->getState(iter->first, ignoredReturnState)) {
LogContext(logContext).log(Log_WARNING,
"Storage target " + StringTk::intToStr(iter->first)
+ " missing in targetStates. Consistency state is lost.");
LogContext(logContext).log(Log_WARNING, "Adding default state for storage target "
+ StringTk::intToStr(iter->first) + ": "
+ states->stateToStr(defaultState));
IGNORE_UNUSED_VARIABLE(logContext);
states->addIfNotExists(iter->first, defaultState);
}
}
}
mappingsDirty = true;
......
#include "Quota.h"
std::ostream& operator<<(std::ostream& stream, const QuotaBlockDeviceFsType type)
{
switch (type)
{
case QuotaBlockDeviceFsType_UNKNOWN:
return stream << "Unknown";
case QuotaBlockDeviceFsType_EXTX:
return stream << "Ext2/3/4";
case QuotaBlockDeviceFsType_XFS:
return stream << "XFS";
case QuotaBlockDeviceFsType_ZFS:
case QuotaBlockDeviceFsType_ZFSOLD: // fallthrough
return stream << "ZFS";
}
return stream << "Invalid";
}
#ifndef COMMON_STORAGE_QUOTA_QUOTA_H_
#define COMMON_STORAGE_QUOTA_QUOTA_H_
#include <ostream>
enum QuotaBlockDeviceFsType
{
QuotaBlockDeviceFsType_UNKNOWN=0,
QuotaBlockDeviceFsType_EXTX=1,
QuotaBlockDeviceFsType_XFS=2,
QuotaBlockDeviceFsType_ZFS=3
QuotaBlockDeviceFsType_ZFS=3,
QuotaBlockDeviceFsType_ZFSOLD=4 // zfs < 0.7.4 (no inode quota)
};
std::ostream& operator<<(std::ostream& stream, const QuotaBlockDeviceFsType type);
enum QuotaInodeSupport
{
QuotaInodeSupport_UNKNOWN=0,
......
......@@ -139,10 +139,7 @@ class StripePattern
*/
size_t getStripeTargetIndex(int64_t pos) const
{
const unsigned chunkSize = getChunkSize();
const unsigned stripeSetSize = getNumStripeTargetIDs() * chunkSize;
return (pos % stripeSetSize) / chunkSize;
return (pos / getChunkSize()) % getNumStripeTargetIDs();
}
/**
......
......@@ -166,6 +166,7 @@ void Config::applyConfigMap(bool enableException, bool addDashes) throw (Invalid
if(testConfigMapKeyMatch(iter, "tuneDentryCacheSize", addDashes) )
tuneDentryCacheSize = StringTk::strToUInt64(iter->second.c_str() );
else
IGNORE_CONFIG_CLIENT_VALUE("connMaxConcurrentAttempts")
IGNORE_CONFIG_CLIENT_VALUE("tuneFileCacheType")
IGNORE_CONFIG_CLIENT_VALUE("tunePagedIOBufSize")
IGNORE_CONFIG_CLIENT_VALUE("tunePagedIOBufNum")
......
......@@ -56,6 +56,10 @@ struct InodeAttribs
uint64_t nlinks;
};
// represents a duplicated Inode. The set contains the IDs of the nodes / buddy groups where the
// entries were found. The boolean flag indicates if the corresponding ID is a node ID or a buddy
// group ID
typedef std::pair<db::EntryID, std::set<std::pair<uint32_t, bool>>> DuplicatedInode;
}
class FsckDB
......@@ -70,7 +74,7 @@ class FsckDB
void clear();
// FsckDBChecks.cpp
Cursor<std::pair<db::EntryID, std::set<uint32_t> > > findDuplicateInodeIDs();
Cursor<checks::DuplicatedInode> findDuplicateInodeIDs();
Cursor<std::list<FsckChunk> > findDuplicateChunks();
Cursor<std::list<db::ContDir>> findDuplicateContDirs();
......
......@@ -183,10 +183,10 @@ struct DuplicateIDGroup
{
typedef db::EntryID KeyType;
typedef db::EntryID ProjType;
typedef std::set<uint32_t> GroupType;
typedef std::set<std::pair<uint32_t,bool>> GroupType;
bool hasTarget;
uint32_t lastTarget;
std::pair<uint32_t, bool> lastTarget;
GroupType group;
DuplicateIDGroup()
......@@ -200,32 +200,31 @@ struct DuplicateIDGroup
group.clear();
}
KeyType key(std::pair<db::EntryID, uint32_t> pair)
KeyType key(std::tuple<db::EntryID, uint32_t, bool> tuple)
{
return pair.first;
return std::get<0>(tuple);
}
ProjType project(std::pair<db::EntryID, uint32_t> pair)
ProjType project(std::tuple<db::EntryID, uint32_t, bool> tuple)
{
return pair.first;
return std::get<0>(tuple);
}
void step(std::pair<db::EntryID, uint32_t> pair)
void step(std::tuple<db::EntryID, uint32_t, bool> tuple)
{
if(!hasTarget)
{
lastTarget = pair.second;
lastTarget = std::make_pair(std::get<1>(tuple), std::get<2>(tuple));
hasTarget = true;
return;
}
if(lastTarget != 0)
if(lastTarget.first != 0)
{
group.insert(lastTarget);
lastTarget = 0;
lastTarget.first = 0;
}
group.insert(pair.second);
group.insert(std::make_pair(std::get<1>(tuple), std::get<2>(tuple)));
}
GroupType finish()
......@@ -239,23 +238,23 @@ struct DuplicateIDGroup
};
}
Cursor<std::pair<db::EntryID, std::set<uint32_t> > > FsckDB::findDuplicateInodeIDs()
Cursor<checks::DuplicatedInode> FsckDB::findDuplicateInodeIDs()
{
struct ops
{
static std::pair<db::EntryID, uint32_t> idAndTargetF(db::FileInode& file)
static std::tuple<db::EntryID, uint32_t, bool> idAndTargetF(const db::FileInode& file)
{
return std::make_pair(file.id, file.saveNodeID);
return std::make_tuple(file.id, file.saveNodeID, !!file.isBuddyMirrored);
}
static std::pair<db::EntryID, uint32_t> idAndTargetD(db::DirInode& file)
static std::tuple<db::EntryID, uint32_t, bool> idAndTargetD(const db::DirInode& file)
{
return std::make_pair(file.id, file.saveNodeID);
return std::make_tuple(file.id, file.saveNodeID, !!file.isBuddyMirrored);
}
static bool hasDuplicateID(std::pair<db::EntryID, std::set<uint32_t> >& pair)
static bool hasDuplicateID(const checks::DuplicatedInode& dInode)
{
return !pair.second.empty();
return !dInode.second.empty();
}
};
......
......@@ -72,7 +72,7 @@ class LeftJoinEq
else
this->hasRightMark = false;
// fall-through
BEEGFS_FALLTHROUGH;
case s_first_right: {
while(rightKey() < leftKey() )
......
......@@ -201,7 +201,8 @@ class Table {
{
case ms_bulk_insert:
assertNoBulkInsert();
// fall-through
BEEGFS_FALLTHROUGH;
case ms_none:
modificationState = ms_ordered_only_insert;
break;
......
This diff is collapsed.
......@@ -80,7 +80,7 @@ class ModeCheckFS : public Mode
int64_t checkAndRepairChunksInWrongPath();
int64_t checkDuplicateInodeIDs();
void logDuplicateInodeID(std::pair<db::EntryID, std::set<uint32_t> >& dups, int&);
void logDuplicateInodeID(checks::DuplicatedInode& dups, int&);
int64_t checkDuplicateChunks();
void logDuplicateChunk(std::list<FsckChunk>& dups, int&);
......
......@@ -375,13 +375,13 @@ void TestDatabase::testFindDuplicateInodeIDs()
this->db->getDirInodesTable()->insert(disposal);
this->db->getFileInodesTable()->insert(files);
Cursor<std::pair<db::EntryID, std::set<uint32_t> > > c = this->db->findDuplicateInodeIDs();
Cursor<checks::DuplicatedInode> c = this->db->findDuplicateInodeIDs();
CPPUNIT_ASSERT(c.step() );
{
std::set<uint32_t> nodes;
nodes.insert(3000);
nodes.insert(2);
std::set<std::pair<uint32_t,bool>> nodes;
nodes.insert(std::make_pair(3000, false));
nodes.insert(std::make_pair(2, false));
CPPUNIT_ASSERT(c.get()->first == db::EntryID(0, 1, 1) );
CPPUNIT_ASSERT(c.get()->second.size() == 2);
......@@ -390,9 +390,9 @@ void TestDatabase::testFindDuplicateInodeIDs()
CPPUNIT_ASSERT(c.step() );
{
std::set<uint32_t> nodes;
nodes.insert(3002);
nodes.insert(2);
std::set<std::pair<uint32_t,bool>> nodes;