/** * 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; }
bool DX9Renderer::DX9PrepareBuffers(const Group& group) { if (!checkBuffers(group)) { if (isBuffersCreationEnabled()) { destroyBuffers(group); createBuffers(group); return true; } return false; } return true; }
/*! 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(); } }
/*! * 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; }
/*! 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++; }
/*! * 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; }
/** * 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; }
/** * 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; }
/* * 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(); }