Example #1
0
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;
}
Example #2
0
/*
** Unlock an vfstrace-file.
*/
static int vfstraceUnlock(sqlite3_file *pFile, int eLock){
  vfstrace_file *p = (vfstrace_file *)pFile;
  vfstrace_info *pInfo = p->pInfo;
  int rc;
  vfstrace_printf(pInfo, "%s.xUnlock(%s,%s)", pInfo->zVfsName, p->zFName,
                  lockName(eLock));
  rc = p->pReal->pMethods->xUnlock(p->pReal, eLock);
  vfstrace_print_errcode(pInfo, " -> %s\n", rc);
  return rc;
}
Example #3
0
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);
	}
    }
}
// Index the token
bool OSToken::index(bool isFirstTime /* = false */)
{
	// Check if re-indexing is required
	if (!isFirstTime && (!valid || !gen->wasUpdated()))
	{
		return true;
	}

	// Check the integrity
	if (!tokenDir->refresh() || !tokenObject->valid)
	{
		valid = false;

		return false;
	}

	DEBUG_MSG("Token %s has changed", tokenPath.c_str());

	// Retrieve the directory listing
	std::vector<std::string> tokenFiles = tokenDir->getFiles();

	// Filter out the objects
	std::set<std::string> newSet;

	for (std::vector<std::string>::iterator i = tokenFiles.begin(); i != tokenFiles.end(); i++)
	{
		if ((i->size() > 7) &&
		    (!(i->substr(i->size() - 7).compare(".object"))) &&
		    (i->compare("token.object")))
		{
			newSet.insert(*i);
		}
		else
		{
			DEBUG_MSG("Ignored file %s", i->c_str());
		}
	}

	// Compute the changes compared to the last list of files
	std::set<std::string> addedFiles;
	std::set<std::string> removedFiles;

	// No access to object mutable fields before
	MutexLocker lock(tokenMutex);

	if (!isFirstTime)
	{
		// First compute which files were added
		for (std::set<std::string>::iterator i = newSet.begin(); i != newSet.end(); i++)
		{
			if (currentFiles.find(*i) == currentFiles.end())
			{
				addedFiles.insert(*i);
			}
		}

		// Now compute which files were removed
		for (std::set<std::string>::iterator i = currentFiles.begin(); i != currentFiles.end(); i++)
		{
			if (newSet.find(*i) == newSet.end())
			{
				removedFiles.insert(*i);
			}
		}
	}
	else
	{
		addedFiles = newSet;
	}

	currentFiles = newSet;

	DEBUG_MSG("%d objects were added and %d objects were removed", addedFiles.size(), removedFiles.size());
	DEBUG_MSG("Current directory set contains %d objects", currentFiles.size());

	// Now update the set of objects

	// Add new objects
	for (std::set<std::string>::iterator i = addedFiles.begin(); i != addedFiles.end(); i++)
	{
		if ((i->find_last_of('.') == std::string::npos) ||
		    (i->substr(i->find_last_of('.')) != ".object"))
		{
			continue;
		}

		std::string lockName(*i);
		lockName.replace(lockName.find_last_of('.'), std::string::npos, ".lock");

		// Create a new token object for the added file
		ObjectFile* newObject = new ObjectFile(this, tokenPath + OS_PATHSEP + *i, tokenPath + OS_PATHSEP + lockName);

		DEBUG_MSG("(0x%08X) New object %s (0x%08X) added", this, newObject->getFilename().c_str(), newObject);

		objects.insert(newObject);
		allObjects.insert(newObject);
	}

	// Remove deleted objects
	std::set<OSObject*> newObjects;

	for (std::set<OSObject*>::iterator i = objects.begin(); i != objects.end(); i++)
	{
		ObjectFile* fileObject = dynamic_cast<ObjectFile*>((*i));
		if (fileObject == NULL)
		{
			ERROR_MSG("Object type not compatible with this token class 0x%08X", (*i));
	
			return false;
		}
		
		DEBUG_MSG("Processing %s (0x%08X)", fileObject->getFilename().c_str(), *i);

		if (removedFiles.find(fileObject->getFilename()) == removedFiles.end())
		{
			DEBUG_MSG("Adding object %s", fileObject->getFilename().c_str());
			// This object gets to stay in the set
			newObjects.insert(*i);
		}
		else
		{
			fileObject->invalidate();
		}
	}

	// Set the new objects
	objects = newObjects;

	DEBUG_MSG("The token now contains %d objects", objects.size());

	return true;
}