12 #include "maintagent.h"
26 PGresult *
PQexecCheck(
int exitNumber,
char *
SQL,
char *file,
const int line)
55 long startTime, endTime;
58 strncpy(SQL_analyze,
"ANALYZE",
sizeof(SQL_analyze));
64 if (serverVersion > 0)
66 serverMajor = serverVersion / 10000;
68 if (serverMajor >= 17)
70 snprintf(SQL_vacuum,
sizeof(SQL_vacuum),
"VACUUM FULL");
74 snprintf(SQL_vacuum,
sizeof(SQL_vacuum),
"VACUUM");
80 strncat(SQL_vacuum,
" VERBOSE",
81 sizeof(SQL_vacuum) - strlen(SQL_vacuum) - 1);
82 strncat(SQL_analyze,
" VERBOSE",
83 sizeof(SQL_analyze) - strlen(SQL_analyze) - 1);
86 startTime = (long) time(0);
87 double _start = now_monotonic_seconds();
88 log_action_start(
"vacAnalyze (2 Queries)");
92 char desc_analyze[80];
93 snprintf(desc_vac,
sizeof(desc_vac),
"vacAnalyze: 1/2 - VACUUM");
94 if (serverMajor >= 17)
96 strncat(desc_vac,
" FULL",
sizeof(desc_vac) - strlen(desc_vac) - 1);
100 strncat(desc_vac,
" VERBOSE",
sizeof(desc_vac) - strlen(desc_vac) - 1);
102 snprintf(desc_analyze,
sizeof(desc_analyze),
"vacAnalyze: 2/2 - ANALYZE");
105 strncat(desc_analyze,
" VERBOSE",
106 sizeof(desc_analyze) - strlen(desc_analyze) - 1);
111 log_action_end(desc_vac, _start);
115 log_action_end(desc_analyze, _start);
117 endTime = (long) time(0);
118 printf(
"Vacuum/Analyze took %ld seconds\n", endTime - startTime);
120 log_action_end(
"vacAnalyze", _start);
137 char *invalidUploadRefs =
"DELETE FROM foldercontents WHERE foldercontents_mode = 2 AND child_id NOT IN (SELECT upload_pk FROM upload)";
138 char *invalidUploadtreeRefs =
"DELETE FROM foldercontents WHERE foldercontents_mode = 4 AND child_id NOT IN (SELECT uploadtree_pk FROM uploadtree)";
139 char *unRefFolders =
"DELETE FROM folder WHERE folder_pk \
140 NOT IN (SELECT child_id FROM foldercontents WHERE foldercontents_mode = 1) AND folder_pk != '1'";
141 long startTime, endTime;
143 startTime = (long)time(0);
145 double _start = now_monotonic_seconds();
146 log_action_start(
"validateFolders");
149 result =
PQexecCheck(-120, invalidUploadRefs, __FILE__, __LINE__);
150 countTuples = PQcmdTuples(result);
152 printf(
"%s Invalid folder upload References\n", countTuples);
155 result =
PQexecCheck(-121, invalidUploadtreeRefs, __FILE__, __LINE__);
156 countTuples = PQcmdTuples(result);
158 printf(
"%s Invalid folder uploadtree References\n", countTuples);
161 result =
PQexecCheck(-122, unRefFolders, __FILE__, __LINE__);
162 countTuples = PQcmdTuples(result);
164 printf(
"%s unreferenced folders\n", countTuples);
166 endTime = (long)time(0);
167 printf(
"Validate folders took %ld seconds\n", endTime-startTime);
169 log_action_end(
"validateFolders", _start);
206 LOG_NOTICE(
"Verify file permissions is not implemented yet");
221 long startTime, endTime;
226 double _start = now_monotonic_seconds();
227 log_action_start(
"removeUploads (4 Queries)");
229 startTime = (long)time(0);
232 snprintf(tempTable,
sizeof(tempTable),
"tmp_ids_%d", getpid());
234 snprintf(SQLBuf, MAXSQL,
"CREATE TEMP TABLE %s(id bigint);", tempTable);
236 log_action_end(
"removeUploads: 1/4 - temp table creation", _start);
240 snprintf(SQLBuf, MAXSQL,
241 "INSERT INTO %s (id) SELECT upload_fk FROM uploadtree WHERE parent "
242 "IS NULL AND pfile_fk IS NULL;",
245 log_action_end(
"removeUploads: 2/4 - first set insertion", _start);
249 snprintf(SQLBuf, MAXSQL,
250 "INSERT INTO %s (id) SELECT upload_pk FROM upload WHERE upload_pk "
251 "NOT IN (SELECT upload_fk FROM uploadtree) AND (expire_action IS "
252 "NULL OR expire_action != 'd') AND pfile_fk IS NOT NULL;",
255 log_action_end(
"removeUploads: 3/4 - second set insertion", _start);
258 snprintf(SQLBuf, MAXSQL,
259 "DELETE FROM upload USING %s WHERE upload.upload_pk = %s.id;",
260 tempTable, tempTable);
261 result =
PQexecCheck(-133, SQLBuf, __FILE__, __LINE__);
262 countTuples = PQcmdTuples(result);
264 log_action_end(
"removeUploads: 4/4 - deletion", _start);
266 endTime = (long)time(0);
267 printf(
"%s Uploads with no pfiles (%ld seconds)\n", countTuples, endTime-startTime);
269 log_action_end(
"removeUploads (4 Queries)", _start);
272 snprintf(SQLBuf, MAXSQL,
"DROP TABLE IF EXISTS %s;", tempTable);
289 int droppedCount = 0;
291 long startTime, endTime;
293 double _start = now_monotonic_seconds();
294 log_action_start(
"removeTemps");
297 "SELECT table_name FROM information_schema.tables WHERE table_type = 'BASE TABLE' "
298 "AND table_schema = 'public' AND (table_name ~ '^metaanalysis_[[:digit:]]+$' "
299 "OR table_name LIKE 'delup_%');";
301 startTime = (long)time(0);
305 countTuples = PQntuples(result);
307 for (row = 0; row < countTuples; row++) {
308 snprintf(SQLBuf, MAXSQL,
"DROP TABLE %s", PQgetvalue(result, row, 0));
314 endTime = (long)time(0);
315 printf(
"%d Orphaned temp tables were dropped (%ld seconds)\n", droppedCount, endTime-startTime);
317 log_action_end(
"removeTemps", _start);
340 LOG_NOTICE(
"Process expired uploads is not implemented yet");
355 long StartTime, EndTime;
356 double _start = now_monotonic_seconds();
357 log_action_start(
"removeOrphanedFiles");
360 char filesPath[myBUFSIZ];
362 StartTime = (long)time(0);
365 strncpy(filesPath, repoPath, myBUFSIZ - 1);
366 strncat(filesPath,
"/localhost/files", myBUFSIZ - 1);
368 if (access(filesPath, R_OK | W_OK) != 0)
370 LOG_ERROR(
"Files path is not readable/writeable: '%s'", filesPath);
377 EndTime = (long)time(0);
378 printf(
"Remove orphaned files from the repository took %ld seconds\n",
379 EndTime - StartTime);
381 log_action_end(
"removeOrphanedFiles", _start);
395 long StartTime, EndTime;
396 double _start = now_monotonic_seconds();
397 log_action_start(
"deleteOrphanGold");
400 char goldPath[myBUFSIZ];
402 StartTime = (long)time(0);
405 strncpy(goldPath, repoPath, myBUFSIZ - 1);
406 strncat(goldPath,
"/localhost/gold", myBUFSIZ - 1);
408 if (access(goldPath, R_OK | W_OK) != 0)
410 LOG_ERROR(
"Gold path is not readable/writeable: '%s'", goldPath);
417 EndTime = (long)time(0);
418 printf(
"Remove orphaned gold files from the repository took %ld seconds\n",
419 EndTime - StartTime);
421 log_action_end(
"deleteOrphanGold", _start);
432 long startTime, endTime;
433 double _start = now_monotonic_seconds();
434 log_action_start(
"normalizeUploadPriorities (3 Queries)");
437 "CREATE TEMPORARY TABLE tmp_upload_prio(ordprio serial, uploadid int, groupid int)";
439 "INSERT INTO tmp_upload_prio (uploadid, groupid) "
440 "(SELECT upload_fk uploadid, group_fk groupid FROM upload_clearing ORDER BY priority ASC);";
442 "UPDATE upload_clearing "
443 "SET priority = ordprio FROM tmp_upload_prio "
444 "WHERE uploadid=upload_fk AND group_fk=groupid;";
446 startTime = (long)time(0);
449 log_action_end(
"normalizeUploadPriorities: 1/3", _start);
452 log_action_end(
"normalizeUploadPriorities: 2/3", _start);
455 log_action_end(
"normalizeUploadPriorities: 3/3", _start);
457 endTime = (long)time(0);
458 printf(
"Normalized upload priorities (%ld seconds)\n", endTime-startTime);
460 log_action_end(
"normalizeUploadPriorities (3 Queries)", _start);
474 long startTime, endTime;
475 double _start = now_monotonic_seconds();
476 log_action_start(
"reIndexAllTables");
479 "SELECT table_catalog FROM information_schema.tables WHERE table_type = "
480 "'BASE TABLE' AND table_schema = 'public' AND table_name LIKE"
483 startTime = (long)time(0);
488 memset(SQLBuf,
'\0',
sizeof(SQLBuf));
489 snprintf(SQLBuf,
sizeof(SQLBuf),
"REINDEX DATABASE %s;", PQgetvalue(result, 0, 0));
493 endTime = (long)time(0);
494 printf(
"Time taken for reindexing the database : %ld seconds\n", endTime-startTime);
496 log_action_end(
"reIndexAllTables", _start);
510 long startTime, endTime;
511 double _start = now_monotonic_seconds();
512 log_action_start(
"removeOrphanedRows (6 Queries)");
515 "DELETE FROM uploadtree UT "
516 " WHERE NOT EXISTS ( "
519 " WHERE UT.upload_fk = U.upload_pk "
523 "DELETE FROM clearing_decision AS CD "
524 " WHERE NOT EXISTS ( "
526 " FROM uploadtree UT "
527 " WHERE CD.uploadtree_fk = UT.uploadtree_pk "
528 " ) AND CD.scope = '0';";
531 "DELETE FROM clearing_event CE "
532 " WHERE NOT EXISTS ( "
534 " FROM uploadtree UT "
535 " WHERE CE.uploadtree_fk = UT.uploadtree_pk "
536 " ) AND NOT EXISTS ( "
538 " FROM clearing_decision CD"
539 " WHERE CD.uploadtree_fk = CE.uploadtree_fk "
540 " AND CD.scope = '1'"
544 "DELETE FROM clearing_decision_event CDE"
545 " WHERE NOT EXISTS ( "
547 " FROM clearing_event CE "
548 " WHERE CE.clearing_event_pk = CDE.clearing_event_fk "
552 "DELETE FROM obligation_map OM "
553 " WHERE NOT EXISTS ( "
555 " FROM license_ref LR "
556 " WHERE OM.rf_fk = LR.rf_pk "
560 "DELETE FROM obligation_candidate_map OCM "
561 " WHERE NOT EXISTS ( "
563 " FROM license_ref LR "
564 " WHERE OCM.rf_fk = LR.rf_pk "
567 startTime = (long)time(0);
569 result =
PQexecCheck(-200, SQL1, __FILE__, __LINE__);
570 countTuples = PQcmdTuples(result);
572 printf(
"%s Orphaned records have been removed from uploadtree table\n", countTuples);
574 log_action_end(
"removeOrphanedRows: 1/6 - uploadtree", _start);
576 result =
PQexecCheck(-201, SQL2, __FILE__, __LINE__);
577 countTuples = PQcmdTuples(result);
579 printf(
"%s Orphaned records have been removed from clearing_decision table\n", countTuples);
581 log_action_end(
"removeOrphanedRows: 2/6 - clearing_decision", _start);
583 result =
PQexecCheck(-202, SQL3, __FILE__, __LINE__);
584 countTuples = PQcmdTuples(result);
586 printf(
"%s Orphaned records have been removed from clearing_event table\n", countTuples);
588 log_action_end(
"removeOrphanedRows: 3/6 - clearing_event", _start);
590 result =
PQexecCheck(-203, SQL4, __FILE__, __LINE__);
591 countTuples = PQcmdTuples(result);
593 printf(
"%s Orphaned records have been removed from clearing_decision_event table\n", countTuples);
595 log_action_end(
"removeOrphanedRows: 4/6 - clearing_decision_event", _start);
597 result =
PQexecCheck(-204, SQL5, __FILE__, __LINE__);
598 countTuples = PQcmdTuples(result);
600 printf(
"%s Orphaned records have been removed from obligation_map table\n", countTuples);
602 log_action_end(
"removeOrphanedRows: 5/6 - obligation_map", _start);
604 result =
PQexecCheck(-205, SQL6, __FILE__, __LINE__);
605 countTuples = PQcmdTuples(result);
607 printf(
"%s Orphaned records have been removed from obligation_candidate_map table\n", countTuples);
609 log_action_end(
"removeOrphanedRows: 6/6 - obligation_candidate_map", _start);
611 endTime = (long)time(0);
613 printf(
"Time taken for removing orphaned rows from database : %ld seconds\n", endTime-startTime);
615 log_action_end(
"removeOrphanedRows (6 Queries)", _start);
628 PGresult* updateResult;
631 int removedCount = 0;
634 long startTime, endTime;
638 double _start = now_monotonic_seconds();
639 log_action_start(
"removeOrphanedLogFiles");
642 "SELECT jq_pk, jq_log FROM job ja "
643 "INNER JOIN job jb ON ja.job_upload_fk = jb.job_upload_fk "
644 "INNER JOIN jobqueue jq ON jb.job_pk = jq.jq_job_fk "
645 "WHERE ja.job_name = 'Delete' AND jq_log IS NOT NULL "
646 "AND jq_log != 'removed';";
648 startTime = (long)time(0);
655 countTuples = PQntuples(result);
657 updateStatement = fo_dbManager_PrepareStamement(
dbManager,
658 "updateRemovedLogFromJobqueue",
659 "UPDATE jobqueue SET jq_log = 'removed' WHERE jq_pk = $1;",
int);
661 for (row = 0; row < countTuples; row++)
664 jobQueueId = atoi(PQgetvalue(result, row, 0));
665 logPath = PQgetvalue(result, row, 1);
666 if (stat(logPath, &statbuf) == -1)
668 LOG_NOTICE(
"Log file '%s' does not exists", logPath);
673 LOG_VERBOSE2(
"Removed file '%s'", logPath);
678 PQclear(updateResult);
683 LOG_ERROR(
"Unable to update the value of jobqueue.jq_log to 'removed' "
684 "for jq_pk = %d", jobQueueId);
690 endTime = (long)time(0);
691 printf(
"%d / %d Orphaned log files were removed "
692 "(%ld seconds)\n", removedCount, countTuples, endTime - startTime);
694 log_action_end(
"removeOrphanedLogFiles", _start);
708 long startTime, endTime;
710 time_t current_time = time(0);
711 time_t shifted_time = current_time - (retentionPeriod*24*60*60);
712 struct tm time_structure = *localtime(&shifted_time);
714 double _start = now_monotonic_seconds();
715 log_action_start(
"removeExpiredTokens");
717 snprintf(
SQL,
sizeof(
SQL),
718 "DELETE FROM personal_access_tokens WHERE (active = 'FALSE' OR expire_on < '%d-%02d-%02d') AND client_id IS NULL",
719 time_structure.tm_year + 1900,
720 time_structure.tm_mon + 1,
721 time_structure.tm_mday
724 startTime = (long)time(0);
727 countTuples = PQcmdTuples(result);
729 printf(
"%s Expired personal access tokens have been removed from personal_access_tokens table\n", countTuples);
732 endTime = (long)time(0);
734 printf(
"Time taken for removing expired personal access tokens from database : %ld seconds\n", endTime-startTime);
736 log_action_end(
"removeExpiredTokens", _start);
752 long StartTime, EndTime;
753 int countTuples, row, remval;
754 int day, month, year;
758 day = month = year = -1;
759 sscanf(date,
"%4d-%2d-%2d", &year, &month, &day);
760 if (((year < 1900) || (year > 9999)) || ((month < 1) || (month > 12)) ||
761 ((day < 1) || (day > 31)))
763 LOG_FATAL(
"Invalid date! Require yyyy-mm-dd, '%s' given.", date);
767 double _start = now_monotonic_seconds();
768 log_action_start(
"deleteOldGold");
770 snprintf(sql, MAXSQL,
771 "SELECT DISTINCT ON(pfile_pk) "
772 "CONCAT(LOWER(pfile_sha1), '.', LOWER(pfile_md5), '.', pfile_size) "
773 "AS filename FROM upload INNER JOIN pfile ON pfile_pk = pfile_fk "
774 "WHERE upload_ts < '%s' AND pfile_fk NOT IN ("
775 "SELECT pfile_fk FROM upload WHERE upload_ts > '%s' "
776 "AND pfile_fk IS NOT NULL);",
779 StartTime = (long)time(0);
781 result = PQexec(
pgConn, sql);
786 countTuples = PQntuples(result);
789 LOG_DEBUG(
"Read %d rows from DB.", countTuples);
792 for (row = 0; row < countTuples; row++)
794 filepath =
fo_RepMkPath(
"gold", PQgetvalue(result, row, 0));
795 remval = remove(filepath);
801 LOG_WARNING(
"Unable to remove '%s' file.", filepath);
812 EndTime = (long)time(0);
813 printf(
"Removed %d old gold files from the repository, took %ld seconds\n",
814 numrows, EndTime - StartTime);
816 log_action_end(
"deleteOldGold", _start);
834 time_t current_time = time(0);
836 time_t ellapsed_time;
839 unsigned int numfiles = 0;
840 long StartTime, EndTime;
845 double _start = now_monotonic_seconds();
846 log_action_start(
"removeOldLogFiles");
847 StartTime = (long)time(0);
848 if (sscanf(olderThan,
"%d-%d-%d", &ti.tm_year, &ti.tm_mon, &ti.tm_mday) != 3)
850 LOG_FATAL(
"Unable to parse date '%s' in YYYY-MM-DD format.", olderThan);
855 shifted_time = mktime(&ti);
856 ellapsed_time = (current_time - shifted_time) / 60 / 60 / 24 - 1;
858 char file_template[] =
"/tmp/foss-XXXXXX";
859 int fd = mkstemp(file_template);
861 snprintf(cmd, myBUFSIZ,
"/usr/bin/find %s/logs -type f -mtime +%ld -fprint %s",
862 fo_sysconfig(
"FOSSOLOGY",
"path"), ellapsed_time, file_template);
863 retval = system(cmd);
864 if (!WIFEXITED(retval))
866 LOG_FATAL(
"Unable run find for logs files.");
867 unlink(file_template);
870 tempFile = fdopen(fd,
"r");
871 if (tempFile == NULL)
873 LOG_FATAL(
"Unable to open temp file.");
874 unlink(file_template);
877 while ((ch = fgetc(tempFile)) != EOF)
885 snprintf(cmd, myBUFSIZ,
"/usr/bin/xargs --arg-file=%s /bin/rm -f", file_template);
886 retval = system(cmd);
887 if (!WIFEXITED(retval))
889 LOG_FATAL(
"Unable delete log files with xargs.");
891 unlink(file_template);
895 unlink(file_template);
897 EndTime = (long)time(0);
899 printf(
"Removed %d log files.\n", numfiles);
902 "Removing log files older than '%s' from the repository took %ld "
904 olderThan, EndTime - StartTime);
906 log_action_end(
"removeOldLogFiles", _start);
char SQL[256]
SQL query to execute.
void exitNow(int exitVal)
Exit function. This does all cleanup and should be used instead of calling exit() or main() return.
PGconn * pgConn
Database connection.
int fo_checkPQresult(PGconn *pgConn, PGresult *result, char *sql, char *FileID, int LineNumb)
Check the result status of a postgres SELECT.
int fo_checkPQcommand(PGconn *pgConn, PGresult *result, char *sql, char *FileID, int LineNumb)
Check the result status of a postgres commands (not select) If an error occured, write the error to s...
char * fo_RepMkPath(const char *Type, char *Filename)
Given a filename, construct the full path to the file.
void fo_scheduler_heart(int i)
This function must be called by agents to let the scheduler know they are alive and how many items th...
char * fo_sysconfig(const char *sectionname, const char *variablename)
gets a system configuration variable from the configuration data.
int agent_verbose
Common verbose flags for the agents, this is used so that the scheduler can change the verbose level ...
FUNCTION void removeOrphanedRows()
remove orphaned rows from fossology database
FUNCTION void verifyFilePerms(int fix)
Verify and optionally fix file permissions.
FUNCTION void deleteOldGold(char *date)
Delete gold files which are older than specified date.
FUNCTION void removeTemps()
Remove orphaned temp tables from deprecated pkgmettagetta and old delagent.
fo_dbManager * dbManager
fo_dbManager object
PGresult * PQexecCheck(int exitNumber, char *SQL, char *file, const int line)
simple wrapper which includes PQexec and fo_checkPQcommand
FUNCTION void reIndexAllTables()
reindex of all indexes in fossology database
FUNCTION void removeOldLogFiles(const char *olderThan)
FUNCTION void removeUploads()
Remove Uploads with no pfiles.
FUNCTION void removeOrphanedLogFiles()
FUNCTION void PQexecCheckClear(int exitNumber, char *SQL, char *file, const int line)
Execute SQL query and create the result and clear the result.
FUNCTION void processExpired()
Process expired uploads (slow)
FUNCTION void removeExpiredTokens(long int retentionPeriod)
remove expired personal access tokens from fossology database
FUNCTION void validateFolders()
Validate folder and foldercontents tables.
FUNCTION void removeOrphanedFiles()
Remove orphaned files from the repository (slow) Loop through each file in the repository and make su...
FUNCTION void vacAnalyze()
Do database vacuum and analyze.
FUNCTION void deleteOrphanGold()
Delete orphaned gold files from the repository.
FUNCTION void normalizeUploadPriorities()
Normalize priority of Uploads.
FUNCTION void recurseDir(const char *type, char *path, int level)
Recursively read directory till level is 0.
PGresult * fo_dbManager_ExecPrepared(fo_dbManager_PreparedStatement *preparedStatement,...)
Execute a prepared statement.