コード例 #1
0
ファイル: testfs.c プロジェクト: liuhaotian/sfs
/**
 * Checks if the contents of the file match the give data.
 */
int verifyFile(char *fileName, char *data, int fsize) {
    int hr = SUCCESS;
    /* open a file and verify the contents of the file are correct */
    char data2[fsize];
    // open file
    int fd = sfs_fopen(fileName);
    FAIL_BRK3((fd == -1), stdout,
            "Error: Unable to open file %s with intention to read\n", fileName);
    // read file
    FAIL_BRK3((sfs_fread(fd, data2, fsize) != fsize), stdout,
            "Error: failed to read %d bytes to %s, fd:%d\n", fsize, fileName,
            fd);

    FAIL_BRK3(checkBuffers(data, data2, fsize, 0), stdout,
            "Error: contents didn't match\n");

    // TODO: We should not allow reading pass the end of the file...
    //int bread;
    //FAIL_BRK( ((bread = sfs_fread(fd, data2, 1)) == 1), stdout, "Error: successfully reading more data when we didn't expected it %d\n", bread);

    // close file
    FAIL_BRK3(sfs_fclose(fd), stdout, "Error: Unable to close fd: %d\n", fd);

    Fail: return hr;
}
コード例 #2
0
ファイル: SPK_DX9Renderer.cpp プロジェクト: tecan/LunaLibs
	bool DX9Renderer::DX9PrepareBuffers(const Group& group)
	{
		if (!checkBuffers(group))
		{
			if (isBuffersCreationEnabled())
			{
				destroyBuffers(group);
				createBuffers(group);
				return true;
			}
			return false;
		}
		return true;
	}
コード例 #3
0
    /*!
    If client is also server (attached mode), after sending event, it should process right away
    the incoming event.
    \param [in] ranks list rank of server connected this client
    */
    void CContextClient::waitEvent(list<int>& ranks)
    {
      parentServer->server->setPendingEvent();
      while (checkBuffers(ranks))
      {
        parentServer->server->listen();
        parentServer->server->checkPendingRequest();
      }

      while (parentServer->server->hasPendingEvent())
      {
       parentServer->server->eventLoop();
      }
    }
コード例 #4
0
    /*!
     * Get buffers for each connection to the servers. This function blocks until there is enough room in the buffers unless
     * it is explicitly requested to be non-blocking.
     *
     * \param [in] serverList list of rank of connected server
     * \param [in] sizeList size of message corresponding to each connection
     * \param [out] retBuffers list of buffers that can be used to store an event
     * \param [in] nonBlocking whether this function should be non-blocking
     * \return whether the already allocated buffers could be used
    */
    bool CContextClient::getBuffers(const list<int>& serverList, const list<int>& sizeList, list<CBufferOut*>& retBuffers, bool nonBlocking /*= false*/)
    {
      list<int>::const_iterator itServer, itSize;
      list<CClientBuffer*> bufferList;
      map<int,CClientBuffer*>::const_iterator it;
      list<CClientBuffer*>::iterator itBuffer;
      bool areBuffersFree;

      for (itServer = serverList.begin(); itServer != serverList.end(); itServer++)
      {
        it = buffers.find(*itServer);
        if (it == buffers.end())
        {
          newBuffer(*itServer);
          it = buffers.find(*itServer);
        }
        bufferList.push_back(it->second);
      }

      CTimer::get("Blocking time").resume();
      do
      {
        areBuffersFree = true;
        for (itBuffer = bufferList.begin(), itSize = sizeList.begin(); itBuffer != bufferList.end(); itBuffer++, itSize++)
          areBuffersFree &= (*itBuffer)->isBufferFree(*itSize);

        if (!areBuffersFree)
        {
          checkBuffers();
          context->server->listen();
        }
      } while (!areBuffersFree && !nonBlocking);
      CTimer::get("Blocking time").suspend();

      if (areBuffersFree)
      {
        for (itBuffer = bufferList.begin(), itSize = sizeList.begin(); itBuffer != bufferList.end(); itBuffer++, itSize++)
          retBuffers.push_back((*itBuffer)->getBuffer(*itSize));
      }

      return areBuffersFree;
   }
