39 "CREATE TABLE IF NOT EXISTS inodes (path TEXT PRIMARY KEY);";
41 "INSERT INTO inodes (oid, path) VALUES (?, ?);";
43 "INSERT INTO inodes VALUES (?);";
45 "SELECT rowid FROM inodes where path = ?;";
47 "SELECT path FROM inodes where rowid = ?;";
56 "busy handler, attempt %d, accumulated waiting time %u",
61 const unsigned backoff_range_ms = 1 << attempt;
62 unsigned backoff_ms = handler_info->
prng.
Next(backoff_range_ms);
78 const uint64_t root_inode,
85 "nfs.sqlite.n_added",
"total number of issued inode");
87 "nfs.sqlite.n_seq",
"last inode issued");
89 "nfs.sqlite.n_path_hit",
"inode --> path hits");
91 "nfs.sqlite.n_inode_hit",
"path --> inode hits");
93 string db_path = db_dir +
"/inode_maps.db";
98 "Ignoring rebuild flag as this may crash other cluster nodes.");
101 int retval = sqlite3_enable_shared_cache(0);
102 assert(retval == SQLITE_OK);
104 retval = sqlite3_open_v2(db_path.c_str(), &maps->
db_,
105 SQLITE_OPEN_NOMUTEX | SQLITE_OPEN_READWRITE
106 | SQLITE_OPEN_CREATE, NULL);
107 if (retval != SQLITE_OK) {
109 "Failed to create inode_maps file (%s)",
116 retval = sqlite3_busy_handler(
118 assert(retval == SQLITE_OK);
121 retval = sqlite3_prepare_v2(
122 maps->
db_, kSqlCreateTable, -1, &stmt, NULL);
123 if (retval != SQLITE_OK) {
125 "Failed to prepare create table statement: %s",
126 sqlite3_errmsg(maps->
db_));
129 if (sqlite3_step(stmt) != SQLITE_DONE) {
131 "Failed to create main inode table: %s",
132 sqlite3_errmsg(maps->
db_));
133 sqlite3_finalize(stmt);
136 sqlite3_finalize(stmt);
139 retval = sqlite3_prepare_v2(
141 assert(retval == SQLITE_OK);
142 retval = sqlite3_prepare_v2(maps->
db_, kSqlGetInode, -1,
144 assert(retval == SQLITE_OK);
145 retval = sqlite3_prepare_v2(maps->
db_, kSqlAddInode, -1,
147 assert(retval == SQLITE_OK);
152 retval = sqlite3_prepare_v2(maps->
db_, kSqlAddRoot, -1, &stmt, NULL);
153 assert(retval == SQLITE_OK);
154 retval = sqlite3_bind_int64(stmt, 1, root_inode);
155 assert(retval == SQLITE_OK);
156 retval = sqlite3_bind_text(stmt, 2,
"", 0, SQLITE_TRANSIENT);
157 assert(retval == SQLITE_OK);
158 if (sqlite3_step(stmt) != SQLITE_DONE) {
160 sqlite3_errmsg(maps->
db_));
162 sqlite3_finalize(stmt);
176 sqlite_state = sqlite3_bind_text(stmt_get_inode_, 1, path.
GetChars(),
178 assert(sqlite_state == SQLITE_OK);
179 sqlite_state = sqlite3_step(stmt_get_inode_);
180 if (sqlite_state == SQLITE_DONE) {
182 sqlite3_reset(stmt_get_inode_);
185 if (sqlite_state != SQLITE_ROW) {
187 path.
c_str(), sqlite3_errmsg(db_));
188 sqlite3_reset(stmt_get_inode_);
191 inode = sqlite3_column_int64(stmt_get_inode_, 0);
192 sqlite3_reset(stmt_get_inode_);
204 sqlite_state = sqlite3_prepare_v2(db_, kSqlAddInode, -1, &stmt_add_, NULL);
205 assert(sqlite_state == SQLITE_OK);
206 sqlite_state = sqlite3_bind_text(stmt_add_, 1, path.
GetChars(),
208 if (sqlite_state != SQLITE_OK) {
210 "Failed to bind path in IssueInode (%s)", path.
c_str());
211 sqlite3_reset(stmt_add_);
214 sqlite_state = sqlite3_step(stmt_add_);
215 if (sqlite_state != SQLITE_DONE) {
217 "Failed to execute SQL for IssueInode (%s): %s",
218 path.
c_str(), sqlite3_errmsg(db_));
219 sqlite3_reset(stmt_add_);
222 inode = sqlite3_last_insert_rowid(db_);
223 sqlite3_reset(stmt_add_);
224 n_db_seq_->Set(inode);
241 inode = FindInode(path);
247 inode = IssueInode(path);
251 inode = RetryGetInode(path, attempt + 1);
261 return RetryGetInode(path, 0);
275 sqlite_state = sqlite3_bind_int64(stmt_get_path_, 1, inode);
276 assert(sqlite_state == SQLITE_OK);
277 sqlite_state = sqlite3_step(stmt_get_path_);
278 if (sqlite_state == SQLITE_DONE) {
280 sqlite3_reset(stmt_get_path_);
283 if (sqlite_state != SQLITE_ROW) {
285 inode, sqlite3_errmsg(db_));
287 const char *raw_path = (
const char *)sqlite3_column_text(stmt_get_path_, 0);
288 path->
Assign(raw_path, strlen(raw_path));
289 sqlite3_reset(stmt_get_path_);
297 , stmt_get_path_(NULL)
298 , stmt_get_inode_(NULL)
303 , n_db_path_found_(NULL)
304 , n_db_inode_found_(NULL)
306 lock_ =
reinterpret_cast<pthread_mutex_t *
>(smalloc(
sizeof(pthread_mutex_t)));
307 int retval = pthread_mutex_init(
lock_, NULL);
317 sqlite3_close_v2(
db_);
318 pthread_mutex_destroy(
lock_);
perf::Counter * n_db_added_
Counter * Register(const std::string &name, const std::string &desc)
static const char * kSqlGetPath
static NfsMapsSqlite * Create(const std::string &db_dir, const uint64_t root_inode, const bool rebuild, perf::Statistics *statistics_)
perf::Counter * n_db_seq_
void Assign(const char *chars, const unsigned length)
uint64_t FindInode(const PathString &path)
assert((mem||(size==0))&&"Out Of Memory")
BusyHandlerInfo busy_handler_info_
static const char * kSqlGetInode
static const unsigned kMaxWaitMs
virtual uint64_t GetInode(const PathString &path)
static int BusyHandler(void *data, int attempt)
static const char * kSqlCreateTable
static const unsigned kMaxBackoffMs
virtual bool GetPath(const uint64_t inode, PathString *path)
void Inc(class Counter *counter)
perf::Counter * n_db_inode_found_
sqlite3_stmt * stmt_get_inode_
uint64_t RetryGetInode(const PathString &path, int attempt)
uint64_t IssueInode(const PathString &path)
perf::Counter * n_db_path_found_
void SafeSleepMs(const unsigned ms)
sqlite3_stmt * stmt_get_path_
unsigned GetLength() const
const char * c_str() const
const char * GetChars() const
static const char * kSqlAddRoot
static const char * kSqlAddInode
uint32_t Next(const uint64_t boundary)
CVMFS_EXPORT void LogCvmfs(const LogSource source, const int mask, const char *format,...)