FOSSology  3.2.0rc1
Open Source License Compliance by Open Source Software
process.c
Go to the documentation of this file.
1 /***************************************************************
2  Copyright (C) 2013 Hewlett-Packard Development Company, L.P.
3  Copyright (C) 2014-2015,2019 Siemens AG
4 
5  This program is free software; you can redistribute it and/or
6  modify it under the terms of the GNU General Public License
7  version 2 as published by the Free Software Foundation.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License along
15  with this program; if not, write to the Free Software Foundation, Inc.,
16  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 
18  ***************************************************************/
24 #include "maintagent.h"
25 
26 /********** Globals *************/
27 PGconn* pgConn = NULL;
29 
38 PGresult * PQexecCheck(int exitNumber, char *SQL, char *file, const int line)
39 {
40  PGresult *result;
41  result = PQexec(pgConn, SQL);
42  if (fo_checkPQcommand(pgConn, result, SQL, file, line)) {
43  PQclear(result);
44  exitNow(exitNumber);
45  }
46  return result;
47 }
48 
54 FUNCTION void PQexecCheckClear(int exitNumber, char *SQL, char *file, const int line)
55 {
56  PGresult *result;
57  result = PQexecCheck(exitNumber, SQL, file, line);
58  PQclear(result);
59 }
60 
65 FUNCTION void vacAnalyze()
66 {
67  long startTime, endTime;
68  char *SQL = "VACUUM ANALYZE";
69 
70  startTime = (long)time(0);
71 
72  /* Vacuum and Analyze */
73  PQexecCheckClear(-110, SQL, __FILE__, __LINE__);
74 
75  endTime = (long)time(0);
76  printf("Vacuum Analyze took %ld seconds\n", endTime-startTime);
77 
78  fo_scheduler_heart(1); // Tell the scheduler that we are alive and update item count
79  return; // success
80 }
81 
87 FUNCTION void validateFolders()
88 {
89  PGresult* result; // the result of the database access
90  char *countTuples;
91 
92  char *invalidUploadRefs = "DELETE FROM foldercontents WHERE foldercontents_mode = 2 AND child_id NOT IN (SELECT upload_pk FROM upload)";
93  char *invalidUploadtreeRefs = "DELETE FROM foldercontents WHERE foldercontents_mode = 4 AND child_id NOT IN (SELECT uploadtree_pk FROM uploadtree)";
94  char *unRefFolders = "DELETE FROM folder WHERE folder_pk \
95  NOT IN (SELECT child_id FROM foldercontents WHERE foldercontents_mode = 1) AND folder_pk != '1'";
96  long startTime, endTime;
97 
98  startTime = (long)time(0);
99 
100  /* Remove folder contents with invalid upload references */
101  result = PQexecCheck(-120, invalidUploadRefs, __FILE__, __LINE__);
102  countTuples = PQcmdTuples(result);
103  PQclear(result);
104  printf("%s Invalid folder upload References\n", countTuples);
105 
106  /* Remove folder contents with invalid uploadtree references */
107  result = PQexecCheck(-121, invalidUploadtreeRefs, __FILE__, __LINE__);
108  countTuples = PQcmdTuples(result);
109  PQclear(result);
110  printf("%s Invalid folder uploadtree References\n", countTuples);
111 
112  /* Remove unreferenced folders */
113  result = PQexecCheck(-122, unRefFolders, __FILE__, __LINE__);
114  countTuples = PQcmdTuples(result);
115  PQclear(result);
116  printf("%s unreferenced folders\n", countTuples);
117 
118  endTime = (long)time(0);
119  printf("Validate folders took %ld seconds\n", endTime-startTime);
120 
121  fo_scheduler_heart(1); // Tell the scheduler that we are alive and update item count
122  return; // success
123 }
124 
140 FUNCTION void verifyFilePerms(int fix)
141 {
142 /*
143  long StartTime, EndTime;
144  char *RepoPath;
145 
146  StartTime = (long)time(0);
147 
148  RepoPath = fo_sysconfig("FOSSOLOGY", "path");
149  if (stat(RepoPath, &statbuf) == -1)
150  {
151  }
152 
153  EndTime = (long)time(0);
154  printf("Verify File Permissions took %ld seconds\n", EndTime-StartTime);
155 */
156  LOG_NOTICE("Verify file permissions is not implemented yet");
157 
158  fo_scheduler_heart(1); // Tell the scheduler that we are alive and update item count
159  return; // success
160 }
161 
167 FUNCTION void removeUploads()
168 {
169  PGresult* result; // the result of the database access
170  char *countTuples;
171  long startTime, endTime;
172 
173  char *SQL = "DELETE FROM upload WHERE upload_pk \
174  IN (SELECT upload_fk FROM uploadtree WHERE parent IS NULL AND pfile_fk IS NULL) \
175  OR (upload_pk NOT IN (SELECT upload_fk FROM uploadtree) \
176  AND (expire_action IS NULL OR expire_action != 'd') AND pfile_fk IS NOT NULL)";
177 
178  startTime = (long)time(0);
179 
180  result = PQexecCheck(-130, SQL, __FILE__, __LINE__);
181  countTuples = PQcmdTuples(result);
182  PQclear(result);
183 
184  endTime = (long)time(0);
185  printf("%s Uploads with no pfiles (%ld seconds)\n", countTuples, endTime-startTime);
186 
187  fo_scheduler_heart(1); // Tell the scheduler that we are alive and update item count
188  return; // success
189 }
190 
195 FUNCTION void removeTemps()
196 {
197  PGresult* result;
198  int row;
199  int countTuples;
200  int droppedCount = 0;
201  char SQLBuf[MAXSQL];
202  long startTime, endTime;
203 
204  char *SQL = "SELECT table_name FROM information_schema.tables WHERE table_type = 'BASE TABLE'"
205  "AND table_schema = 'public' AND (table_name SIMILAR TO '^metaanalysis_[[:digit:]]+$'"
206  "OR table_name SIMILAR TO '^delup_%');";
207 
208  startTime = (long)time(0);
209 
210  result = PQexec(pgConn, SQL);
211  if (fo_checkPQresult(pgConn, result, SQL, __FILE__, __LINE__)) exitNow(-140);
212  countTuples = PQntuples(result);
213  /* Loop through the temp table names, dropping the tables */
214  for (row = 0; row < countTuples; row++) {
215  snprintf(SQLBuf, MAXSQL, "DROP TABLE %s", PQgetvalue(result, row, 0));
216  PQexecCheckClear(-141, SQLBuf, __FILE__, __LINE__);
217  droppedCount++;
218  }
219  PQclear(result);
220 
221  endTime = (long)time(0);
222  printf("%d Orphaned temp tables were dropped (%ld seconds)\n", droppedCount, endTime-startTime);
223 
224  fo_scheduler_heart(1); // Tell the scheduler that we are alive and update item count
225  return; // success
226 }
227 
233 FUNCTION void processExpired()
234 {
235 /*
236  PGresult* result; // the result of the database access
237  int numrows; // generic return value
238  long StartTime, EndTime;
239 
240  StartTime = (long)time(0);
241 
242  EndTime = (long)time(0);
243  printf("Process expired uploads took %ld seconds\n", EndTime-StartTime);
244 */
245  LOG_NOTICE("Process expired uploads is not implemented yet");
246 
247  fo_scheduler_heart(1); // Tell the scheduler that we are alive and update item count
248  return; // success
249 }
250 
258 FUNCTION void removeOrphanedFiles()
259 {
260 /*
261  PGresult* result; // the result of the database access
262  int numrows; // generic return value
263  long StartTime, EndTime;
264 
265  StartTime = (long)time(0);
266 
267  EndTime = (long)time(0);
268  printf("Remove orphaned files from the repository took %ld seconds\n", EndTime-StartTime);
269 */
270  LOG_NOTICE("Remove orphaned files from the repository is not implemented yet");
271 
272  fo_scheduler_heart(1); // Tell the scheduler that we are alive and update item count
273  return; // success
274 }
275 
282 FUNCTION void deleteOrphanGold()
283 {
284 /*
285  PGresult* result; // the result of the database access
286  int numrows; // generic return value
287  long StartTime, EndTime;
288 
289  StartTime = (long)time(0);
290 
291  EndTime = (long)time(0);
292  printf("Remove orphaned files from the repository took %ld seconds\n", EndTime-StartTime);
293 */
294  LOG_NOTICE("Remove orphaned gold files from the repository is not implemented yet");
295 
296  fo_scheduler_heart(1); // Tell the scheduler that we are alive and update item count
297  return; // success
298 }
299 
305 {
306  long startTime, endTime;
307 
308  char *SQL1 = "CREATE TEMPORARY TABLE tmp_upload_prio(ordprio serial, uploadid int, groupid int)";
309  char *SQL2 = "INSERT INTO tmp_upload_prio (uploadid, groupid) (SELECT upload_fk uploadid, group_fk groupid FROM upload_clearing ORDER BY priority ASC);";
310  char *SQL3 = "UPDATE upload_clearing SET priority = ordprio FROM tmp_upload_prio WHERE uploadid=upload_fk AND group_fk=groupid;";
311 
312  startTime = (long)time(0);
313 
314  PQexecCheckClear(-180, SQL1, __FILE__, __LINE__);
315  PQexecCheckClear(-181, SQL2, __FILE__, __LINE__);
316  PQexecCheckClear(-182, SQL3, __FILE__, __LINE__);
317 
318  endTime = (long)time(0);
319  printf("Normalized upload priorities (%ld seconds)\n", endTime-startTime);
320 
321  fo_scheduler_heart(1); // Tell the scheduler that we are alive and update item count
322  return; // success
323 }
324 
329 FUNCTION void reIndexAllTables()
330 {
331  PGresult* result; // the result of the database access
332  char SQLBuf[MAXSQL];
333  long startTime, endTime;
334  char *SQL= "SELECT table_catalog FROM information_schema.tables WHERE table_type = 'BASE TABLE' AND table_schema = 'public' AND (table_name SIMILAR TO 'upload%') LIMIT 1";
335 
336  startTime = (long)time(0);
337 
338  result = PQexec(pgConn, SQL);
339  if (fo_checkPQresult(pgConn, result, SQL, __FILE__, __LINE__)) exitNow(-190);
340 
341  memset(SQLBuf,'\0',sizeof(SQLBuf));
342  snprintf(SQLBuf,sizeof(SQLBuf),"REINDEX DATABASE %s;", PQgetvalue(result, 0, 0));
343  PQclear(result);
344  PQexecCheckClear(-191, SQLBuf, __FILE__, __LINE__);
345 
346  endTime = (long)time(0);
347  printf("Time taken for reindexing the database : %ld seconds\n", endTime-startTime);
348 
349  fo_scheduler_heart(1); // Tell the scheduler that we are alive and update item count
350  return; // success
351 }
352 
357 FUNCTION void removeOrphanedRows()
358 {
359  PGresult* result; // the result of the database access
360  char *countTuples;
361  long startTime, endTime;
362 
363  char *SQL1 = "DELETE FROM uploadtree UT "
364  " WHERE NOT EXISTS ( "
365  " SELECT 1 "
366  " FROM upload U "
367  " WHERE UT.upload_fk = U.upload_pk "
368  " );";
369 
370  char *SQL2 = "DELETE FROM clearing_decision AS CD "
371  " WHERE NOT EXISTS ( "
372  " SELECT 1 "
373  " FROM uploadtree UT "
374  " WHERE CD.uploadtree_fk = UT.uploadtree_pk "
375  " ) AND CD.scope = '0';";
376 
377  char *SQL3 = "DELETE FROM clearing_event CE "
378  " WHERE NOT EXISTS ( "
379  " SELECT 1 "
380  " FROM uploadtree UT "
381  " WHERE CE.uploadtree_fk = UT.uploadtree_pk "
382  " ) AND NOT EXISTS ( "
383  " SELECT 1 "
384  " FROM clearing_decision CD"
385  " WHERE CD.uploadtree_fk = CE.uploadtree_fk "
386  " AND CD.scope = '1'"
387  " );";
388 
389  char *SQL4 = "DELETE FROM clearing_decision_event CDE"
390  " WHERE NOT EXISTS ( "
391  " SELECT 1 "
392  " FROM clearing_event CE "
393  " WHERE CE.clearing_event_pk = CDE.clearing_event_fk "
394  " );";
395 
396  char *SQL5 = "DELETE FROM obligation_map OM "
397  " WHERE NOT EXISTS ( "
398  " SELECT 1 "
399  " FROM license_ref LR "
400  " WHERE OM.rf_fk = LR.rf_pk "
401  " );";
402 
403  char *SQL6 = "DELETE FROM obligation_candidate_map OCM "
404  " WHERE NOT EXISTS ( "
405  " SELECT 1 "
406  " FROM license_ref LR "
407  " WHERE OCM.rf_fk = LR.rf_pk "
408  " );";
409 
410  startTime = (long)time(0);
411 
412  result = PQexecCheck(-200, SQL1, __FILE__, __LINE__);
413  countTuples = PQcmdTuples(result);
414  PQclear(result);
415  printf("%s Orphaned records have been removed from uploadtree table\n", countTuples);
417 
418  result = PQexecCheck(-201, SQL2, __FILE__, __LINE__);
419  countTuples = PQcmdTuples(result);
420  PQclear(result);
421  printf("%s Orphaned records have been removed from clearing_decision table\n", countTuples);
423 
424  result = PQexecCheck(-202, SQL3, __FILE__, __LINE__);
425  countTuples = PQcmdTuples(result);
426  PQclear(result);
427  printf("%s Orphaned records have been removed from clearing_event table\n", countTuples);
429 
430  result = PQexecCheck(-203, SQL4, __FILE__, __LINE__);
431  countTuples = PQcmdTuples(result);
432  PQclear(result);
433  printf("%s Orphaned records have been removed from clearing_decision_event table\n", countTuples);
435 
436  result = PQexecCheck(-204, SQL5, __FILE__, __LINE__);
437  countTuples = PQcmdTuples(result);
438  PQclear(result);
439  printf("%s Orphaned records have been removed from obligation_map table\n", countTuples);
441 
442  result = PQexecCheck(-205, SQL6, __FILE__, __LINE__);
443  countTuples = PQcmdTuples(result);
444  PQclear(result);
445  printf("%s Orphaned records have been removed from obligation_candidate_map table\n", countTuples);
446  fo_scheduler_heart(1); // Tell the scheduler that we are alive and update item count
447 
448  endTime = (long)time(0);
449 
450  printf("Time taken for removing orphaned rows from database : %ld seconds\n", endTime-startTime);
451 
452  return; // success
453 }
454 
455 
460 FUNCTION void removeOrphanedLogFiles()
461 {
462  PGresult* result;
463  PGresult* updateResult;
464  int row;
465  int countTuples;
466  int removedCount = 0;
467  int jobQueueId;
468  char* logPath;
469  long startTime, endTime;
470  fo_dbManager_PreparedStatement* updateStatement;
471  struct stat statbuf;
472 
473  char *SQL = "SELECT jq_pk, jq_log FROM job ja "
474  "INNER JOIN job jb ON ja.job_upload_fk = jb.job_upload_fk "
475  "INNER JOIN jobqueue jq ON jb.job_pk = jq.jq_job_fk "
476  "WHERE ja.job_name = 'Delete' AND jq_log IS NOT NULL "
477  "AND jq_log != 'removed';";
478 
479  startTime = (long)time(0);
480 
481  result = PQexec(pgConn, SQL);
482  if (fo_checkPQresult(pgConn, result, SQL, __FILE__, __LINE__))
483  {
484  exitNow(-140);
485  }
486  countTuples = PQntuples(result);
487 
488  updateStatement = fo_dbManager_PrepareStamement(dbManager,
489  "updateRemovedLogFromJobqueue",
490  "UPDATE jobqueue SET jq_log = 'removed' WHERE jq_pk = $1;", int);
491  /* Loop through the logs found and delete them. Also update the database */
492  for (row = 0; row < countTuples; row++)
493  {
494  fo_dbManager_begin(dbManager);
495  jobQueueId = atoi(PQgetvalue(result, row, 0));
496  logPath = PQgetvalue(result, row, 1);
497  if (stat(logPath, &statbuf) == -1)
498  {
499  LOG_NOTICE("Log file '%s' does not exists", logPath);
500  }
501  else
502  {
503  remove(logPath);
504  LOG_VERBOSE2("Removed file '%s'", logPath);
505  }
506  updateResult = fo_dbManager_ExecPrepared(updateStatement, jobQueueId);
507  if (updateResult)
508  {
509  free(updateResult);
510  removedCount++;
511  }
512  else
513  {
514  LOG_ERROR("Unable to update the value of jobqueue.jq_log to 'removed' "
515  "for jq_pk = %d", jobQueueId);
516  }
517  fo_dbManager_commit(dbManager);
518  }
519  PQclear(result);
520 
521  endTime = (long)time(0);
522  printf("%d / %d Orphaned log files were removed "
523  "(%ld seconds)\n", removedCount, countTuples, endTime - startTime);
524 
525  fo_scheduler_heart(1); // Tell the scheduler that we are alive and update item count
526  return; // success
527 }
int fo_checkPQresult(PGconn *pgConn, PGresult *result, char *sql, char *FileID, int LineNumb)
Check the result status of a postgres SELECT.
Definition: libfossdb.c:181
FUNCTION void removeOrphanedFiles()
Remove orphaned files from the repository (slow) Loop through each file in the repository and make su...
Definition: process.c:258
FUNCTION void removeTemps()
Remove orphaned temp tables from deprecated pkgmettagetta and old delagent.
Definition: process.c:195
FUNCTION void deleteOrphanGold()
Delete orphaned gold files from the repository Loop through each gold file in the repository and make...
Definition: process.c:282
FUNCTION void reIndexAllTables()
reindex of all indexes in fossology database
Definition: process.c:329
PGresult * fo_dbManager_ExecPrepared(fo_dbManager_PreparedStatement *preparedStatement,...)
Execute a prepared statement.
Definition: standalone.c:31
PGconn * pgConn
Database connection.
Definition: adj2nest.c:98
FUNCTION void vacAnalyze()
Do database vacuum and analyze.
Definition: process.c:65
FUNCTION void removeOrphanedRows()
remove orphaned rows from fossology database
Definition: process.c:357
FUNCTION void verifyFilePerms(int fix)
Verify and optionally fix file permissions.
Definition: process.c:140
FUNCTION void normalizeUploadPriorities()
Normalize priority of Uploads.
Definition: process.c:304
PGresult * PQexecCheck(int exitNumber, char *SQL, char *file, const int line)
simple wrapper which includes PQexec and fo_checkPQcommand
Definition: process.c:38
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...
Definition: libfossdb.c:215
FUNCTION void processExpired()
Process expired uploads (slow)
Definition: process.c:233
char SQL[256]
SQL query to execute.
Definition: adj2nest.c:90
FUNCTION void validateFolders()
Validate folder and foldercontents tables.
Definition: process.c:87
fo_dbManager * dbManager
fo_dbManager object
Definition: process.c:28
FUNCTION void removeOrphanedLogFiles()
Definition: process.c:460
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...
FUNCTION void removeUploads()
Remove Uploads with no pfiles.
Definition: process.c:167
FUNCTION void PQexecCheckClear(int exitNumber, char *SQL, char *file, const int line)
Execute SQL query and create the result and clear the result.
Definition: process.c:54
void exitNow(int exitVal)
Exit function. This does all cleanup and should be used instead of calling exit() or main() return...
Definition: util.c:1099