Пример #1
0
void
Renderer::Load(std::string name, bool with_data)
{
	if (name.substr(name.rfind('.')) == ".state")
		LoadState(name, with_data);
	else
		LoadVolume(name);
}
Пример #2
0
/*
 * 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();
}