a44421a79fb36cc2036fe116b97ea3bc9590cd0c braney Fri Dec 2 09:34:39 2011 -0800 removed rcsid (#295) diff --git src/utils/ccCpLock/ccCp.3.c src/utils/ccCpLock/ccCp.3.c index fd01217..e398bde 100644 --- src/utils/ccCpLock/ccCp.3.c +++ src/utils/ccCpLock/ccCp.3.c @@ -1,313 +1,312 @@ /* ccCp - copy file to the cluster efficiently. */ #include "common.h" #include "obscure.h" #include "portable.h" #include "dystring.h" -static char const rcsid[] = "$Id: ccCp.3.c,v 1.2 2003/05/06 07:41:04 kate Exp $"; boolean amFirst = FALSE; /* Is this the copy that launched the copies? */ char *fullPathName(char *relName) /* Return full version of path name. */ { char firstChar = relName[0]; char fullPath[512]; char dir[512]; if (firstChar == '/' || firstChar == '~') return cloneString(relName); getcwd(dir, sizeof(dir)); sprintf(fullPath, "%s/%s", dir, relName); return cloneString(fullPath); } int scpFile(char *source, char *destHost, char *destFile) /* Execute scp command to copy source file to host. */ { struct dyString *dy = newDyString(512); int ret; dyStringPrintf(dy, "scp %s %s:/%s >/dev/null", source, destHost, destFile); ret = system(dy->string); freeDyString(&dy); return ret; } int cpFile(char *source, char *destFile) /* Execute cp command to copy file to host. */ { struct dyString *dy = newDyString(512); int ret; dyStringPrintf(dy, "cp %s %s", source, destFile); ret = system(dy->string); freeDyString(&dy); return ret; } void sshSelf(char *hostList, char *host, int start, char *destFile, char *lockDir) /* Execute ssh command to invoke self. */ { struct dyString *dy = newDyString(512); dyStringPrintf(dy, "ssh -x %s /projects/compbio/experiments/hg/bin/i386/ccCp %s %s %d %s &", host, destFile, hostList, start, lockDir); system(dy->string); freeDyString(&dy); } void usage() /* Explain usage and exit. */ { errAbort( "ccCp - copy a file to cluster." "usage:\n" " ccCp sourceFile destFile [hostList]\n" "This will copy sourceFile to destFile for all machines in\n" "hostList\n" "\n" "example:\n" " ccCp h.zip /var/tmp/h.zip newHosts"); } char *lockName(char *lockDir, char *host) /* Return name of lock for host. */ { static char buf[512]; sprintf(buf, "%s/%s", lockDir, host); return buf; } int makeLock(char *host, char *lockDir) /* Return lock file handle. */ { char *name = lockName(lockDir, host); int fd; fd = open(name, O_CREAT | O_EXCL | O_WRONLY, 0666); return fd; } void cleanupLocks(char *lockDir) /* Remove all locks. */ { struct slName *dir = listDir(lockDir, "*"); char name[512]; struct slName *one; for (one = dir; one != NULL; one = one->next) { sprintf(name, "%s/%s", lockDir, one->name); remove(name); } rmdir(lockDir); } void ccMore(char *fileName, char *hostList, int start, char *lockDir) /* Copy source file to hostList starting at start. Look at * lock files in lock dir to see which one to do next. */ { char **hosts; char *newHost; char *hostBuf; int hostCount; int i; readAllWords(hostList, &hosts, &hostCount, &hostBuf); if (hostCount <= 0) errAbort("%s is empty.", hostList); for (i=start; i<hostCount; ++i) { int lockFd; newHost = hosts[i]; if ((lockFd = makeLock(newHost, lockDir)) >= 0) { char ok = TRUE; if (scpFile(fileName, newHost, fileName) != 0) ok = FALSE; write(lockFd, &ok, 1); close(lockFd); if (ok ) { if (i <= (hostCount+1)/2) /* Don't spawn off on last round. */ sshSelf(hostList, newHost, i+1, fileName, lockDir); } } } } void ccFirst(char *source, char *dest, char *hostList, char *lockDir) /* Do first instance of this program. Copy file to first host, * make up lock directory, and then poll lock directory to see * if we're done. */ { char *firstHost, *lastHost; char **hosts; char *hostBuf; int hostCount; int firstLock; int childPid; char *thisHost = getenv("HOST"); char ok; long startTime = clock1000(); if (thisHost == NULL) errAbort("HOST environment variable undefined\n"); readAllWords(hostList, &hosts, &hostCount, &hostBuf); if (hostCount <= 0) errAbort("%s is empty.", hostList); if (stringArrayIx(thisHost, hosts, hostCount) < 0) errAbort("Current host (%s) not in host list\n", thisHost); if (mkdir(lockDir, 0777) < 0) errAbort("Couldn't make lock directory %s\n", lockDir); firstHost = thisHost; lastHost = hosts[hostCount-1]; if (sameString(lastHost, thisHost) && hostCount > 1) lastHost = hosts[hostCount-2]; firstLock = makeLock(firstHost, lockDir); if (firstLock < 0) errAbort("Couldn't make lock file %s/%s\n", lockDir, firstHost); if (cpFile(source, dest) != 0) { warn("Couldn't copy %s to %s:%d\n", source, firstHost, dest); close(firstLock); cleanupLocks(lockDir); errAbort("Cleaned up locks in %s, aborting copy.", lockDir); } ok = 1; write(firstLock, &ok, 1); close(firstLock); childPid = fork(); if (childPid == 0) { /* Have child process keep copying. */ ccMore(dest, hostList, 0, lockDir); } else { int sleepIx = 0; int sleepTime = 10; int lastStart = 0, lastErr = 0, lastEnd = 0; /* Have parent process wait until last file done. */ for (sleepIx = 0; ; ++sleepIx) { int lockFd; int i; int startCount = 0; int endCount = 0; int errCount = 0; int toGo = 0; int procCount = 0; int lastProcCount = 0; int finCount; boolean reportErr; for (i=0; i<hostCount; ++i) { char *ln = lockName(lockDir, hosts[i]); lockFd = open(ln, O_RDONLY); if (lockFd < 0) ++toGo; else { char ok; if (read(lockFd, &ok, 1) < 1) ++startCount; else { if (ok) ++endCount; else ++errCount; } close(lockFd); } } finCount = endCount + errCount; // if (lastStart != startCount || lastEnd != endCount || lastErr != errCount) { printf(" copies in progress %d finished %d errors %d total %d\n", startCount, endCount, errCount, hostCount); lastStart = startCount; lastEnd = endCount; lastErr = errCount; } if (finCount >= hostCount) { if (errCount > 0) { fprintf(stderr, "Errors copying to hosts:"); for (i=0; i<hostCount; ++i) { char *ln = lockName(lockDir, hosts[i]); lockFd = open(ln, O_RDONLY); if (lockFd < 0) { fprintf(stderr, " ??%s??", hosts[i]); } else { char ok; if (read(lockFd, &ok, 1) < 1) { fprintf(stderr, " ?%s?", hosts[i]); ++startCount; } else { if (!ok) { fprintf(stderr, " %s", hosts[i]); ++errCount; } } close(lockFd); } } fprintf(stderr, "\n"); } cleanupLocks(lockDir); break; } sleep(sleepTime); } } } int main(int argc, char *argv[]) /* Process command line. */ { int start = 0, count = 0; char *lockDir; char *source, *dest, *hostList; if (argc != 3 && argc != 4 && argc != 5) usage(); if (argc == 5) { dest = argv[1]; hostList = argv[2]; start = atoi(argv[3]); lockDir = argv[4]; ccMore(dest, hostList, start, lockDir); } else { source = argv[1]; dest = argv[2]; if (argc == 4) { hostList = argv[3]; hostList = fullPathName(hostList); } else hostList = "/projects/compbio/experiments/hg/masterList"; lockDir = tempnam("/projects/compbio/experiments/hg/tmp", "lock"); amFirst = TRUE; ccFirst(source, dest, hostList, lockDir); } }