diff --git a/dali/daliadmin/daadmin.cpp b/dali/daliadmin/daadmin.cpp index e143850e3eb..34c76ea5997 100644 --- a/dali/daliadmin/daadmin.cpp +++ b/dali/daliadmin/daadmin.cpp @@ -16,6 +16,7 @@ ############################################################################## */ #include +#include #include #include "platform.h" @@ -3424,4 +3425,76 @@ void cleanJobQueues(bool dryRun) } } +void cleanGeneratedDlls(bool dryRun, bool backup) +{ + PROGLOG("Gathering workunits for referencd generated dlls"); + CCycleTimer timer; + Owned conn = querySDS().connect("/", myProcessSession(), 0, SDS_LOCK_TIMEOUT); + if (!conn) + { + WARNLOG("Failed to connect to /WorkUnits"); + return; + } + IPropertyTree *root = conn->queryRoot(); + IPropertyTree *wuidsTree = root->queryPropTree("WorkUnits"); + if (!wuidsTree) + { + PROGLOG("No WorkUnits found"); + return; + } + Owned wuidIter = wuidsTree->getElements("*"); + std::unordered_set referencedGDlls; + ForEach(*wuidIter) + { + IPropertyTree &wuid = wuidIter->query(); + Owned gdIter = wuid.getElements("Query/Associated/File[@type='dll']"); + ForEach(*gdIter) + { + IPropertyTree &gd = gdIter->query(); + const char *fullPath = gd.queryProp("@filename"); + const char *filename = pathTail(fullPath); + if (filename) + referencedGDlls.emplace(filename); + } + } + PROGLOG("Found %u workunits that reference generated dlls, took: %u ms", (unsigned)referencedGDlls.size(), timer.elapsedMs()); + PROGLOG("Scanning GeneratedDlls"); + timer.reset(); + IPropertyTree *generatedDllsTree = root->queryPropTree("GeneratedDlls"); + if (!generatedDllsTree) + { + PROGLOG("No GeneratedDlls found"); + return; + } + std::vector gDllsToRemove; + unsigned totalGDlls = 0; + Owned gDlls = generatedDllsTree->getElements("*"); + ForEach(*gDlls) + { + ++totalGDlls; + IPropertyTree &gDll = gDlls->query(); + const char *name = gDll.queryProp("@name"); + if (referencedGDlls.find(name) == referencedGDlls.end()) + gDllsToRemove.push_back(&gDll); + } + PROGLOG("Found %u GeneratedDlls, %u not referenced, took: %u ms", totalGDlls, (unsigned)gDllsToRemove.size(), timer.elapsedMs()); + if (!dryRun) + { + if (backup) + { + StringBuffer bakName; + Owned iFileIO = createUniqueFile(NULL, "daliadmin_generateddlls", "bak", bakName); + if (!iFileIO) + throw makeStringException(0, "Failed to create backup file"); + PROGLOG("Saving backup of GeneratedDlls to %s", bakName.str()); + saveXML(*iFileIO, generatedDllsTree, 2); + } + PROGLOG("Deleting %u unreferenced GeneratedDlls", (unsigned)gDllsToRemove.size()); + timer.reset(); + for (auto &item: gDllsToRemove) + generatedDllsTree->removeTree(item); + PROGLOG("Removed %u unreferenced GeneratedDlls, took: %u ms", (unsigned)gDllsToRemove.size(), timer.elapsedMs()); + } +} + } // namespace daadmin diff --git a/dali/daliadmin/daadmin.hpp b/dali/daliadmin/daadmin.hpp index f0141760e03..34df175c737 100644 --- a/dali/daliadmin/daadmin.hpp +++ b/dali/daliadmin/daadmin.hpp @@ -96,5 +96,6 @@ extern DALIADMIN_API void daliping(const char *dalis, unsigned connecttime, unsi extern DALIADMIN_API void validateStore(bool fix, bool deleteFiles, bool verbose); extern DALIADMIN_API void removeOrphanedGlobalVariables(bool dryrun, bool reconstruct); extern DALIADMIN_API void cleanJobQueues(bool dryRun); +extern DALIADMIN_API void cleanGeneratedDlls(bool dryRun, bool backup); } // namespace daadmin \ No newline at end of file diff --git a/dali/daliadmin/daliadmin.cpp b/dali/daliadmin/daliadmin.cpp index 4c56836aac6..c08d7cc57e3 100644 --- a/dali/daliadmin/daliadmin.cpp +++ b/dali/daliadmin/daliadmin.cpp @@ -94,6 +94,7 @@ void usage(const char *exe) printf(" auditlog \n"); printf(" cleanglobalwuid [dryrun] [noreconstruct]\n"); printf(" cleanjobqueues [dryrun]\n"); + printf(" cleangenerateddlls [dryrun] [nobackup]\n"); printf(" clusterlist -- list clusters (mask optional)\n"); printf(" coalesce -- force transaction coalesce\n"); printf(" dalilocks [ ] [ files ] -- get all locked files/xpaths\n"); @@ -582,6 +583,20 @@ int main(int argc, const char* argv[]) bool dryRun = np>0 && strieq("dryrun", params.item(1)); cleanJobQueues(dryRun); } + else if (strieq(cmd, "cleangenerateddlls")) + { + bool dryRun = false; + bool backup = true; // default + for (unsigned i=1; i