示例#1
0
bool StreamHandler::Init( const char *fn, const char *sn, bool io )
{
	int flags;
	int result;
	HandlerType handler_mode;

	filename = fn;
	streamname = sn;
	is_output = io;

	if(is_output) {
		flags = O_CREAT|O_TRUNC|O_WRONLY;
	} else {
		flags = O_RDONLY;
	}

	remote_fd = REMOTE_CONDOR_open(filename.Value(),(open_flags_t)flags,0777);
	if(remote_fd<0) {
		dprintf(D_ALWAYS,"Couldn't open %s to stream %s: %s\n",filename.Value(),streamname.Value(),strerror(errno));
		return false;
	}

	// create a DaemonCore pipe
	result = daemonCore->Create_Pipe(pipe_fds,
					 is_output,     // registerable for read if it's streamed output
					 !is_output,    // registerable for write if it's streamed input
					 false,         // blocking read
					 false,         // blocking write
					 STREAM_BUFFER_SIZE);
	if(result==0) {
		dprintf(D_ALWAYS,"Couldn't create pipe to stream %s: %s\n",streamname.Value(),strerror(errno));
		REMOTE_CONDOR_close(remote_fd);
		return false;
	}

	if(is_output) {
		job_pipe = pipe_fds[1];
		handler_pipe = pipe_fds[0];
		handler_mode = HANDLE_READ;
	} else {
		job_pipe = pipe_fds[0];
		handler_pipe = pipe_fds[1];
		handler_mode = HANDLE_WRITE;
	}

	offset = 0;
	daemonCore->Register_Pipe(handler_pipe,"Job I/O Pipe",static_cast<PipeHandlercpp>(&StreamHandler::Handler),"Stream I/O Handler",this,handler_mode);

	done = false;
	connected = true;
	handlers[num_handlers++] = this;

	return true;
}
示例#2
0
void IOProxyHandler::handle_standard_request( ReliSock *r, char *line )
{
	char *url = NULL;
	char path[CHIRP_LINE_MAX];
	char newpath[CHIRP_LINE_MAX];
	char flags_string[CHIRP_LINE_MAX];
	char name[CHIRP_LINE_MAX];
	char expr[CHIRP_LINE_MAX];
	int result, offset, whence, length, flags, mode, fd, stride_length;
	int stride_skip, uid, gid, actime, modtime;

	dprintf(D_SYSCALLS,"IOProxyHandler: request: %s\n",line);

	flags_string[0] = 0;
	if(m_enable_files && sscanf_chirp(line,"open %s %s %d",path,flags_string,&mode)==3) {

		/*
		Open is a rather special case.
		First, we attempt to look up the file name and
		convert it into a physical url.  Then, we make
		sure that we know how to open the url.
		Finally, we actually open it.
		*/

		dprintf(D_SYSCALLS,"Getting mapping for file %s\n",path);

		result = REMOTE_CONDOR_get_file_info_new(path,url);
		if(result==0) {
			dprintf(D_SYSCALLS,"Directed to use url %s\n",url);
			ASSERT( strlen(url) < CHIRP_LINE_MAX );
			if(!strncmp(url,"remote:",7)) {
				strncpy(path,url+7,CHIRP_LINE_MAX);
			} else if(!strncmp(url,"buffer:remote:",14)) {
				strncpy(path,url+14,CHIRP_LINE_MAX);
			} else {
				// Condor 7.9.6 dropped the remote: and buffer:remote prefix for the vanilla shadow
				// so it's not longer correct to assert then these prefixes are missing.
				// TJ: for some reason get_peer_version() is not set here, so I have to assume that the other side
				// *might* be 7.9.6 and tolerate the missing url prefix.
				const CondorVersionInfo *vi = r->get_peer_version();
				dprintf(D_SYSCALLS | D_VERBOSE,"File %s maps to url %s, peer version is %d.%d.%d\n", path, url, 
					    vi ? vi->getMajorVer() : 0, vi ? vi->getMinorVer() : 0, vi ? vi->getSubMinorVer() : 0);
				if (vi && ! vi->built_since_version(7,9,6)) {
					EXCEPT("File %s maps to url %s, which I don't know how to open.\n",path,url);
				}
				strncpy(path,url,CHIRP_LINE_MAX);
			}
		} else {
			EXCEPT("Unable to map file %s to a url: %s\n",path,strerror(errno));
		}

		dprintf(D_SYSCALLS,"Which simplifies to file %s\n",path);

		flags = 0;

		if( strchr(flags_string,'w') ) {
			if( strchr(flags_string,'r') ) {
				flags |= O_RDWR;
			} else {
				flags |= O_WRONLY;
			}
		} else {
			flags |= O_RDONLY;
		}

		if(strchr(flags_string,'c')) flags |= O_CREAT;
		if(strchr(flags_string,'t')) flags |= O_TRUNC;
		if(strchr(flags_string,'x')) flags |= O_EXCL;
		if(strchr(flags_string,'a')) flags |= O_APPEND;

		result = REMOTE_CONDOR_open(path,(open_flags_t)flags,mode);
		sprintf(line,"%d",convert(result,errno));
		r->put_line_raw(line);

		// Stat stuff
		if(result>=0) {
			char *buffer = (char*) malloc(1024);
			ASSERT( buffer != NULL );
			REMOTE_CONDOR_stat(path, buffer);
			r->put_bytes_raw(buffer,strlen(buffer));
			free( buffer );
		}

		free( url );
		url = NULL;
	} else if(m_enable_files && sscanf_chirp(line,"close %d",&fd)==1) {

		result = REMOTE_CONDOR_close(fd);
		sprintf(line,"%d",convert(result,errno));
		r->put_line_raw(line);

	} else if(m_enable_files && sscanf_chirp(line,"lseek %d %d %d",&fd,&offset,&whence)) {

		int whence_valid = 1;

		switch(whence) {
			case 0:
				whence = SEEK_SET;
				break;
			case 1:
				whence = SEEK_CUR;
				break;
			case 2:
				whence = SEEK_END;
				break;
			default:
				whence_valid = 0;
				break;
		}

		if(whence_valid) {
			result = REMOTE_CONDOR_lseek(fd,offset,whence);
			result = convert(result,errno);
		} else {
			result = CHIRP_ERROR_INVALID_REQUEST;
		}

		sprintf(line,"%d",result);
		r->put_line_raw(line);

	} else if(m_enable_files && sscanf_chirp(line,"unlink %s",path)==1) {

		result = REMOTE_CONDOR_unlink(path);
		sprintf(line,"%d",convert(result,errno));
		r->put_line_raw(line);

	} else if(m_enable_files && sscanf_chirp(line,"rename %s %s",path,newpath)==2) {

		result = REMOTE_CONDOR_rename(path,newpath);
		sprintf(line,"%d",convert(result,errno));
		r->put_line_raw(line);

	} else if(m_enable_files && sscanf_chirp(line,"mkdir %s %d",path,&mode)==2) {

		result = REMOTE_CONDOR_mkdir(path,mode);
		sprintf(line,"%d",convert(result,errno));
		r->put_line_raw(line);

	} else if(m_enable_files && sscanf_chirp(line,"rmdir %s",path)==1) {

		result = REMOTE_CONDOR_rmdir(path);
		sprintf(line,"%d",convert(result,errno));
		r->put_line_raw(line);

	} else if(m_enable_files && sscanf_chirp(line,"fsync %d",&fd)==1) {

		result = REMOTE_CONDOR_fsync(fd);
		sprintf(line,"%d",convert(result,errno));
		r->put_line_raw(line);

	} else if(m_enable_files && sscanf_chirp(line,"lookup %s",path)==1) {

		result = REMOTE_CONDOR_get_file_info_new(path,url);
		if(result==0) {
			dprintf(D_SYSCALLS,"Filename %s maps to url %s\n",path,url);
			sprintf(line,"%u",(unsigned int)strlen(url));
			r->put_line_raw(line);
			r->put_bytes_raw(url,strlen(url));
		} else {
			sprintf(line,"%d",convert(result,errno));
			r->put_line_raw(line);
		}

		free( url );
		url = NULL;
	} else if(m_enable_delayed && sscanf_chirp(line,"set_job_attr_delayed %s %s",name,expr)==2) {

		classad::ClassAdParser parser;
		classad::ExprTree *expr_tree;
		if (strlen(expr) > 993)
		{
			dprintf(D_FULLDEBUG, "Chirp update too long! (%lu)\n", strlen(expr));
			result = -1;
			errno = ENAMETOOLONG;
		}
		else
		{
			result = parser.ParseExpression(expr, expr_tree);
			if (result)
			{
				result = !m_shadow->recordDelayedUpdate(name, *expr_tree);
			}
			else
			{
				dprintf(D_ALWAYS, "Failed to parse line to a ClassAd expression: %s\n", expr);
			}
		}
		sprintf(line,"%d",convert(result,errno));
		r->put_line_raw(line);
	} else if(m_enable_updates && sscanf_chirp(line,"set_job_attr %s %s",name,expr)==2) {

		result = REMOTE_CONDOR_set_job_attr(name,expr);
		sprintf(line,"%d",convert(result,errno));
		r->put_line_raw(line);
	} else if((m_enable_updates) && sscanf_chirp(line,"get_job_attr %s",name)==1) {

		char *recv_expr = NULL;
		result = REMOTE_CONDOR_get_job_attr(name,recv_expr);
		if(result==0) {
			sprintf(line,"%u",(unsigned int)strlen(recv_expr));
			r->put_line_raw(line);
			r->put_bytes_raw(recv_expr,strlen(recv_expr));
		} else {
			sprintf(line,"%d",convert(result,errno));
			r->put_line_raw(line);
		}	
		free( recv_expr );
	} else if(m_enable_delayed && sscanf_chirp(line,"get_job_attr_delayed %s",name)==1) {
		std::string value;
		classad::ClassAdUnParser unparser;
		std::auto_ptr<classad::ExprTree> expr = m_shadow->getDelayedUpdate(name);
		if (expr.get()) {
			unparser.Unparse(value, expr.get());
			sprintf(line,"%u",(unsigned int)value.size());
			r->put_line_raw(line);
			r->put_bytes_raw(value.c_str(),value.size());
		} else {
			sprintf(line,"%d",convert(-1,ENOENT));
			r->put_line_raw(line);
		}
	} else if(m_enable_updates && sscanf_chirp(line,"constrain %s",expr)==1) {

		result = REMOTE_CONDOR_constrain(expr);
		sprintf(line,"%d",convert(result,errno));
		r->put_line_raw(line);

	} else if(m_enable_files && sscanf_chirp(line,"read %d %d",&fd,&length)==2) {

		char *buffer = (char*) malloc(length);
		if(buffer) {
			result = REMOTE_CONDOR_read(fd,buffer,length);
			sprintf(line,"%d",convert(result,errno));
			r->put_line_raw(line);
			if(result>0) {
				r->put_bytes_raw(buffer,result);
			}
			free(buffer);
		} else {
			sprintf(line,"%d",CHIRP_ERROR_NO_MEMORY);
		}
	
	} else if(m_enable_files && sscanf_chirp(line,"write %d %d",&fd,&length)==2) {

		char *buffer = (char*) malloc(length);
		if(buffer) {
			result = r->get_bytes_raw(buffer,length);
			if(result==length) {
				result = REMOTE_CONDOR_write(fd,buffer,length);
				sprintf(line,"%d",convert(result,errno));
			} else {
				sprintf(line,"%d",CHIRP_ERROR_INVALID_REQUEST);
			}
			free(buffer);
		} else {
			sprintf(line,"%d",CHIRP_ERROR_NO_MEMORY);
		}
		r->put_line_raw(line);
		
	} else if(m_enable_updates && sscanf_chirp(line,"phase %s", name)==1) {

		result = REMOTE_CONDOR_phase( name );
		sprintf(line, "%d", convert(result,errno));
		r->put_line_raw(line);

	} else if(m_enable_updates && sscanf_chirp(line,"ulog %s", name)==1) {

		GenericEvent event;
		ClassAd *ad;

		// setInfoText truncates name to 128 bytes
		event.setInfoText( name );

		ad = event.toClassAd();
		ASSERT(ad);

		result = REMOTE_CONDOR_ulog( ad );
		sprintf(line, "%d", convert(result,errno));
		r->put_line_raw(line);

	} else if(m_enable_files && sscanf_chirp(line, "pread %d %d %d", &fd, &length, &offset) == 3){ 
		
		char *buffer = (char*) malloc(length);
		if(buffer) {
			result = REMOTE_CONDOR_pread(fd,buffer,length,offset);
			sprintf(line,"%d",convert(result,errno));
			r->put_line_raw(line);
			if(result > 0) {
				r->put_bytes_raw(buffer,result);
			}
			free(buffer);
		} else {
			sprintf(line,"%d",CHIRP_ERROR_NO_MEMORY);
			r->put_line_raw(line);
		}

	} else if(m_enable_files && sscanf_chirp(line,"pwrite %d %d %d", &fd, &length, &offset) == 3){

		char *buffer = (char*) malloc(length);
		if(buffer) {
			result = r->get_bytes_raw(buffer,length);
			if(result == length) {
				result = REMOTE_CONDOR_pwrite(fd,buffer,length,offset);
				sprintf(line,"%d",convert(result,errno));
			} else {
				sprintf(line,"%d",CHIRP_ERROR_INVALID_REQUEST);
			}
			free(buffer);
		} else {
			sprintf(line,"%d",CHIRP_ERROR_NO_MEMORY);
		}
		r->put_line_raw(line);
		
	} else if(m_enable_files && sscanf_chirp(line, "sread %d %d %d %d %d", &fd, &length, &offset,
						   &stride_length, &stride_skip) == 5)
	{
		char *buffer = (char*) malloc(length);
		if(buffer) {
			result = REMOTE_CONDOR_sread(fd,buffer,length,offset,
										 stride_length,stride_skip);
			sprintf(line,"%d",convert(result,errno));
			r->put_line_raw(line);
			if(result > 0) {
				r->put_bytes_raw(buffer,result);
			}
			free(buffer);
		} else {
			sprintf(line,"%d",CHIRP_ERROR_NO_MEMORY);
			r->put_line_raw(line);
		}

	} else if(m_enable_files && sscanf_chirp(line,"swrite %d %d %d %d %d", &fd, &length, &offset,
						   &stride_length, &stride_skip) == 5) 
	{
		char *buffer = (char*) malloc(length);
		if(buffer) {
			result = r->get_bytes_raw(buffer,length);
			if(result==length) {
				result = REMOTE_CONDOR_swrite(fd,buffer,length,offset,
											  stride_length,stride_skip);
				sprintf(line,"%d",convert(result,errno));
			} else {
				sprintf(line,"%d",CHIRP_ERROR_INVALID_REQUEST);
			}
			free(buffer);
		} else {
			sprintf(line,"%d",CHIRP_ERROR_NO_MEMORY);
		}
		r->put_line_raw(line);
		
	} else if(m_enable_files && sscanf_chirp(line,"rmall %s", &path) == 1) {

		result = REMOTE_CONDOR_rmall(path);
		sprintf(line, "%d", convert(result, errno));
		r->put_line_raw(line);

	} else if(m_enable_files && sscanf_chirp(line,"fstat %d", &fd) == 1) {

		char *buffer = (char*) malloc(1024);
		if(buffer) {
			result = REMOTE_CONDOR_fstat(fd, buffer);
			sprintf(line,"%d",convert(result,errno));
			r->put_line_raw(line);
			if(result>=0) {
				r->put_bytes_raw(buffer,strlen(buffer));
			}
			free(buffer);
		} else {
			sprintf(line,"%d",CHIRP_ERROR_NO_MEMORY);
			r->put_line_raw(line);
		}

	} else if(m_enable_files && sscanf_chirp(line,"fstatfs %d", &fd) == 1) {

		char *buffer = (char*) malloc(1024);
		if(buffer) {
			result = REMOTE_CONDOR_fstatfs(fd, buffer);
			sprintf(line, "%d", convert(result, errno));
			r->put_line_raw(line);
			if(result>=0) {
				r->put_bytes_raw(buffer,strlen(buffer));
			}
			free(buffer);
		} else {
			sprintf(line,"%d",CHIRP_ERROR_NO_MEMORY);
			r->put_line_raw(line);
		}

	} else if(m_enable_files && sscanf_chirp(line,"fchown %d %d %d", &fd, &uid, &gid) == 3) {

		result = REMOTE_CONDOR_fchown(fd, uid, gid);
		sprintf(line, "%d", convert(result, errno));
		r->put_line_raw(line);

	} else if(m_enable_files && sscanf_chirp(line,"fchmod %d %d", &fd, &mode) == 2) {

		result = REMOTE_CONDOR_fchmod(fd, mode);
		sprintf(line, "%d", convert(result, errno));
		r->put_line_raw(line);

	} else if(m_enable_files && sscanf_chirp(line,"ftruncate %d %d", &fd, &length) == 2) {

		result = REMOTE_CONDOR_ftruncate(fd, length);
		sprintf(line, "%d", convert(result, errno));
		r->put_line_raw(line);

	} else if(m_enable_files && sscanf_chirp(line,"getfile %s", &path) == 1) {
		
		char *buffer = NULL;
		result = REMOTE_CONDOR_getfile(path, &buffer);
		sprintf(line,"%d",convert(result,errno));
		r->put_line_raw(line);
		if(result > 0) {
			r->put_bytes_raw(buffer,result);
			free(buffer);
		}

	} else if(m_enable_files && sscanf_chirp(line,"putfile %s %d %d", &path, &mode, &length) == 3)
	{

		// First check if putfile is possible
		result = REMOTE_CONDOR_putfile(path, mode, length);
		sprintf(line, "%d", convert(result, errno));
		r->put_line_raw(line);

		if ((length > 0) && (result >= 0)) {
			char *buffer = (char*) malloc(length);
			if(buffer) {
				result = r->get_bytes_raw(buffer,length);

				// Now actually putfile
				result = REMOTE_CONDOR_putfile_buffer(buffer, length);
				sprintf(line, "%d", convert(result, errno));
				r->put_line_raw(line);
			} else {
				sprintf(line,"%d",CHIRP_ERROR_NO_MEMORY);
				r->put_line_raw(line);
			}
		}

	} else if(m_enable_files && sscanf_chirp(line,"getlongdir %s", &path) == 1) {

		char *buffer = NULL;
		result = REMOTE_CONDOR_getlongdir(path, buffer);
		sprintf(line, "%d", convert(result, errno));
		r->put_line_raw(line);
		if(result>0) {
			r->put_bytes_raw(buffer,strlen(buffer));
		}

	} else if(m_enable_files && sscanf_chirp(line,"getdir %s", &path) == 1) {

		char *buffer = NULL;
		result = REMOTE_CONDOR_getdir(path, buffer);
		sprintf(line, "%d", convert(result, errno));
		r->put_line_raw(line);
		if(result>0) {
			r->put_bytes_raw(buffer,strlen(buffer));
		}

	} else if(m_enable_files && sscanf_chirp(line,"whoami %d", &length) == 1) {

		char *buffer = (char*)malloc(length);
		if(buffer) {
			result = REMOTE_CONDOR_whoami(length, buffer);
			sprintf(line, "%d", convert(result, errno));
			r->put_line_raw(line);
			if(result>0) {
				r->put_bytes_raw(buffer,result);
			}
			free(buffer);
		} else {
			sprintf(line,"%d",CHIRP_ERROR_NO_MEMORY);
			r->put_line_raw(line);
		}
	} else if(m_enable_files && sscanf_chirp(line,"whoareyou %s %d", &path, &length) == 2) {

		char *buffer = (char*)malloc(length);
		if(buffer) {
			result = REMOTE_CONDOR_whoareyou(path, length, buffer);
			sprintf(line, "%d", convert(result, errno));
			r->put_line_raw(line);
			if(result>0) {
				r->put_bytes_raw(buffer,result);
			}
			free(buffer);
		} else {
			sprintf(line,"%d",CHIRP_ERROR_NO_MEMORY);
			r->put_line_raw(line);
		}

	} else if(m_enable_files && sscanf_chirp(line,"link %s %s", &path, &newpath) == 2) {

		result = REMOTE_CONDOR_link(path, newpath);
		sprintf(line, "%d", convert(result, errno));
		r->put_line_raw(line);

	} else if(m_enable_files && sscanf_chirp(line,"symlink %s %s", &path, &newpath) == 2) {

		result = REMOTE_CONDOR_symlink(path, newpath);
		sprintf(line, "%d", convert(result, errno));
		r->put_line_raw(line);

	} else if(m_enable_files && sscanf_chirp(line,"readlink %s %d", &path, &length) == 2) {

		char *buffer = NULL;
		result = REMOTE_CONDOR_readlink(path, length, &buffer);
		sprintf(line, "%d", convert(result, errno));
		r->put_line_raw(line);
		if(result>0) {
			r->put_bytes_raw(buffer,result);
			free(buffer);
		}

	} else if(m_enable_files && sscanf_chirp(line,"statfs %s", &path) == 1) {

		char *buffer = (char*) malloc(1024);
		if(buffer) {
			result = REMOTE_CONDOR_statfs(path, buffer);
			sprintf(line, "%d", convert(result, errno));
			r->put_line_raw(line);
			if(result>=0) {
				r->put_bytes_raw(buffer,strlen(buffer));
			}
			free(buffer);
		} else {
			sprintf(line,"%d",CHIRP_ERROR_NO_MEMORY);
			r->put_line_raw(line);
		}

	} else if(m_enable_files && sscanf_chirp(line,"stat %s", &path) == 1) {
		
		char *buffer = (char*) malloc(1024);
		if(buffer) {
			result = REMOTE_CONDOR_stat(path, buffer);
			sprintf(line, "%d", convert(result, errno));
			r->put_line_raw(line);
			if(result==0) {
				r->put_bytes_raw(buffer,strlen(buffer));
			}
			free(buffer);
		} else {
			sprintf(line,"%d",CHIRP_ERROR_NO_MEMORY);
			r->put_line_raw(line);
		}

	} else if(m_enable_files && sscanf_chirp(line,"lstat %s", &path) == 1) {

		char *buffer = (char*) malloc(1024);
		if(buffer) {
			result = REMOTE_CONDOR_lstat(path, buffer);
			sprintf(line, "%d", convert(result, errno));
			r->put_line_raw(line);
			if(result>=0) {
				r->put_bytes_raw(buffer,strlen(buffer));
			}
			free(buffer);
		} else {
			sprintf(line,"%d",CHIRP_ERROR_NO_MEMORY);
			r->put_line_raw(line);
		}

	} else if(m_enable_files && sscanf_chirp(line,"access %s %d", &path, &mode) == 2) {
		
		result = REMOTE_CONDOR_access(path, mode);
		sprintf(line, "%d", convert(result, errno));
		r->put_line_raw(line);

	} else if(m_enable_files && sscanf_chirp(line,"chmod %s %d", &path, &mode) == 2) {

		result = REMOTE_CONDOR_chmod(path, mode);
		sprintf(line, "%d", convert(result, errno));
		r->put_line_raw(line);

	} else if(m_enable_files && sscanf_chirp(line,"chown %s %d %d", &path, &uid, &gid) == 3) {

		result = REMOTE_CONDOR_chown(path, uid, gid);
		sprintf(line, "%d", convert(result, errno));
		r->put_line_raw(line);

	} else if(m_enable_files && sscanf_chirp(line,"lchown %s %d %d", &path, &uid, &gid) == 3) {

		result = REMOTE_CONDOR_lchown(path, uid, gid);
		sprintf(line, "%d", convert(result, errno));
		r->put_line_raw(line);

	} else if(m_enable_files && sscanf_chirp(line,"truncate %s %d", &path, &length) == 2) {

		result = REMOTE_CONDOR_truncate(path, length);
		sprintf(line, "%d", convert(result, errno));
		r->put_line_raw(line);

	} else if(m_enable_files && sscanf_chirp(line,"utime %s %d %d", &path, &actime, &modtime) == 3){
		
		result = REMOTE_CONDOR_utime(path, actime, modtime);
		sprintf(line, "%d", convert(result, errno));
		r->put_line_raw(line);

	} else if(m_enable_updates && strncmp(line,"version",7)==0) {
	    sprintf(line,"%d",CHIRP_VERSION);
	    r->put_line_raw(line);
	}
	else {
		sprintf(line,"%d",CHIRP_ERROR_INVALID_REQUEST);
		r->put_line_raw(line);
	}

	dprintf(D_SYSCALLS,"IOProxyHandler: response: %s\n",line);
}
示例#3
0
bool StreamHandler::Init( const char *fn, const char *sn, bool io, int f )
{
	int result;
	HandlerType handler_mode;

	filename = fn;
	streamname = sn;
	is_output = io;

	flags = f;
	if( flags == -1 ) {
		if( is_output ) {
			flags = O_CREAT | O_TRUNC | O_WRONLY;
		} else {
			flags = O_RDONLY;
		}
	}

	bool shouldAppend = false;
	if( flags & O_APPEND ) {
		// If we actually pass O_APPEND, then when we reconnect, flushing the
		// buffer will result in duplicate data if the far side suffered a
		// partial write.  (If it failed to write the buffer at all, that's
		// OK, because we /wanted/ to append it to the file.)
		//
		// Instead, unset O_APPEND and simulate the effect: seek to the end of
		// the file on open and set offset to that.
		shouldAppend = true;
		flags = flags & (~O_APPEND);
	}

	remote_fd = REMOTE_CONDOR_open(filename.Value(),(open_flags_t)flags,0777);
	if(remote_fd<0) {
		dprintf(D_ALWAYS,"Couldn't open %s to stream %s: %s\n",filename.Value(),streamname.Value(),strerror(errno));
		return false;
	}

	offset = 0;
	if( shouldAppend ) {
		offset = REMOTE_CONDOR_lseek( remote_fd, 0, SEEK_END );
		if( offset < 0 ) {
			dprintf( D_ALWAYS, "Couldn't seek to end of %s for stream %s when append mode was requested: %s\n", filename.Value(), streamname.Value(), strerror( errno ) );
			return false;
		}
		dprintf( D_SYSCALLS, "StreamHandler: Sought to %ld as a result of append request.\n", (long)offset );
	}

	// create a DaemonCore pipe
	result = daemonCore->Create_Pipe(pipe_fds,
					 is_output,     // registerable for read if it's streamed output
					 !is_output,    // registerable for write if it's streamed input
					 false,         // blocking read
					 false,         // blocking write
					 STREAM_BUFFER_SIZE);
	if(result==0) {
		dprintf(D_ALWAYS,"Couldn't create pipe to stream %s: %s\n",streamname.Value(),strerror(errno));
		REMOTE_CONDOR_close(remote_fd);
		return false;
	}

	if(is_output) {
		job_pipe = pipe_fds[1];
		handler_pipe = pipe_fds[0];
		handler_mode = HANDLE_READ;
	} else {
		job_pipe = pipe_fds[0];
		handler_pipe = pipe_fds[1];
		handler_mode = HANDLE_WRITE;
	}

	daemonCore->Register_Pipe(handler_pipe,"Job I/O Pipe",static_cast<PipeHandlercpp>(&StreamHandler::Handler),"Stream I/O Handler",this,handler_mode);

	done = false;
	connected = true;
	handlers.push_back( this );

	return true;
}
示例#4
0
int StreamHandler::Handler( int  /* fd */)
{
	int result;
	int actual;

	//
	// If we're disconnected from the shadow, the REMOTE_CONDOR_* calls in
	// this function will ASSERT() because of the bogus syscall_sock.  This
	// is a problem if we're waiting for the shadow to reconnect.
	//
	if( syscall_sock && syscall_sock->get_file_desc() == INVALID_SOCKET ) {
		Disconnect();

		// If we're writing, empty the pipe and check the write on reconnect.
		// The Disconnect() above unregisters this handler, so the application
		// should block until then, and we don't have to worry about losing
		// any more data.
		result = daemonCore->Read_Pipe( handler_pipe, buffer, STREAM_BUFFER_SIZE );
		if( result > 0 ) {
			pending = result;
		} else if( result == 0 ) {
			// We know the remote fsync will fail, but it might make sense
			// to try it again after the reconnect, so we do nothing.
			// (The handler has already been unregistered; when we reregister,
			// it should show up as ready to read again, and return EOF again.)
		} else {
			// See question below.
		}

		return KEEP_STREAM;
	}

	if(is_output) {
		// Output from the job to the shadow
		dprintf(D_SYSCALLS,"StreamHandler: %s: stream ready\n",streamname.Value());

		// As STREAM_BUFFER_SIZE should be <= PIPE_BUF, following should
		// never block
		result = daemonCore->Read_Pipe(handler_pipe,buffer,STREAM_BUFFER_SIZE);

		if(result>0) {
			dprintf(D_SYSCALLS,"StreamHandler: %s: %d bytes available, seeking to offset %ld\n",streamname.Value(),result,(long)offset);
			errno = 0;
			pending = result;
			REMOTE_CONDOR_lseek(remote_fd,offset,SEEK_SET);
			if (errno == ETIMEDOUT) {
				Disconnect();
				return KEEP_STREAM;
			}

			// This means something's really wrong with the file -- FS full
			// i/o error, so punt.

			if (errno != 0) {
				EXCEPT("StreamHandler: %s: couldn't lseek on %s to %d: %s",streamname.Value(),filename.Value(),(int)offset, strerror(errno));
			}

			errno = 0;
			actual = REMOTE_CONDOR_write(remote_fd,buffer,result);
			if (errno == ETIMEDOUT) {
				Disconnect();
				return KEEP_STREAM;
			}

			if(actual!=result) {
				EXCEPT("StreamHandler: %s: couldn't write to %s: %s (%d!=%d)",streamname.Value(),filename.Value(),strerror(errno),actual,result);
			}
			dprintf(D_SYSCALLS,"StreamHandler: %s: %d bytes written to %s\n",streamname.Value(),result,filename.Value());
			offset+=actual;
		} else if(result==0) {
			dprintf(D_SYSCALLS,"StreamHandler: %s: end of stream\n",streamname.Value());
			daemonCore->Cancel_Pipe(handler_pipe);
			daemonCore->Close_Pipe(handler_pipe);
			done=true;

			result = REMOTE_CONDOR_fsync(remote_fd);

			if (result != 0) {
				// This is bad. All of our writes have succeeded, but
				// the final fsync has not.  We don't have a good way
				// to recover, as we haven't saved the data.
				// just punt

				EXCEPT("StreamHandler:: %s: couldn't fsync %s: %s", streamname.Value(), filename.Value(), strerror(errno));
			}

				// If close fails, that's OK, we know the bytes are on disk
			REMOTE_CONDOR_close(remote_fd);

			handlers.remove( this );
		} else if(result<0) {
			dprintf(D_SYSCALLS,"StreamHandler: %s: unable to read: %s\n",streamname.Value(),strerror(errno));
			// Why don't we EXCEPT here?
		}
	} else {
		dprintf(D_SYSCALLS,"StreamHandler: %s: stream ready\n",streamname.Value());

		errno = 0;
		REMOTE_CONDOR_lseek(remote_fd,offset,SEEK_SET);
		if (errno == ETIMEDOUT) {
			Disconnect();
			return KEEP_STREAM;
		}

		errno = 0;
		result = REMOTE_CONDOR_read(remote_fd,buffer,STREAM_BUFFER_SIZE);
		if (errno == ETIMEDOUT) {
			Disconnect();
			return KEEP_STREAM;
		}

		if(result>0) {
			dprintf(D_SYSCALLS,"StreamHandler: %s: %d bytes read from %s\n",streamname.Value(),result,filename.Value());
			actual = daemonCore->Write_Pipe(handler_pipe,buffer,result);
			if(actual>=0) {
				dprintf(D_SYSCALLS,"StreamHandler: %s: %d bytes consumed by job\n",streamname.Value(),actual);
				offset+=actual;
			} else {
				dprintf(D_SYSCALLS,"StreamHandler: %s: nothing consumed by job\n",streamname.Value());
			}
		} else if(result==0) {
			dprintf(D_SYSCALLS,"StreamHandler: %s: end of file\n",streamname.Value());
			done=true;
			daemonCore->Cancel_Pipe(handler_pipe);
			daemonCore->Close_Pipe(handler_pipe);
			REMOTE_CONDOR_close(remote_fd);
			handlers.remove( this );
		} else if(result<0) {
			EXCEPT("StreamHandler: %s: unable to read from %s: %s",streamname.Value(),filename.Value(),strerror(errno));
		}
	}

	return KEEP_STREAM;
}
示例#5
0
int StreamHandler::Handler( int  /* fd */)
{
	int result;
	int actual;

	if(is_output) {
		// Output from the job to the shadow
		dprintf(D_SYSCALLS,"StreamHandler: %s: stream ready\n",streamname.Value());

		// As STREAM_BUFFER_SIZE should be <= PIPE_BUF, following should
		// never block
		result = daemonCore->Read_Pipe(handler_pipe,buffer,STREAM_BUFFER_SIZE);

		if(result>0) {
			dprintf(D_SYSCALLS,"StreamHandler: %s: %d bytes available\n",streamname.Value(),result);
			errno = 0;
			pending = result;
			REMOTE_CONDOR_lseek(remote_fd,offset,SEEK_SET);
			if (errno == ETIMEDOUT) {
				Disconnect();
				return KEEP_STREAM;
			}
	
			// This means something's really wrong with the file -- FS full
			// i/o error, so punt.

			if (errno != 0) {
				EXCEPT("StreamHandler: %s: couldn't lseek on %s to %d: %s",streamname.Value(),filename.Value(),(int)offset, strerror(errno));
			}

			errno = 0;
			actual = REMOTE_CONDOR_write(remote_fd,buffer,result);
			if (errno == ETIMEDOUT) {
				Disconnect();
				return KEEP_STREAM;
			}

			if(actual!=result) {
				EXCEPT("StreamHandler: %s: couldn't write to %s: %s (%d!=%d)",streamname.Value(),filename.Value(),strerror(errno),actual,result);
			}
			dprintf(D_SYSCALLS,"StreamHandler: %s: %d bytes written to %s\n",streamname.Value(),result,filename.Value());
			offset+=actual;
		} else if(result==0) {
			dprintf(D_SYSCALLS,"StreamHandler: %s: end of stream\n",streamname.Value());
			daemonCore->Cancel_Pipe(handler_pipe);
			daemonCore->Close_Pipe(handler_pipe);
			done=true;
			
			result = REMOTE_CONDOR_fsync(remote_fd);	

			if (result != 0) {
				// This is bad. All of our writes have succeeded, but
				// the final fsync has not.  We don't have a good way
				// to recover, as we haven't saved the data.
				// just punt

				EXCEPT("StreamHandler:: %s: couldn't fsync %s: %s", streamname.Value(), filename.Value(), strerror(errno));
			}

				// If close fails, that's OK, we know the bytes are on disk
			REMOTE_CONDOR_close(remote_fd);

		} else if(result<0) {
			dprintf(D_SYSCALLS,"StreamHandler: %s: unable to read: %s\n",streamname.Value(),strerror(errno));
			// Why don't we EXCEPT here?
		}
	} else {
		dprintf(D_SYSCALLS,"StreamHandler: %s: stream ready\n",streamname.Value());

		errno = 0;
		REMOTE_CONDOR_lseek(remote_fd,offset,SEEK_SET);
		if (errno == ETIMEDOUT) {
			Disconnect();
			return KEEP_STREAM;
		}

		errno = 0;
		result = REMOTE_CONDOR_read(remote_fd,buffer,STREAM_BUFFER_SIZE);
		if (errno == ETIMEDOUT) {
			Disconnect();
			return KEEP_STREAM;
		}

		if(result>0) {
			dprintf(D_SYSCALLS,"StreamHandler: %s: %d bytes read from %s\n",streamname.Value(),result,filename.Value());
			actual = daemonCore->Write_Pipe(handler_pipe,buffer,result);
			if(actual>=0) {
				dprintf(D_SYSCALLS,"StreamHandler: %s: %d bytes consumed by job\n",streamname.Value(),actual);
				offset+=actual;
			} else {
				dprintf(D_SYSCALLS,"StreamHandler: %s: nothing consumed by job\n",streamname.Value());
			}
		} else if(result==0) {
			dprintf(D_SYSCALLS,"StreamHandler: %s: end of file\n",streamname.Value());
			done=true;
			daemonCore->Cancel_Pipe(handler_pipe);
			daemonCore->Close_Pipe(handler_pipe);
			REMOTE_CONDOR_close(remote_fd);
		} else if(result<0) {
			EXCEPT("StreamHandler: %s: unable to read from %s: %s",streamname.Value(),filename.Value(),strerror(errno));
		}
	}

	return KEEP_STREAM;
}