コード例 #5
0
    /*!
    In case of attached mode, the current context must be reset to context for client
    \param [in] event Event sent to server
    */
    void CContextClient::sendEvent(CEventClient& event)
    {
      list<int> ranks = event.getRanks();

      if (!event.isEmpty())
      {
        list<int> sizes = event.getSizes();

        // We force the getBuffers call to be non-blocking on the servers
        list<CBufferOut*> buffList;
        bool couldBuffer = getBuffers(ranks, sizes, buffList, !CXios::isClient);

        if (couldBuffer)
        {
          event.send(timeLine, sizes, buffList);

          checkBuffers(ranks);

          if (isAttachedModeEnabled()) // couldBuffer is always true in attached mode
          {
            waitEvent(ranks);
            CContext::setCurrent(context->getId());
          }
        }
        else
        {
          tmpBufferedEvent.ranks = ranks;
          tmpBufferedEvent.sizes = sizes;

          for (list<int>::const_iterator it = sizes.begin(); it != sizes.end(); it++)
            tmpBufferedEvent.buffers.push_back(new CBufferOut(*it));

          event.send(timeLine, tmpBufferedEvent.sizes, tmpBufferedEvent.buffers);
        }
      }

      timeLine++;
    }
コード例 #6
0
    /*!
     * Send the temporarily buffered event (if any).
     *
     * \return true if a temporarily buffered event could be sent, false otherwise 
     */
    bool CContextClient::sendTemporarilyBufferedEvent()
    {
      bool couldSendTmpBufferedEvent = false;

      if (hasTemporarilyBufferedEvent())
      {
        list<CBufferOut*> buffList;
        if (getBuffers(tmpBufferedEvent.ranks, tmpBufferedEvent.sizes, buffList, true)) // Non-blocking call
        {
          list<CBufferOut*>::iterator it, itBuffer;

          for (it = tmpBufferedEvent.buffers.begin(), itBuffer = buffList.begin(); it != tmpBufferedEvent.buffers.end(); it++, itBuffer++)
            (*itBuffer)->put((char*)(*it)->start(), (*it)->count());

          checkBuffers(tmpBufferedEvent.ranks);

          tmpBufferedEvent.clear();

          couldSendTmpBufferedEvent = true;
        }
      }

      return couldSendTmpBufferedEvent;
    }
コード例 #7
0
ファイル: testfs.c プロジェクト: liuhaotian/sfs
/**
 * Performs various file operations.
 *
 * @param name name of file to create
 * @param fsize size of file to create
 * @return -1 upon failure, 0 otherwise
 */
