|
@@ -98,6 +98,7 @@ void usage(const char *exe)
|
|
|
printf(" dfscompratio <logicalname> -- returns compression ratio of file\n");
|
|
|
printf(" dfsscopes <mask> -- lists logical scopes (mask = * for all)\n");
|
|
|
printf(" cleanscopes -- remove empty scopes\n");
|
|
|
+ printf(" dfsreplication <clustermask> <logicalnamemask> <redundancy-count> -- set redundancy for files matching mask, on specified clusters only");
|
|
|
printf("\n");
|
|
|
printf("Workunit commands:\n");
|
|
|
printf(" listworkunits [<prop>=<val> [<lower> [<upper>]]] -- list workunits that match prop=val in workunit name range lower to upper\n");
|
|
@@ -1645,6 +1646,48 @@ static void listmatches(const char *path, const char *match, const char *pval)
|
|
|
//=============================================================================
|
|
|
|
|
|
|
|
|
+static void dfsreplication(const char *clusterMask, const char *lfnMask, unsigned redundancy, bool dryRun)
|
|
|
+{
|
|
|
+ StringBuffer findXPath("//File");
|
|
|
+ if (clusterMask && !streq("*", clusterMask))
|
|
|
+ findXPath.appendf("[Cluster/@name=\"%s\"]", clusterMask);
|
|
|
+ if (lfnMask && !streq("*", lfnMask))
|
|
|
+ findXPath.appendf("[@name=\"%s\"]", lfnMask);
|
|
|
+
|
|
|
+ const char *basePath = "/Files";
|
|
|
+ const char *propToSet = "@redundancy";
|
|
|
+ StringBuffer value;
|
|
|
+ value.append(redundancy);
|
|
|
+
|
|
|
+ StringBuffer clusterFilter("Cluster");
|
|
|
+ if (clusterMask && !streq("*", clusterMask))
|
|
|
+ clusterFilter.appendf("[@name=\"%s\"]", clusterMask);
|
|
|
+
|
|
|
+ Owned<IRemoteConnection> conn = querySDS().connect(basePath, myProcessSession(), 0, daliConnectTimeoutMs);
|
|
|
+ Owned<IPropertyTreeIterator> iter = conn->getElements(findXPath);
|
|
|
+ ForEach(*iter)
|
|
|
+ {
|
|
|
+ IPropertyTree &file = iter->query();
|
|
|
+ Owned<IPropertyTreeIterator> clusterIter = file.getElements(clusterFilter);
|
|
|
+ ForEach(*clusterIter)
|
|
|
+ {
|
|
|
+ IPropertyTree &cluster = clusterIter->query();
|
|
|
+ const char *oldValue = cluster.queryProp(propToSet);
|
|
|
+ if (!oldValue || !streq(value, oldValue))
|
|
|
+ {
|
|
|
+ const char *fileName = file.queryProp("OrigName");
|
|
|
+ const char *clusterName = cluster.queryProp("@name");
|
|
|
+ VStringBuffer msg("File=%s on cluster=%s - %s %s to %s", fileName, clusterName, dryRun?"Would set":"Setting", propToSet, value.str());
|
|
|
+ if (oldValue)
|
|
|
+ msg.appendf(" [old value = %s]", oldValue);
|
|
|
+ PROGLOG("%s", msg.str());
|
|
|
+ if (!dryRun)
|
|
|
+ cluster.setProp(propToSet, value);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
static const char *getNum(const char *s,unsigned &num)
|
|
|
{
|
|
|
while (*s&&!isdigit(*s))
|
|
@@ -2812,6 +2855,11 @@ int main(int argc, char* argv[])
|
|
|
CHECKPARAMS(2,2);
|
|
|
wuidCompress(params.item(1), params.item(2), false);
|
|
|
}
|
|
|
+ else if (stricmp(cmd,"dfsreplication")==0) {
|
|
|
+ CHECKPARAMS(3,4);
|
|
|
+ bool dryRun = np>3 && strieq("dryrun", params.item(4));
|
|
|
+ dfsreplication(params.item(1), params.item(2), atoi(params.item(3)), dryRun);
|
|
|
+ }
|
|
|
else
|
|
|
ERRLOG("Unknown command %s",cmd);
|
|
|
}
|