fsal_posixdb_status_t fsal_posixdb_delete(fsal_posixdb_conn * p_conn, /* IN */ posixfsal_handle_t * p_parent_directory_handle, /* IN */ fsal_name_t * p_filename, /* IN */ fsal_posixdb_fileinfo_t * p_object_info /* IN */ ) { result_handle_t res; fsal_posixdb_status_t st; char query[2048]; /******************* * 1/ sanity check * *******************/ if(!p_conn || !p_parent_directory_handle || !p_filename) ReturnCodeDB(ERR_FSAL_POSIXDB_FAULT, 0); BeginTransaction(p_conn); /******************************* * 2/ we check the file exists * *******************************/ snprintf(query, 2048, "SELECT Parent.handleid, Parent.handlets, " "Handle.deviceid, Handle.inode, Handle.nlink, Handle.ctime, Handle.ftype " "FROM Parent INNER JOIN Handle ON Parent.handleid = Handle.handleid " "AND Parent.handlets=Handle.handlets " "WHERE handleidparent=%llu AND handletsparent=%u AND name='%s' " "FOR UPDATE", p_parent_directory_handle->data.id, p_parent_directory_handle->data.ts, p_filename->name); st = db_exec_sql(p_conn, query, &res); if(FSAL_POSIXDB_IS_ERROR(st)) goto rollback; if(mysql_num_rows(res) != 1) { /* parent entry not found */ mysql_free_result(res); RollbackTransaction(p_conn); ReturnCodeDB(ERR_FSAL_POSIXDB_NOENT, 0); } mysql_free_result(res); /*********************************************** * 3/ Get information about the file to delete * ***********************************************/ st = fsal_posixdb_internal_delete(p_conn, p_parent_directory_handle->data.id, p_parent_directory_handle->data.ts, p_filename->name, p_object_info); if(FSAL_POSIXDB_IS_ERROR(st)) goto rollback; return EndTransaction(p_conn); rollback: RollbackTransaction(p_conn); return st; }
bool MySqlConnection::ExecuteTransaction(MySqlTransaction* transaction) { std::list<SQLElementData> const& queries = transaction->m_queries; if (queries.empty()) { TRACE_LOG("MySqlConnection::ExecuteTransaction:quries is empty\n"); return true; } if (!BeginTransaction()) { TRACE_LOG("MySqlConnection::ExecuteTransaction:BeginTransaction\n"); return false; } std::list<SQLElementData>::const_iterator itr; for (itr = queries.begin(); itr != queries.end(); ++itr) { SQLElementData const& data = *itr; switch (itr->type) { case SQL_ELEMENT_PREPARED: { PreparedStmt* stmt = data.element.stmt; if (!Execute(stmt)) { WARNING_LOG("Transaction aborted. %u queries not executed.\n", static_cast<uint32>(queries.size())); RollbackTransaction(); return false; } } break; case SQL_ELEMENT_RAW: { const char* sql = data.element.query; if (!Execute(sql)) { WARNING_LOG("Transaction aborted. %u queries not executed.\n", static_cast<uint32>(queries.size())); RollbackTransaction(); return false; } } break; } } // we might encounter errors during certain queries, and depending on the kind of error // we might want to restart the transaction. So to prevent data loss, we only clean up when it's all done. // This is done in calling functions DatabaseWorkerPool<T>::DirectCommitTransaction and TransactionTask::Execute, // and not while iterating over every element. CommitTransaction(); return true; }
int MySQLConnection::ExecuteTransaction(SQLTransaction& transaction) { std::list<SQLElementData> const& queries = transaction->m_queries; if (queries.empty()) return -1; BeginTransaction(); std::list<SQLElementData>::const_iterator itr; for (itr = queries.begin(); itr != queries.end(); ++itr) { SQLElementData const& data = *itr; switch (itr->type) { case SQL_ELEMENT_PREPARED: { PreparedStatement* stmt = data.element.stmt; ASSERT(stmt); if (!Execute(stmt)) { TC_LOG_WARN("sql.sql", "Transaction aborted. %u queries not executed.", (uint32)queries.size()); int errorCode = GetLastError(); RollbackTransaction(); return errorCode; } } break; case SQL_ELEMENT_RAW: { const char* sql = data.element.query; ASSERT(sql); if (!Execute(sql)) { TC_LOG_WARN("sql.sql", "Transaction aborted. %u queries not executed.", (uint32)queries.size()); int errorCode = GetLastError(); RollbackTransaction(); return errorCode; } } break; } } // we might encounter errors during certain queries, and depending on the kind of error // we might want to restart the transaction. So to prevent data loss, we only clean up when it's all done. // This is done in calling functions DatabaseWorkerPool<T>::DirectCommitTransaction and TransactionTask::Execute, // and not while iterating over every element. CommitTransaction(); return 0; }
void MySqlFactoryDal::CleanupOldRecords(nlib::DateTime olderThanDate, nlib::DateTime olderThanAlertDate) { nlib::DateTime currTime = nlib::CurrentUniversalTime(); const char *pszQry[] ={ "DELETE FROM CommandParameters WHERE CommandID IN (SELECT C.CommandID from Commands C WHERE C.TimePosted < \"%s\");", // +24*7 "DELETE FROM Commands WHERE TimePosted < \"%s\";", // +24*7 "DELETE FROM CommandParameters WHERE CommandID IN (SELECT C.CommandID from Commands C WHERE C.TimePosted < \"%s\" AND (C.CommandStatus = 2 OR C.CommandStatus = 3));", "DELETE FROM Commands WHERE TimePosted < \"%s\" AND (CommandStatus = 2 OR CommandStatus = 3);", "DELETE FROM DeviceReadingsHistory WHERE ReadingTime < \"%s\";", //there is other approach //"DELETE FROM DeviceHistory WHERE Timestamp < \"%s\";", "DELETE FROM DeviceHealthHistory WHERE Timestamp < \"%s\";", "DELETE FROM NeighborHealthHistory WHERE Timestamp < \"%s\";", "DELETE FROM AlertNotifications WHERE AlertTime < \"%s\";", "DELETE FROM DeviceChannelsHistory WHERE Timestamp < \"%s\";", "DELETE FROM ISACSConfirmDataBuffer WHERE Timestamp < \"%s\";", "DELETE FROM Firmwares WHERE UploadStatus = 5 AND UploadDate < \"%s\";" }; LOG("DEBUG CleanupOldRecords START [%s] [%s]", nlib::ToString(olderThanDate).c_str(), nlib::ToString(currTime - nlib::util::hours(24*7)).c_str()); for( int i = 0; i< sizeof(pszQry) / sizeof(pszQry[0]); ++i) { char szQry[ 1024 ]; snprintf( szQry, sizeof(szQry), pszQry[i], (i>=2) ? nlib::ToString(olderThanDate).c_str() : (nlib::ToString(currTime - nlib::util::hours(24*7)).c_str()) ); szQry[ sizeof(szQry)-1 ] = 0; std::string obQry( szQry ); MySQLCommand command(connection, obQry); try { BeginTransaction(); command.ExecuteNonQuery(); CommitTransaction(); } catch(std::exception& ex) { LOG_ERROR("CATCH(exception): CleanupOldRecords failed at step=" << i << " error=" << ex.what()); RollbackTransaction(); } catch(...) { LOG_ERROR("CATCH(...): CleanupOldRecords failed at step=" << i ); RollbackTransaction(); } } LOG_STR("DEBUG CleanupOldRecords END"); }
/** * @brief Lock the line of the Handle table with inode & devid defined in p_info * * @param p_conn * Database connection * @param p_info * Information about the file * * @return ERR_FSAL_POSIXDB_NOERR if no error, * another error code else. */ fsal_posixdb_status_t fsal_posixdb_lockHandleForUpdate(fsal_posixdb_conn * p_conn, /* IN */ fsal_posixdb_fileinfo_t * p_info /* IN */ ) { result_handle_t res; fsal_posixdb_status_t st; char query[2048]; BeginTransaction(p_conn); snprintf(query, 2048, "SELECT handleid, handlets, nlink, ctime, ftype " "FROM Handle WHERE deviceid=%llu AND inode=%llu " "FOR UPDATE", (unsigned long long)p_info->devid, (unsigned long long)p_info->inode); st = db_exec_sql(p_conn, query, &res); if(FSAL_POSIXDB_IS_ERROR(st)) { RollbackTransaction(p_conn); return st; } mysql_free_result(res); /* Do not end the transaction, because it will be closed by the next call to a posixdb function */ ReturnCodeDB(ERR_FSAL_POSIXDB_NOERR, 0); }
bool MySQLConnection::ExecuteTransaction(SQLTransaction& transaction) { std::queue<SQLElementData> &queries = transaction->m_queries; if (queries.empty()) return false; BeginTransaction(); while (!queries.empty()) { SQLElementData data = queries.front(); switch (data.type) { case SQL_ELEMENT_PREPARED: { PreparedStatement* stmt = data.element.stmt; ASSERT(stmt); if (!Execute(stmt)) { sLog->outSQLDriver("[Warning] Transaction aborted. %u queries not executed.", (uint32)queries.size()); RollbackTransaction(); return false; } delete data.element.stmt; } break; case SQL_ELEMENT_RAW: { const char* sql = data.element.query; ASSERT(sql); if (!Execute(sql)) { sLog->outSQLDriver("[Warning] Transaction aborted. %u queries not executed.", (uint32)queries.size()); RollbackTransaction(); return false; } free((void*)const_cast<char*>(sql)); } break; } queries.pop(); } CommitTransaction(); return true; }
bool MySQLConnection::ExecuteTransaction(SQLTransaction& transaction) { std::list<SQLElementData> const& queries = transaction->m_queries; if (queries.empty()) return false; BeginTransaction(); std::list<SQLElementData>::const_iterator itr; for (itr = queries.begin(); itr != queries.end(); ++itr) { SQLElementData const& data = *itr; switch (itr->type) { case SQL_ELEMENT_PREPARED: { PreparedStatement* stmt = data.element.stmt; ASSERT(stmt); if (!Execute(stmt)) { sLog->outSQLDriver("[Warning] Transaktion abgebrochen. %u Anfrage nicht ausgeführt.", (uint32)queries.size()); RollbackTransaction(); return false; } } break; case SQL_ELEMENT_RAW: { const char* sql = data.element.query; ASSERT(sql); if (!Execute(sql)) { sLog->outSQLDriver("[Warning] Transaktion abgebrochen. %u Abfrage nicht ausgeführt.", (uint32)queries.size()); RollbackTransaction(); return false; } } break; } } CommitTransaction(); return true; }
/** * @brief Unlock the Handle line previously locked by fsal_posixdb_lockHandleForUpdate * * @param p_conn * Database connection * * @return ERR_FSAL_POSIXDB_NOERR if no error, * another error code else. */ fsal_posixdb_status_t fsal_posixdb_cancelHandleLock(fsal_posixdb_conn * p_conn /* IN */ ) { PGresult *p_res; PGTransactionStatusType transStatus = PQtransactionStatus(p_conn); if(transStatus == PQTRANS_ACTIVE || transStatus == PQTRANS_INTRANS) { RollbackTransaction(p_conn, p_res); } ReturnCodeDB(ERR_FSAL_POSIXDB_NOERR, 0); }
InterfaceDatabase::~InterfaceDatabase() { try { if (conn_) { RollbackTransaction(); } } catch (...) { } }
/// delete firmware transfers when older than 7 days, regardless of the download status /// TODO: keep application alerts longer void MySqlFactoryDal::CleanupOldAlarmsAndFW(nlib::DateTime olderThanDate) { nlib::DateTime currTime = nlib::CurrentUniversalTime(); const char *pszQry[] ={ "DELETE FROM FirmwareDownloads WHERE StartedOn < \"%s\";", // +24*7 "DELETE FROM AlertNotifications WHERE AlertTime < \"%s\";" }; LOG("DEBUG CleanupOldRecords for Alarms and FW START [%s] [%s]", nlib::ToString(olderThanDate).c_str(), nlib::ToString(currTime - nlib::util::hours(24*1)).c_str()); for( int i = 0; i< sizeof(pszQry) / sizeof(pszQry[0]); ++i) { char szQry[ 1024 ]; snprintf( szQry, sizeof(szQry), pszQry[i], (i>=1) ? nlib::ToString(olderThanDate).c_str() : (nlib::ToString(currTime - nlib::util::hours(24*7)).c_str()) ); szQry[ sizeof(szQry)-1 ] = 0; std::string obQry( szQry ); MySQLCommand command(connection, obQry); try { BeginTransaction(); command.ExecuteNonQuery(); CommitTransaction(); } catch(std::exception& ex) { LOG_ERROR("CATCH(exception): CleanupOldRecords failed at step=" << i << " error=" << ex.what()); RollbackTransaction(); } catch(...) { LOG_ERROR("CATCH(...): CleanupOldRecords failed at step=" << i ); RollbackTransaction(); } } LOG_STR("DEBUG CleanupOldRecords for Alarms and FW END"); }
fsal_posixdb_status_t fsal_posixdb_deleteHandle(fsal_posixdb_conn * p_conn, /* IN */ posixfsal_handle_t * p_parent_directory_handle /* IN */ ) { /* char handleid_str[MAX_HANDLEIDSTR_SIZE]; char handlets_str[MAX_HANDLETSSTR_SIZE]; const char *paramValues[2]; */ int found; result_handle_t res; fsal_posixdb_status_t st; char query[2048]; BeginTransaction(p_conn); LogFullDebug(COMPONENT_FSAL, "Deleting %llu.%u\n", p_parent_directory_handle->data.id, p_parent_directory_handle->data.ts); snprintf(query, 2048, "SELECT Handle.deviceid, Handle.inode, Handle.nlink, Handle.ctime, Handle.ftype " "FROM Handle WHERE handleid=%llu AND handlets=%u FOR UPDATE", p_parent_directory_handle->data.id, p_parent_directory_handle->data.ts); st = db_exec_sql(p_conn, query, &res); if(FSAL_POSIXDB_IS_ERROR(st)) goto rollback; found = mysql_num_rows(res); mysql_free_result(res); if(found) { /* entry found */ st = fsal_posixdb_recursiveDelete(p_conn, p_parent_directory_handle->data.id, p_parent_directory_handle->data.ts, FSAL_TYPE_DIR); if(FSAL_POSIXDB_IS_ERROR(st)) goto rollback; } return EndTransaction(p_conn); rollback: RollbackTransaction(p_conn); return st; }
bool CTextureDatabase::UpdateOldVersion(int version) { BeginTransaction(); try { if (version < 7) { // update all old thumb://foo urls to image://foo?size=thumb m_pDS->query("select id,texture from path where texture like 'thumb://%'"); while (!m_pDS->eof()) { unsigned int id = m_pDS->fv(0).get_asInt(); CURL url(m_pDS->fv(1).get_asString()); m_pDS2->exec(PrepareSQL("update path set texture='image://%s?size=thumb' where id=%u", url.GetHostName().c_str(), id)); m_pDS->next(); } m_pDS->query("select id, url from texture where url like 'thumb://%'"); while (!m_pDS->eof()) { unsigned int id = m_pDS->fv(0).get_asInt(); CURL url(m_pDS->fv(1).get_asString()); m_pDS2->exec(PrepareSQL("update texture set url='image://%s?size=thumb', urlhash=0 where id=%u", url.GetHostName().c_str(), id)); m_pDS->next(); } m_pDS->close(); } if (version < 8) { // get rid of old cached thumbs as they were previously set to the cached thumb name instead of the source thumb m_pDS->exec("delete from path"); } if (version < 9) { // get rid of the old path table and add the type column m_pDS->dropIndex("path", "idxPath"); m_pDS->exec("DROP TABLE path"); m_pDS->exec("CREATE TABLE path (id integer primary key, urlhash integer, url text, type text, texture text)\n"); m_pDS->exec("CREATE INDEX idxPath ON path(urlhash, type)"); } if (version < 10) { // get rid of urlhash in both tables... m_pDS->dropIndex("path", "idxPath"); m_pDS->exec("DROP TABLE path"); m_pDS->exec("CREATE TABLE path (id integer primary key, url text, type text, texture text)\n"); m_pDS->exec("CREATE INDEX idxPath ON path(url, type)"); m_pDS->dropIndex("texture", "idxTexture"); m_pDS->exec("CREATE TEMPORARY TABLE texture_backup(id,url,cachedurl,usecount,lastusetime,imagehash,lasthashcheck)"); m_pDS->exec("INSERT INTO texture_backup SELECT id,url,cachedurl,usecount,lastusetime,imagehash,lasthashcheck FROM texture"); m_pDS->exec("DROP TABLE texture"); m_pDS->exec("CREATE TABLE texture (id integer primary key, url text, cachedurl text, usecount integer, lastusetime text, imagehash text, lasthashcheck text)"); m_pDS->exec("CREATE INDEX idxTexture ON texture(url)"); m_pDS->exec("INSERT INTO texture SELECT * FROM texture_backup"); m_pDS->exec("DROP TABLE texture_backup"); } if (version < 11) { // get rid of cached URLs that don't have the correct extension m_pDS->exec("DELETE FROM texture WHERE SUBSTR(cachedUrl,-4,4) NOT IN ('.jpg', '.png')"); } } catch (...) { CLog::Log(LOGERROR, "%s(%d) failed", __FUNCTION__, version); RollbackTransaction(); return false; } CommitTransaction(); return true; }
fsal_posixdb_status_t fsal_posixdb_getInfoFromHandle(fsal_posixdb_conn * p_conn, /* IN */ posixfsal_handle_t * p_object_handle, /* IN/OUT */ fsal_path_t * p_paths, /* OUT */ int paths_size, /* IN */ int *p_count /* OUT */ ) { fsal_posixdb_status_t st; result_handle_t res; MYSQL_ROW row; posixfsal_handle_t parent_directory_handle; int i_path; int toomanypaths = 0; char query[2048]; /* sanity check */ if(!p_conn || !p_object_handle || ((!p_paths || !p_count) && paths_size > 0)) { ReturnCodeDB(ERR_FSAL_POSIXDB_FAULT, 0); } LogFullDebug(COMPONENT_FSAL, "OBJECT_ID=%lli\n", p_object_handle->data.id); BeginTransaction(p_conn); /* lookup for the handle of the file */ if(!fsal_posixdb_GetInodeCache(p_object_handle)) { snprintf(query, 2048, "SELECT Handle.deviceid, Handle.inode, Handle.nlink, Handle.ctime, Handle.ftype " "FROM Handle WHERE handleid=%llu AND handlets=%u", p_object_handle->data.id, p_object_handle->data.ts); st = db_exec_sql(p_conn, query, &res); if(FSAL_POSIXDB_IS_ERROR(st)) goto rollback; /* p_res contains : Handle.deviceId, Handle.inode, Handle.nlink, Handle.ctime, Handle.ftype */ LogDebug(COMPONENT_FSAL, "lookupHandle(%llu,%u)", p_object_handle->data.id, (unsigned int)p_object_handle->data.ts); if((mysql_num_rows(res) != 1) || ((row = mysql_fetch_row(res)) == NULL)) { LogDebug(COMPONENT_FSAL, "lookupHandle=%d entries", mysql_num_rows(res)); mysql_free_result(res); RollbackTransaction(p_conn); ReturnCodeDB(ERR_FSAL_POSIXDB_NOENT, 0); } posixdb_internal_fillFileinfoFromStrValues(&(p_object_handle->data.info), row[0], row[1], row[2], row[3], row[4]); mysql_free_result(res); /* update the inode */ fsal_posixdb_UpdateInodeCache(p_object_handle); } /* Build the paths of the object */ if(p_paths) { /* find all the paths to the object */ snprintf(query, 2048, "SELECT name, handleidparent, handletsparent " "FROM Parent WHERE handleid=%llu AND handlets=%u", p_object_handle->data.id, p_object_handle->data.ts); st = db_exec_sql(p_conn, query, &res); if(FSAL_POSIXDB_IS_ERROR(st)) goto rollback; /* res contains name, handleidparent, handletsparent */ *p_count = mysql_num_rows(res); if(*p_count == 0) { mysql_free_result(res); RollbackTransaction(p_conn); ReturnCodeDB(ERR_FSAL_POSIXDB_NOPATH, 0); } else if(*p_count > paths_size) { toomanypaths = 1; LogCrit(COMPONENT_FSAL, "Too many paths found for object %llu.%u: found=%u, max=%d", p_object_handle->data.id, p_object_handle->data.ts, *p_count, paths_size); *p_count = paths_size; } for(i_path = 0; i_path < *p_count; i_path++) { unsigned int tmp_len; row = mysql_fetch_row(res); if(row == NULL) { mysql_free_result(res); RollbackTransaction(p_conn); ReturnCodeDB(ERR_FSAL_POSIXDB_FAULT, 0); } /* build the path of the parent directory */ parent_directory_handle.data.id = atoll(row[1]); parent_directory_handle.data.ts = atoi(row[2]); st = fsal_posixdb_buildOnePath(p_conn, &parent_directory_handle, &p_paths[i_path]); if(FSAL_POSIXDB_IS_ERROR(st)) goto free_res; tmp_len = p_paths[i_path].len; if((tmp_len > 0) && (p_paths[i_path].path[tmp_len - 1] == '/')) { /* then concatenate the name of the file */ /* but not concatenate '/' */ if((tmp_len + strlen(row[0]) >= FSAL_MAX_PATH_LEN)) { mysql_free_result(res); RollbackTransaction(p_conn); ReturnCodeDB(ERR_FSAL_POSIXDB_PATHTOOLONG, 0); } strcpy(&p_paths[i_path].path[tmp_len], row[0]); p_paths[i_path].len += strlen(row[0]); } else { /* then concatenate the name of the file */ if((tmp_len + 1 + strlen(row[0]) >= FSAL_MAX_PATH_LEN)) { mysql_free_result(res); RollbackTransaction(p_conn); ReturnCodeDB(ERR_FSAL_POSIXDB_PATHTOOLONG, 0); } p_paths[i_path].path[tmp_len] = '/'; strcpy(&p_paths[i_path].path[tmp_len + 1], row[0]); p_paths[i_path].len += 1 + strlen(row[0]); } /* insert the object into cache */ fsal_posixdb_CachePath(p_object_handle, &p_paths[i_path]); } mysql_free_result(res); } st = EndTransaction(p_conn); if(toomanypaths) ReturnCodeDB(ERR_FSAL_POSIXDB_TOOMANYPATHS, 0); else return st; free_res: mysql_free_result(res); rollback: RollbackTransaction(p_conn); return st; }
fsal_posixdb_status_t fsal_posixdb_getInfoFromName(fsal_posixdb_conn * p_conn, /* IN */ posixfsal_handle_t * p_parent_directory_handle, /* IN/OUT */ fsal_name_t * p_objectname, /* IN */ fsal_path_t * p_path, /* OUT */ posixfsal_handle_t * p_handle /* OUT */ ) { fsal_posixdb_status_t st; char query[2048]; result_handle_t res; MYSQL_ROW row; /* sanity check */ if(!p_conn || !p_handle) { ReturnCodeDB(ERR_FSAL_POSIXDB_FAULT, 0); } LogFullDebug(COMPONENT_FSAL, "object_name='%s'\n", p_objectname->name ? p_objectname->name : "/"); BeginTransaction(p_conn); /* lookup for the handle of the file */ if(p_parent_directory_handle && p_parent_directory_handle->data.id) { snprintf(query, 2048, "SELECT Parent.handleid, Parent.handlets, Handle.deviceid, " "Handle.inode, Handle.nlink, Handle.ctime, Handle.ftype " "FROM Parent INNER JOIN Handle ON Parent.handleid = Handle.handleid AND Parent.handlets=Handle.handlets " "WHERE handleidparent=%llu AND handletsparent=%u AND name='%s'", p_parent_directory_handle->data.id, p_parent_directory_handle->data.ts, p_objectname->name); st = db_exec_sql(p_conn, query, &res); if(FSAL_POSIXDB_IS_ERROR(st)) goto rollback; } else { /* get root handle: */ st = db_exec_sql(p_conn, "SELECT Parent.handleid, Parent.handlets, Handle.deviceid, Handle.inode, Handle.nlink, Handle.ctime, Handle.ftype " "FROM Parent INNER JOIN Handle ON Parent.handleid = Handle.handleid AND Parent.handlets=Handle.handlets " "WHERE Parent.handleidparent=Parent.handleid AND Parent.handletsparent=Parent.handlets", &res); if(FSAL_POSIXDB_IS_ERROR(st)) goto rollback; } /* res contains : Parent.handleid, Parent.handlets, Handle.deviceid, Handle.inode, Handle.nlink, Handle.ctime, Handle.ftype */ /* entry not found */ if((mysql_num_rows(res) != 1) || ((row = mysql_fetch_row(res)) == NULL)) { mysql_free_result(res); RollbackTransaction(p_conn); ReturnCodeDB(ERR_FSAL_POSIXDB_NOENT, 0); } p_handle->data.id = atoll(row[0]); p_handle->data.ts = atoi(row[1]); posixdb_internal_fillFileinfoFromStrValues(&(p_handle->data.info), row[2], row[3], /* devid, inode */ row[4], /* nlink */ row[5], /* ctime */ row[6]); /* ftype */ mysql_free_result(res); /* Build the path of the object */ if(p_path && p_objectname) { /* build the path of the Parent */ st = fsal_posixdb_buildOnePath(p_conn, p_parent_directory_handle, p_path); if(FSAL_POSIXDB_IS_ERROR(st)) goto rollback; /* then concatenate the filename */ if(!(p_path->len + 1 + p_objectname->len < FSAL_MAX_PATH_LEN)) { RollbackTransaction(p_conn); ReturnCodeDB(ERR_FSAL_POSIXDB_PATHTOOLONG, 0); } p_path->path[p_path->len] = '/'; strcpy(&p_path->path[p_path->len + 1], p_objectname->name); p_path->len += 1 + p_objectname->len; /* add the the path to cache */ fsal_posixdb_CachePath(p_handle, p_path); } else { /* update handle if it was in cache */ fsal_posixdb_UpdateInodeCache(p_handle); } return EndTransaction(p_conn); rollback: RollbackTransaction(p_conn); return st; }
fsal_posixdb_status_t fsal_posixdb_add(fsal_posixdb_conn * p_conn, /* IN */ fsal_posixdb_fileinfo_t * p_object_info, /* IN */ posixfsal_handle_t * p_parent_directory_handle, /* IN */ fsal_name_t * p_filename, /* IN */ posixfsal_handle_t * p_object_handle /* OUT */ ) { PGresult *p_res; char handleid_str[MAX_HANDLEIDSTR_SIZE]; char handlets_str[MAX_HANDLETSSTR_SIZE]; char handleidparent_str[MAX_HANDLEIDSTR_SIZE]; char handletsparent_str[MAX_HANDLETSSTR_SIZE]; char devid_str[MAX_DEVICEIDSTR_SIZE]; char inode_str[MAX_INODESTR_SIZE]; int found; const char *paramValues[6]; fsal_posixdb_status_t st; /******************* * 1/ sanity check * *******************/ /* parent_directory and filename are NULL only if it is the root directory */ if(!p_conn || !p_object_info || !p_object_handle || (p_filename && !p_parent_directory_handle) || (!p_filename && p_parent_directory_handle)) ReturnCodeDB(ERR_FSAL_POSIXDB_FAULT, 0); CheckConn(p_conn); LogFullDebug(COMPONENT_FSAL, "adding entry with parentid=%llu, id=%"PRIu64", name=%s\n", p_parent_directory_handle ? p_parent_directory_handle->data.id : 0, p_object_info ? p_object_info->inode : 0, p_filename ? p_filename->name : "NULL"); BeginTransaction(p_conn, p_res); /********************************* * 2/ we check the parent handle * *********************************/ if(p_parent_directory_handle) { /* the root has no parent */ snprintf(handleidparent_str, MAX_HANDLEIDSTR_SIZE, "%llu", p_parent_directory_handle->data.id); snprintf(handletsparent_str, MAX_HANDLETSSTR_SIZE, "%i", p_parent_directory_handle->data.ts); paramValues[0] = handleidparent_str; paramValues[1] = handletsparent_str; p_res = PQexecPrepared(p_conn, "lookupHandle", 2, paramValues, NULL, NULL, 0); CheckResult(p_res); if(PQntuples(p_res) != 1) { /* parent entry not found */ RollbackTransaction(p_conn, p_res); ReturnCodeDB(ERR_FSAL_POSIXDB_NOENT, 0); } PQclear(p_res); } /********************************************************** * 3/ Check if there is an existing Handle for the object * **********************************************************/ snprintf(devid_str, MAX_DEVICEIDSTR_SIZE, "%llu", (unsigned long long int)p_object_info->devid); snprintf(inode_str, MAX_INODESTR_SIZE, "%llu", (unsigned long long int)p_object_info->inode); paramValues[0] = devid_str; paramValues[1] = inode_str; p_res = PQexecPrepared(p_conn, "lookupHandleByInodeFU", 2, paramValues, NULL, NULL, 0); CheckResult(p_res); found = (PQntuples(p_res) == 1); if(found) { /* a Handle (that matches devid & inode) already exists */ /* fill 'info' with information about the handle in the database */ posixdb_internal_fillFileinfoFromStrValues(&(p_object_handle->data.info), NULL, NULL, PQgetvalue(p_res, 0, 2), /* nlink */ PQgetvalue(p_res, 0, 3), /* ctime */ PQgetvalue(p_res, 0, 4) /* ftype */ ); p_object_handle->data.info.inode = p_object_info->inode; p_object_handle->data.info.devid = p_object_info->devid; strncpy(handleid_str, PQgetvalue(p_res, 0, 0), MAX_HANDLEIDSTR_SIZE); strncpy(handlets_str, PQgetvalue(p_res, 0, 1), MAX_HANDLETSSTR_SIZE); PQclear(p_res); p_object_handle->data.id = atoll(handleid_str); p_object_handle->data.ts = atoi(handlets_str); /* check the consistency of the handle */ if(fsal_posixdb_consistency_check(&(p_object_handle->data.info), p_object_info)) { /* consistency check failed */ /* p_object_handle has been filled in order to be able to fix the consistency later */ RollbackTransaction(p_conn, p_res); ReturnCodeDB(ERR_FSAL_POSIXDB_CONSISTENCY, 0); } /* update nlink & ctime if needed */ if(p_object_info->nlink != p_object_handle->data.info.nlink || p_object_info->ctime != p_object_handle->data.info.ctime) { char nlink_str[MAX_NLINKSTR_SIZE]; char ctime_str[MAX_CTIMESTR_SIZE]; snprintf(nlink_str, MAX_NLINKSTR_SIZE, "%i", p_object_info->nlink); snprintf(ctime_str, MAX_CTIMESTR_SIZE, "%i", (int)p_object_info->ctime); paramValues[0] = handleid_str; paramValues[1] = handlets_str; paramValues[2] = nlink_str; paramValues[3] = ctime_str; p_object_handle->data.info = *p_object_info; p_res = PQexecPrepared(p_conn, "updateHandle", 4, paramValues, NULL, NULL, 0); CheckCommand(p_res); } fsal_posixdb_UpdateInodeCache(p_object_handle); } else { /* no handle found */ /* Handle does not exist, add a new Handle entry */ char nlink_str[MAX_NLINKSTR_SIZE]; char ctime_str[MAX_CTIMESTR_SIZE]; char ftype_str[MAX_FTYPESTR_SIZE]; PQclear(p_res); p_object_handle->data.ts = (int)time(NULL); p_object_handle->data.info = *p_object_info; snprintf(handlets_str, MAX_HANDLETSSTR_SIZE, "%i", p_object_handle->data.ts); snprintf(nlink_str, MAX_NLINKSTR_SIZE, "%i", p_object_info->nlink); snprintf(ctime_str, MAX_CTIMESTR_SIZE, "%i", (int)p_object_info->ctime); snprintf(ftype_str, MAX_CTIMESTR_SIZE, "%i", (int)p_object_info->ftype); paramValues[0] = devid_str; paramValues[1] = inode_str; paramValues[2] = handlets_str; paramValues[3] = nlink_str; paramValues[4] = ctime_str; paramValues[5] = ftype_str; p_res = PQexecPrepared(p_conn, "insertHandle", 6, paramValues, NULL, NULL, 0); CheckCommand(p_res); PQclear(p_res); p_res = PQexecPrepared(p_conn, "lookupHandleByInodeFU", 2, paramValues, NULL, NULL, 0); CheckResult(p_res); strncpy(handleid_str, PQgetvalue(p_res, 0, 0), MAX_HANDLEIDSTR_SIZE); strncpy(handlets_str, PQgetvalue(p_res, 0, 1), MAX_HANDLETSSTR_SIZE); p_object_handle->data.id = atoll(PQgetvalue(p_res, 0, 0)); PQclear(p_res); /* now, we have the handle id */ fsal_posixdb_UpdateInodeCache(p_object_handle); } /************************************************ * add (or update) an entry in the Parent table * ************************************************/ paramValues[0] = p_parent_directory_handle ? handleidparent_str : handleid_str; paramValues[1] = p_parent_directory_handle ? handletsparent_str : handlets_str; paramValues[2] = p_filename ? p_filename->name : ""; p_res = PQexecPrepared(p_conn, "lookupParent", 3, paramValues, NULL, NULL, 0); CheckResult(p_res); /* p-res contains handleid & handlets */ found = (PQntuples(p_res) == 1); paramValues[3] = handleid_str; paramValues[4] = handlets_str; if(found) { /* update the Parent entry if necessary (there entry exists with another handle) */ if((fsal_u64_t) atoll(PQgetvalue(p_res, 0, 0)) != p_object_handle->data.id || atoi(PQgetvalue(p_res, 0, 1)) != p_object_handle->data.ts) { /* steps : - check the nlink value of the Parent entry to be overwritten - if nlink = 1, then we can delete the handle. else we have to update it (nlink--) : that is done by fsal_posixdb_deleteParent - update the handle of the entry */ char bad_handleid_str[MAX_HANDLEIDSTR_SIZE]; char bad_handlets_str[MAX_HANDLETSSTR_SIZE]; int nlink; strncpy(bad_handleid_str, PQgetvalue(p_res, 0, 0), MAX_HANDLEIDSTR_SIZE); strncpy(bad_handlets_str, PQgetvalue(p_res, 0, 1), MAX_HANDLETSSTR_SIZE); PQclear(p_res); /* clear old res before a new query */ /* check the nlink value of the entry to be updated */ paramValues[0] = handleidparent_str; paramValues[1] = handletsparent_str; p_res = PQexecPrepared(p_conn, "lookupHandleFU", 2, paramValues, NULL, NULL, 0); CheckResult(p_res); found = (PQntuples(p_res) == 1); if(found) { /* we have retrieved the handle information of the bad entry */ nlink = atoi(PQgetvalue(p_res, 0, 4)); PQclear(p_res); /* clear old res before a new query */ /* a Parent entry already exists, we delete it */ st = fsal_posixdb_deleteParent(p_conn, bad_handleid_str, bad_handlets_str, p_parent_directory_handle ? handleidparent_str : handleid_str, p_parent_directory_handle ? handletsparent_str : handlets_str, p_filename ? p_filename->name : "", nlink); if(FSAL_POSIXDB_IS_ERROR(st)) { RollbackTransaction(p_conn, p_res); return st; } } else { /* the Handle line has been deleted */ PQclear(p_res); /* clear old res before a new query */ } /* the bad entry has been deleted. Now we had a new Parent entry */ goto add_new_parent_entry; } else { /* a Parent entry exists with our handle, nothing to do */ PQclear(p_res); } } else { /* add a Parent entry */ PQclear(p_res); add_new_parent_entry: paramValues[0] = p_parent_directory_handle ? handleidparent_str : handleid_str; paramValues[1] = p_parent_directory_handle ? handletsparent_str : handlets_str; paramValues[2] = p_filename ? p_filename->name : ""; paramValues[3] = handleid_str; paramValues[4] = handlets_str; p_res = PQexecPrepared(p_conn, "insertParent", 5, paramValues, NULL, NULL, 0); CheckCommand(p_res); PQclear(p_res); /* XXX : is it possible to have unique key violation ? */ } EndTransaction(p_conn, p_res); ReturnCodeDB(ERR_FSAL_POSIXDB_NOERR, 0); }
fsal_posixdb_status_t fsal_posixdb_getInfoFromHandle(fsal_posixdb_conn * p_conn, /* IN */ posixfsal_handle_t * p_object_handle, /* IN/OUT */ fsal_path_t * p_paths, /* OUT */ int paths_size, /* IN */ int *p_count /* OUT */ ) { PGresult *p_res; fsal_posixdb_status_t st; char handleid_str[MAX_HANDLEIDSTR_SIZE]; char handlets_str[MAX_HANDLETSSTR_SIZE]; posixfsal_handle_t parent_directory_handle; int i_path; int toomanypaths = 0; const char *paramValues[2] = { handleid_str, handlets_str }; /* sanity check */ if(!p_conn || !p_object_handle || ((!p_paths || !p_count) && paths_size > 0)) { ReturnCodeDB(ERR_FSAL_POSIXDB_FAULT, 0); } CheckConn(p_conn); LogFullDebug(COMPONENT_FSAL, "OBJECT_ID=%lli\n", p_object_handle->data.id); BeginTransaction(p_conn, p_res); /* lookup for the handle of the file */ snprintf(handleid_str, MAX_HANDLEIDSTR_SIZE, "%lli", p_object_handle->data.id); snprintf(handlets_str, MAX_HANDLETSSTR_SIZE, "%i", p_object_handle->data.ts); if(!fsal_posixdb_GetInodeCache(p_object_handle)) { p_res = PQexecPrepared(p_conn, "lookupHandle", 2, paramValues, NULL, NULL, 0); CheckResult(p_res); /* p_res contains : Handle.deviceId, Handle.inode, Handle.nlink, Handle.ctime, Handle.ftype */ LogDebug(COMPONENT_FSAL, "lookupHandle(%u,%u)", (unsigned int)p_object_handle->data.id, (unsigned int)p_object_handle->data.ts); /* entry not found */ if(PQntuples(p_res) != 1) { LogDebug(COMPONENT_FSAL, "lookupHandle=%d entries", PQntuples(p_res)); RollbackTransaction(p_conn, p_res); ReturnCodeDB(ERR_FSAL_POSIXDB_NOENT, 0); } posixdb_internal_fillFileinfoFromStrValues(&(p_object_handle->data.info), PQgetvalue(p_res, 0, 0), PQgetvalue(p_res, 0, 1), PQgetvalue(p_res, 0, 2), /* nlink */ PQgetvalue(p_res, 0, 3), /* ctime */ PQgetvalue(p_res, 0, 4) /* ftype */ ); PQclear(p_res); /* update the inode */ fsal_posixdb_UpdateInodeCache(p_object_handle); } /* Build the paths of the object */ if(p_paths) { /* find all the paths to the object */ p_res = PQexecPrepared(p_conn, "lookupPaths", 2, paramValues, NULL, NULL, 0); CheckResult(p_res); /* p_res contains name, handleidparent, handletsparent */ *p_count = PQntuples(p_res); if(*p_count == 0) { RollbackTransaction(p_conn, p_res); ReturnCodeDB(ERR_FSAL_POSIXDB_NOPATH, 0); } if(*p_count > paths_size) { toomanypaths = 1; LogCrit(COMPONENT_FSAL, "Too many paths found for object %s.%s: found=%u, max=%d", handleid_str, handlets_str, *p_count, paths_size); *p_count = paths_size; } for(i_path = 0; i_path < *p_count; i_path++) { unsigned int tmp_len; /* build the path of the parent directory */ parent_directory_handle.data.id = atoll(PQgetvalue(p_res, i_path, 1)); parent_directory_handle.data.ts = atoi(PQgetvalue(p_res, i_path, 2)); st = fsal_posixdb_buildOnePath(p_conn, &parent_directory_handle, &p_paths[i_path]); if(st.major != ERR_FSAL_POSIXDB_NOERR) { RollbackTransaction(p_conn, p_res); return st; } tmp_len = p_paths[i_path].len; if((tmp_len > 0) && (p_paths[i_path].path[tmp_len - 1] == '/')) { /* then concatenate the name of the file */ /* but not concatenate '/' */ if((tmp_len + strlen(PQgetvalue(p_res, i_path, 0)) >= FSAL_MAX_PATH_LEN)) { RollbackTransaction(p_conn, p_res); ReturnCodeDB(ERR_FSAL_POSIXDB_PATHTOOLONG, 0); } strcpy(&p_paths[i_path].path[tmp_len], PQgetvalue(p_res, i_path, 0)); p_paths[i_path].len += strlen(PQgetvalue(p_res, i_path, 0)); } else { /* then concatenate the name of the file */ if((tmp_len + 1 + strlen(PQgetvalue(p_res, i_path, 0)) >= FSAL_MAX_PATH_LEN)) { RollbackTransaction(p_conn, p_res); ReturnCodeDB(ERR_FSAL_POSIXDB_PATHTOOLONG, 0); } p_paths[i_path].path[tmp_len] = '/'; strcpy(&p_paths[i_path].path[tmp_len + 1], PQgetvalue(p_res, i_path, 0)); p_paths[i_path].len += 1 + strlen(PQgetvalue(p_res, i_path, 0)); } /* insert the object into cache */ fsal_posixdb_CachePath(p_object_handle, &p_paths[i_path]); } PQclear(p_res); } EndTransaction(p_conn, p_res); ReturnCodeDB(toomanypaths ? ERR_FSAL_POSIXDB_TOOMANYPATHS : ERR_FSAL_POSIXDB_NOERR, 0); }
fsal_posixdb_status_t fsal_posixdb_getInfoFromName(fsal_posixdb_conn * p_conn, /* IN */ posixfsal_handle_t * p_parent_directory_handle, /* IN/OUT */ fsal_name_t * p_objectname, /* IN */ fsal_path_t * p_path, /* OUT */ posixfsal_handle_t * p_handle /* OUT */ ) { PGresult *p_res; fsal_posixdb_status_t st; char handleid_str[MAX_HANDLEIDSTR_SIZE]; char handlets_str[MAX_HANDLETSSTR_SIZE]; const char *paramValues[3] = { handleid_str, handlets_str, p_objectname->name }; /* sanity check */ if(!p_conn || !p_handle) { ReturnCodeDB(ERR_FSAL_POSIXDB_FAULT, 0); } CheckConn(p_conn); LogFullDebug(COMPONENT_FSAL, "object_name='%s'\n", p_objectname->name); BeginTransaction(p_conn, p_res); /* lookup for the handle of the file */ if(p_parent_directory_handle && p_parent_directory_handle->data.id) { snprintf(handleid_str, MAX_HANDLEIDSTR_SIZE, "%lli", p_parent_directory_handle->data.id); snprintf(handlets_str, MAX_HANDLETSSTR_SIZE, "%i", p_parent_directory_handle->data.ts); p_res = PQexecPrepared(p_conn, "lookupHandleByName", 3, paramValues, NULL, NULL, 0); CheckResult(p_res); } else { // get root handle : p_res = PQexecPrepared(p_conn, "lookupRootHandle", 0, NULL, NULL, NULL, 0); CheckResult(p_res); } /* p_res contains : Parent.handleid, Parent.handlets, Handle.deviceId, Handle.inode, Handle.nlink, Handle.ctime, Handle.ftype */ /* entry not found */ if(PQntuples(p_res) != 1) { PQclear(p_res); RollbackTransaction(p_conn, p_res); ReturnCodeDB(ERR_FSAL_POSIXDB_NOENT, 0); } p_handle->data.id = atoll(PQgetvalue(p_res, 0, 0)); p_handle->data.ts = atoi(PQgetvalue(p_res, 0, 1)); posixdb_internal_fillFileinfoFromStrValues(&(p_handle->data.info), PQgetvalue(p_res, 0, 2), PQgetvalue(p_res, 0, 3), PQgetvalue(p_res, 0, 4), /* nlink */ PQgetvalue(p_res, 0, 5), /* ctime */ PQgetvalue(p_res, 0, 6) /* ftype */ ); PQclear(p_res); /* Build the path of the object */ if(p_path && p_objectname) { /* build the path of the Parent */ st = fsal_posixdb_buildOnePath(p_conn, p_parent_directory_handle, p_path); if(st.major != ERR_FSAL_POSIXDB_NOERR) { RollbackTransaction(p_conn, p_res); return st; } /* then concatenate the filename */ if(!(p_path->len + 1 + p_objectname->len < FSAL_MAX_PATH_LEN)) { RollbackTransaction(p_conn, p_res); ReturnCodeDB(ERR_FSAL_POSIXDB_PATHTOOLONG, 0); } p_path->path[p_path->len] = '/'; strcpy(&p_path->path[p_path->len + 1], p_objectname->name); p_path->len += 1 + p_objectname->len; /* add the the path to cache */ fsal_posixdb_CachePath(p_handle, p_path); } else { /* update handle if it was in cache */ fsal_posixdb_UpdateInodeCache(p_handle); } EndTransaction(p_conn, p_res); ReturnCodeDB(ERR_FSAL_POSIXDB_NOERR, 0); }
/** * @brief Unlock the Handle line previously locked by fsal_posixdb_lockHandleForUpdate * * @param p_conn * Database connection * * @return ERR_FSAL_POSIXDB_NOERR if no error, * another error code else. */ fsal_posixdb_status_t fsal_posixdb_cancelHandleLock(fsal_posixdb_conn * p_conn /* IN */ ) { RollbackTransaction(p_conn); ReturnCodeDB(ERR_FSAL_POSIXDB_NOERR, 0); }
void KernelTransaction::rollback(){ RollbackTransaction(this->tx); }