int testFile(char* name, int fsize) {
    int fd = 0; /* file handle */
    int bytes, bytesToRead, offset;
    // fix fsize of too small
    if (fsize<=1) fsize=2;
    char *buf = (char *) malloc(sizeof(char) * fsize);
    char *cpy = (char *) malloc(sizeof(char) * fsize);

    LOG(stdout, "Create file...\n");

    fd = sfs_fopen(name);
    FAIL_BRK((fd == -1), stdout, "Error: Open file failed for: %s\n", name);

    initBuffer(buf, fsize);

    /* write to disk */
    FAIL_BRK((sfs_fwrite(fd, buf, fsize) == -1), stdout,
            "Error: Writing %d bytes to file %s failed!\n", fsize, name);

    /* close file */
    FAIL_BRK(sfs_fclose(fd), stdout, "Closing file %s failed!\n", name);

    /* save disk, close it and reload it to make sure changes are flushed to disk */
    FAIL_BRK(refreshDisk(), stdout, "Error: Refreshing disk failed\n");

    /* open file again */
    fd = sfs_fopen(name);
    FAIL_BRK((fd == -1), stdout, "Error: Second open file failed for: %s\n",
            name);

    /* read file */
    int fsize2;
    FAIL_BRK(((fsize2 = sfs_fread(fd, cpy, fsize)) == -1), stdout,
            "Read failed for: %s\n", name);

    FAIL_BRK(
            (fsize != fsize2),
            stdout,
            "Error: The amount we wrote (%d) is different from what we read (%d)\n",
            fsize, fsize2);

    /* check contents */
    FAIL_BRK(checkBuffers(buf, cpy, fsize, 0), stdout,
            "Error: Contents don't match\n");

    /* reset file */
    FAIL_BRK(sfs_fclose(fd), stdout, "Error: Closing file (%d)(%s) failed\n",
            fd, name);
    fd = sfs_fopen(name);
    FAIL_BRK((fd == -1), stdout, "Error: Opening file (%s) failed\n", name);

    free(cpy);
    cpy = (char *) malloc(sizeof(char) * fsize);

    /* check contents using small chunks */
    bytes = 0;
    while (bytes < fsize) {
        bytesToRead = rand() % 9 + 1;

        if (bytes + bytesToRead >= fsize) {
            bytesToRead = fsize - bytes;
        }

        /* read */
        int bytesActuallyRead;
        bytesActuallyRead = sfs_fread(fd, cpy + bytes, bytesToRead);
        FAIL_BRK((bytesActuallyRead == -1), stdout,
                "Error: Read failed for: %s\n", name);
        FAIL_BRK(
                (bytesActuallyRead != bytesToRead),
                stdout,
                "Error: For file (%s) expected to read (%d) but actually read (%d)\n",
                name, bytesToRead, bytesActuallyRead);

        bytes += bytesToRead;
    }

    FAIL_BRK(checkBuffers(buf, cpy, fsize, 0), stdout,
            "Error: Contents don't match\n");

    /* reset file */
    FAIL_BRK(sfs_fclose(fd), stdout, "Error: Closing file (%d) failed\n", fd);
    fd = sfs_fopen(name);
    FAIL_BRK((fd == -1), stdout, "Error: Opening file (%s) failed\n", name);

    free(cpy);
    cpy = (char *) malloc(sizeof(char) * fsize);

    /* check contents from offset */
    offset = rand() % (fsize - 1);
    bytesToRead = rand() % (fsize - offset);

    if (bytesToRead == 0)
        bytesToRead++;

    FAIL_BRK((sfs_lseek(fd, offset) == -1), stdout,
            "Error: lseek failed for: (%s) fd: (%d), offset: (%d)\n", name, fd,
            offset);

    /* read */
    int bytesActuallyRead = 0;
    bytesActuallyRead = sfs_fread(fd, cpy + offset, bytesToRead);
    FAIL_BRK((bytesActuallyRead == -1), stdout, "Error: Read failed for: %s\n",
            name);
    FAIL_BRK(
            (bytesActuallyRead != bytesToRead),
            stdout,
            "Error: For file (%s) expected to read (%d) but actually read (%d)\n",
            name, bytesToRead, bytesActuallyRead);

    FAIL_BRK(checkBuffers(buf, cpy, bytesToRead, offset), stdout,
            "Error: Contents do not match\n");

    FAIL_BRK(sfs_fclose(fd), stdout, "Error: Closing file (%d) failed\n", fd);

    SAFE_FREE(buf);
    SAFE_FREE(cpy);

    return 0; /* passed all tests */

    // Something went wrong...
    Fail:
    
    SAFE_FREE(buf);
    SAFE_FREE(cpy);
    
    return -1;
}
コード例 #8
0
ファイル: testfs.c プロジェクト: liuhaotian/sfs
/**
 * Create a big file, write lots of data to it and close it. Then append another chunk of data to it.
 */
