void CondorFileTable::lookup_url( char *logical_name, char **url ) { static int never_ask_shadow = FALSE; // Special case: Requests to look up default standard files // should be mapped to constant file descriptors. if(!strcmp(logical_name,"default stdin")) { *url = strdup("fd:0"); return; } else if(!strcmp(logical_name,"default stdout")) { *url = strdup("fd:1"); return; } else if(!strcmp(logical_name,"default stderr")) { *url = strdup("fd:2"); return; } // If in local mode, just use local:logical_name. // Otherwise, ask shadow. If that fails, try buffer:remote:logical_name. if( LocalSysCalls() || (never_ask_shadow == TRUE)) { *url = (char *)malloc(strlen(logical_name)+7); sprintf(*url,"local:%s",logical_name); } else { if (never_ask_shadow == FALSE ) { int result; // If <0 is returned, then an error happened. // If 0 is returned then the shadow wanted the FileTable to work // just like normal in comming back to it for each file the // FileTable wants to know what to do with. // if 1 is returned, then the shadow automatically give up // control of how the files are opened, permanently I assume, // since the static variable in here is preserved across // checkpoints in the memory image. result = REMOTE_CONDOR_get_file_info_new( logical_name, *url ); if (result == 1) { never_ask_shadow = TRUE; } else if( result < 0 ) { free( *url ); *url = (char *)malloc(strlen(logical_name)+8); sprintf(*url,"buffer:remote:%s",logical_name); } if(!got_buffer_info) { int temp; REMOTE_CONDOR_get_buffer_info( &buffer_size, &buffer_block_size, &temp ); got_buffer_info = 1; } } } }
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); }
/* Open a standard file (0, 1, or 2), given its fd number. */ void open_std_file( int fd ) { char *logical_name = NULL; char *physical_name = NULL; char *file_name; int flags; int success; int real_fd; /* First, try the new set of remote lookups */ success = REMOTE_CONDOR_get_std_file_info( fd, logical_name ); if(success>=0) { success = REMOTE_CONDOR_get_file_info_new(logical_name, physical_name); } /* If either of those fail, fall back to the old way */ if(success<0) { success = REMOTE_CONDOR_std_file_info( fd, logical_name, &real_fd ); if(success<0) { EXCEPT("Couldn't get standard file info!"); } physical_name = (char *)malloc(strlen(logical_name)+7); sprintf(physical_name,"local:%s",logical_name); } if(fd==0) { flags = O_RDONLY; } else { flags = O_CREAT|O_WRONLY|O_TRUNC; } /* The starter doesn't have the whole elaborate url mechanism. */ /* So, just strip off the pathname from the end */ file_name = strrchr(physical_name,':'); if(file_name) { file_name++; } else { file_name = physical_name; } /* Check to see if appending is forced */ if(strstr(physical_name,"append:")) { flags = flags | O_APPEND; flags = flags & ~O_TRUNC; } /* Now, really open the file. */ real_fd = safe_open_wrapper_follow(file_name,flags,0); if(real_fd<0) { // Some things, like /dev/null, can't be truncated, so // try again w/o O_TRUNC. Jim, Todd and Derek 5/26/99 flags = flags & ~O_TRUNC; real_fd = safe_open_wrapper_follow(file_name,flags,0); } if(real_fd<0) { MyString err; err.formatstr("Can't open \"%s\": %s", file_name,strerror(errno)); dprintf(D_ALWAYS,"%s\n",err.Value()); REMOTE_CONDOR_report_error(const_cast<char *>(err.Value())); exit( 4 ); } else { if( real_fd != fd ) { dup2( real_fd, fd ); } } free( logical_name ); free( physical_name ); }