en de en en ur en en en en en en en en en nb uk de uk uk uk de en en en en en en en it en fr az fr fr en en en en en en en en en en fr fr en en en en en en en en en it de en en en en fa en en hi de en en uk fr fr fr en en en en en tr en zh en en en en en en en en fr kk fr en fr en en fr en en en oc en en en tr en en en zh oc en en en en en pt fr en pt en en sv en pt zh hbs_lat pt zh en pt en zh de en oc en pt en en en pt en en it pt fr en en en pt en pt en en en en pt da en oc oc en oc fr fr en en en en en en pt en en ru fa oc en en ar ru fr oc en ru sv oc fr fr en en fa en it en en en en fr en fi zh oc en en en en ar fi zh de en ru ru ru sv oc oc fr en en en en fa zh oc oc fa fr en ceb sv en sv oc en ceb oc fr uk en oc sv oc fr ca en ceb oc oc oc en en en fr en en en en en ru az oc en en ar oc en en ru ru zh oc de fr en fr en en en en ru en en en fr en en en oc oc oc en it en hy en uk en en da en en en fr en en en en en en en en en en en en en en en en en en en da en sv en en en en en en en en en en en en uk en fr en en en en en en en en en en en en en en en lt en en en en en en en et en en en en en en en en en en en en en en en en en en en en en en fr en en en en en en en en en en en en en zh en en en en en en en en en en en en en en en en ceb sk en en en en en en en en fr en en fr en en it en en en en en en en en en de en en en es es en en
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Go to te documentation of this file.
38 const char *NfsMapsSqlite::kSqlCreateTable =
39  "CREATE TABLE IF NOT EXISTS inodes (path TEXT PRIMARY KEY);";
40 const char *NfsMapsSqlite::kSqlAddRoot =
41  "INSERT INTO inodes (rowid, path) VALUES (?, \"\");";
42 const char *NfsMapsSqlite::kSqlAddInode =
43  "INSERT INTO inodes VALUES (?);";
45  "SELECT rowid FROM inodes where path = ?;";
46 const char *NfsMapsSqlite::kSqlGetPath =
47  "SELECT path FROM inodes where rowid = ?;";
50 int NfsMapsSqlite::BusyHandler(void *data, int attempt) {
51  BusyHandlerInfo *handler_info = static_cast (data);
53  if (attempt == 0)
56  "busy handler, attempt %d, accumulated waiting time %u",
61  const unsigned backoff_range_ms = 1 << attempt;
82  assert(root_inode > 0);
83  UniquePtr  maps(new NfsMapsSqlite());
84  maps->n_db_added_ = statistics->Register(
85  "nfs.sqlite.n_added", "total number of issued inode");
86  maps->n_db_seq_ = statistics->Register(
87  "nfs.sqlite.n_seq", "last inode issued");
88  maps->n_db_path_found_ = statistics->Register(
89  "nfs.sqlite.n_path_hit", "inode --> path hits");
90  maps->n_db_inode_found_ = statistics->Register(
91  "nfs.sqlite.n_inode_hit", "path --> inode hits");
93  string db_path = db_dir + "/inode_maps.db";
96  if (rebuild) {
97  LogCvmfs(kLogNfsMaps, kLogDebug | kLogSyslogWarn,
98  "Ignoring rebuild flag as this may crash other cluster nodes.");
100  // We don't want te shared cache, we want minimal caching so sync is kept
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)",
113  // Be prepared to wait for up to 1 minute for transactions to complete
114  // Being stuck for a long time is far more favorable than failing
115  // TODO(jblomer): another busy handler. This one conflicts with SIGALRM
116  retval = sqlite3_busy_handler(
117  maps->db_, BusyHandler, &maps->busy_handler_info_);
118  assert(retval == SQLITE_OK);
120  // Set-up te main inode table if it doesn't exist
121  retval = sqlite3_prepare_v2(
122  maps->db_, kSqlCreateTable, kMaxDBSqlLen, &stmt, NULL);
123  if (retval != SQLITE_OK) {
124  LogCvmfs(kLogNfsMaps, kLogDebug | kLogSyslogErr,
125  "Failed to prepare create table statement: %s",
129  if (sqlite3_step(stmt) != SQLITE_DONE) {
131  "Failed to create main inode table: %s",
138  // Prepare lookup and add-inode statements
139  retval = sqlite3_prepare_v2(
140  maps->db_, kSqlGetPath, kMaxDBSqlLen, &maps->stmt_get_path_, NULL);
141  assert(retval == SQLITE_OK);
142  retval = sqlite3_prepare_v2(maps->db_, kSqlGetInode, kMaxDBSqlLen,
144  assert(retval == SQLITE_OK);
145  retval = sqlite3_prepare_v2(maps->db_, kSqlAddInode, kMaxDBSqlLen,
147  assert(retval == SQLITE_OK);
149  // Check te root inode exists, if not create it
150  PathString rootpath("", 0);
151  if (!maps->FindInode(rootpath)) {
152  retval = sqlite3_prepare_v2(
153  maps->db_, kSqlAddRoot, kMaxDBSqlLen, &stmt, NULL);
154  assert(retval == SQLITE_OK);
155  sqlite3_bind_int64(stmt, 1, root_inode);
156  assert(retval == SQLITE_OK);
157  if (sqlite3_step(stmt) != SQLITE_DONE) {
158  PANIC(kLogDebug | kLogSyslogErr, "Failed to execute CreateRoot: %s",
172 uint64_t NfsMapsSqlite::FindInode(const PathString &path) {
175  sqlite_state = sqlite3_bind_text(stmt_get_inode_, 1, path.GetChars(),
177  assert(sqlite_state == SQLITE_OK);
178  sqlite_state = sqlite3_step(stmt_get_inode_);
179  if (sqlite_state == SQLITE_DONE) {
180  // Path not found in DB
184  if (sqlite_state != SQLITE_ROW) {
185  LogCvmfs(kLogNfsMaps, kLogDebug, "Error finding inode (%s): %s",
190  inode = sqlite3_column_int64(stmt_get_inode_, 0);
200 uint64_t NfsMapsSqlite::IssueInode(const PathString &path) {
203  sqlite_state = sqlite3_prepare_v2(db_, kSqlAddInode, kMaxDBSqlLen,
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());
214  sqlite_state = sqlite3_step(stmt_add_);
215  if (sqlite_state != SQLITE_DONE) {
217  "Failed to execute SQL for IssueInode (%s): %s",
222  inode = sqlite3_last_insert_rowid(db_);
230 uint64_t NfsMapsSqlite::RetryGetInode(const PathString &path, int attempt) {
231  if (attempt > 2) {
232  // We have to give up eventually
233  LogCvmfs(kLogNfsMaps, kLogSyslogErr, "Failed to find & create path (%s)",
241  inode = FindInode(path);
242  if (inode) {
246  // Inode not found, issue a new one
247  inode = IssueInode(path);
250  if (!inode) {
251  inode = RetryGetInode(path, attempt + 1);
260 uint64_t NfsMapsSqlite::GetInode(const PathString &path) {
261  return RetryGetInode(path, 0);
271 bool NfsMapsSqlite::GetPath(const uint64_t inode, PathString *path) {
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) {
279  // Success, but inode not found!
283  if (sqlite_state != SQLITE_ROW) {
284  PANIC(kLogSyslogErr, "Failed to execute SQL for GetPath (%" PRIu64 "): %s",
287  const char *raw_path = (const char *)sqlite3_column_text(stmt_get_path_, 0);
306  lock_ = reinterpret_cast (smalloc(sizeof(pthread_mutex_t)));
307  int retval = pthread_mutex_init(lock_, NULL);
308  assert(retval == 0);
313  if (stmt_add_) sqlite3_finalize(stmt_add_);
314  if (stmt_get_path_) sqlite3_finalize(stmt_get_path_);
315  if (stmt_get_inode_) sqlite3_finalize(stmt_get_inode_);
316  // Close te handles, it is explicitly OK to call close with NULL
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_)
void Assign(const char *chars, const unsigned length)
uint64_t FindInode(const PathString &path)
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)
uint64_t RetryGetInode(const PathString &path, int attempt)
uint64_t IssueInode(const PathString &path)
void SafeSleepMs(const unsigned ms)
const char * c_str() const
const char * GetChars() const
static const char * kSqlAddRoot
static const char * kSqlAddInode
uint32_t Next(const uint64_t boundary)
Generated on Sun Sep 25 2022 00:18:12 for CernVM-FS by 1.8.5