int appendFile() {
    int hr = SUCCESS;
    int fsize1 = 20 * SD_SECTORSIZE;
    int fsize2 = 50 * SD_SECTORSIZE;
    char *buffer = malloc(fsize2 * sizeof(char));
    char *buffer2 = malloc(fsize2 * sizeof(char));

    char *fileName = "foo";

    // create the original file
    FAIL_BRK3(singleBigFile(fileName, fsize1), stdout,
            "Error: Unable to create the initial file\n");

    FAIL_BRK3(refreshDisk(), stdout, "Error: Refresh disk failed\n");

    // open it again
    int fd = sfs_fopen(fileName);
    FAIL_BRK3((fd == -1), stdout, "Error: Unable to reopen the file\n");

    // lseek to the end of the file
    int newPos = sfs_lseek(fd, fsize1 - 1);
    FAIL_BRK3(
            (newPos != fsize1 - 1),
            stdout,
            "Error: Seeking1 to the end of the file failed newPos (%d), fsize1(%d)\n",
            newPos, fsize1);

    initBuffer(buffer, fsize2);
    // write the new data
    int bytesWritten = sfs_fwrite(fd, buffer, fsize2);
    FAIL_BRK3((bytesWritten != fsize2), stdout,
            "Error: Appending write failed\n");

    // close the file
    FAIL_BRK3(sfs_fclose(fd), stdout, "Error: Closing the file failed\n");

    FAIL_BRK3(refreshDisk(), stdout, "Error: Refresh disk failed\n");

    // open it again
    fd = sfs_fopen(fileName);
    FAIL_BRK3((fd == -1), stdout, "Error: Unable to reopen the file\n");

    // again lseek to the place where we started appending
    newPos = sfs_lseek(fd, fsize1 - 1);
    FAIL_BRK3((newPos != fsize1 - 1), stdout,
            "Error: Seeking2 to the end of the file failed\n");

    // read the data
    int bytesRead = sfs_fread(fd, buffer2, fsize2);
    FAIL_BRK3((bytesRead != fsize2), stdout,
            "Error: Reading back the appended part failed\n");

    // make sure it matches
    FAIL_BRK3(checkBuffers(buffer, buffer2, fsize2, 0), stdout,
            "Error: Contents don't match\n");

    // close the file
    FAIL_BRK3(sfs_fclose(fd), stdout, "Error: Closing the file failed\n");

    // finalize
    Fail:

    // clean up
    SAFE_FREE(buffer);
    SAFE_FREE(buffer2);
    return hr;
}
コード例 #9
0
ファイル: copyfile.c プロジェクト: BackupTheBerlios/samqfs
/*
 * Stage all files in the stream.
 */
static void
copyStream()
{
	int rval;
	FileInfo_t *file;
	int dcache;
	boolean_t reject;

	StageInit(Stream->vsn);

	/* Set loading flag for this stream. */
	PthreadMutexLock(&Stream->mutex);
	SET_FLAG(Stream->flags, SR_LOADING);
	PthreadMutexUnlock(&Stream->mutex);

	rval = LoadVolume();

	/* Reject if mount/open failed. */
	if (rval != 0) {
		PthreadMutexLock(&Stream->mutex);
		removeDcachedFile(Stream, rval);

		if (rval == ENODEV) {
			Stream->context = 0;
			PthreadMutexUnlock(&Stream->mutex);
			rejectRequest(0, B_TRUE);
			SET_FLAG(Instance->ci_flags, CI_shutdown);
		} else {
			PthreadMutexUnlock(&Stream->mutex);
			SendCustMsg(HERE, 19017, Stream->vsn);
			rejectRequest(rval, B_TRUE);
		}

		StageEnd();
		return;
	}

	/* VSN load has completed. */
	checkBuffers(Stream->vsn);

	PthreadMutexLock(&Stream->mutex);
	CLEAR_FLAG(Stream->flags, SR_LOADING);

	Instance->ci_seqnum = Stream->seqnum;
	reject = B_FALSE;

	/*
	 * Copy all files in stage stream request.  The files have
	 * been ordered to eliminate backward media positioning.
	 */

	while (STREAM_IS_VALID() && reject == B_FALSE) {

		/* Stop staging if parent died. */
		if (getppid() == 1) {
			SetErrno = 0;		/* set for trace */
			Trace(TR_ERR, "Detected stager daemon exit");

			Stream->first = EOS;
			SET_FLAG(Instance->ci_flags, CI_shutdown);
			break;
		}

		file = GetFile(Stream->first);

		PthreadMutexLock(&file->mutex);
		PthreadMutexUnlock(&Stream->mutex);

		/*
		 * If the first vsn, clear bytes read count.
		 * And if multivolume and stage -n set, initialize
		 * residual length.
		 */
		if (file->vsn_cnt == 0) {
			file->read = 0;
			if (GET_FLAG(file->flags, FI_MULTIVOL) &&
			    GET_FLAG(file->flags, FI_STAGE_NEVER)) {
				file->residlen = file->len;
			} else {
				file->residlen = 0;
			}
		}

		SET_FLAG(file->flags, FI_ACTIVE);

		PthreadMutexUnlock(&file->mutex);

		/* Set file in io control structure for archive read thread. */
		setIoThread(file);

		/* Log stage start. */
		file->eq = IoThread->io_drive;
		LogIt(LOG_STAGE_START, file);

		/*
		 * Check if last request was canceled.  If the last request
		 * was canceled, invalidate i/o buffers and clear cancel
		 * flag in the control structure.
		 */
		if (GET_FLAG(IoThread->io_flags, IO_cancel)) {
			ResetBuffers();
			CLEAR_FLAG(IoThread->io_flags, IO_cancel);
		}

		/*
		 * Next archive file.  If disk archive, we may be opening
		 * a disk archive tarball.
		 */
		if ((rval = NextArchiveFile()) == 0) {
			/* Prepare filesystem to receive staged file. */
			dcache = DiskCacheOpen(file);

		} else {
			/* Unable to open disk archive.  Error request. */
			Trace(TR_ERR, "Unable to open disk archive "
			    "copy: %d inode: %d.%d errno: %d",
			    file->copy + 1, file->id.ino, file->id.gen, errno);
			dcache = -1;
			file->error = errno;
			SendErrorResponse(file);
		}

		if (dcache >= 0 && rval == 0) {
			/*
			 * Notify reader thread that next file in stream
			 * is ready to be staged.
			 */
			ThreadStatePost(&IoThread->io_readReady);

			/* Write data to disk cache. */
			rval = DiskCacheWrite(file, dcache);

			if (rval != 0) {
				SendErrorResponse(file);

				/* Check if number of stream errors exceeded. */
				reject = ifMaxStreamErrors(file);
			}

			ThreadStateWait(&IoThread->io_readDone);

		} else if (rval != 0 && dcache >= 0) {
			/* Setup for error handling. */
			SetFileError(file, dcache, 0, EIO);
			SendErrorResponse(file);
		}

		EndArchiveFile();

		/* Remove file from stream before marking it as done. */
		PthreadMutexLock(&Stream->mutex);
		Stream->first = file->next;

		/* Device not available. */
		if (file->error == ENODEV) {
			SetErrno = 0;	/* set for trace */
			Trace(TR_ERR, "No device available");

			reject = B_TRUE;
			if (NumOpenFiles <= 0 && Instance->ci_first == NULL) {
				SET_FLAG(Instance->ci_flags, CI_shutdown);
				Instance->ci_busy = B_TRUE;
			}
		}

		/* Mark file staging as done. */
		SetStageDone(file);
		Stream->count--;

		if (Stream->first == EOS) {
			Stream->last = EOS;
		}

	}

	/* Reject rest of stages in this stream. */
	if (reject == B_TRUE) {
		if (Stream->first > EOS) {
			removeDcachedFile(Stream, ENODEV);
		}
		PthreadMutexUnlock(&Stream->mutex);
		rejectRequest(ENODEV, B_FALSE);
		PthreadMutexLock(&Stream->mutex);
	}

	/* Remove copy request, no one is waiting on it. */
	RemoveMapFile(copyRequestPath, Request, sizeof (CopyRequestInfo_t));
	Request = NULL;

	/* Ready to unload.  Mark stream as done. */
	SET_FLAG(Stream->flags, SR_DONE);
	PthreadMutexUnlock(&Stream->mutex);

	UnloadVolume();

	/*
	 * Unmap pages of memory.  Stream's memory
	 * mapped file is removed in parent.
	 */
	UnMapFile(Stream, sizeof (StreamInfo_t));
	Stream = NULL;

	StageEnd();
}