Esempio n. 1
0
/* Fill in a PROC structure given a job ClassAd.  This function replaces
   GetProc from qmgr_lib_support.C, so we just get the job classad once
   from the schedd and fill in the PROC structure directly. */
int
MakeProc(ClassAd *ad, PROC *p)
{
	char buf[ATTRLIST_MAX_EXPRESSION];
	float	utime,stime;
	ExprTree *e;
	
	p->version_num = 3;
	ad->LookupInteger(ATTR_CLUSTER_ID, p->id.cluster);
	ad->LookupInteger(ATTR_PROC_ID, p->id.proc);
	ad->LookupInteger(ATTR_JOB_UNIVERSE, p->universe);
	ad->LookupInteger(ATTR_WANT_CHECKPOINT, p->checkpoint);
	ad->LookupInteger(ATTR_WANT_REMOTE_SYSCALLS, p->remote_syscalls);
	ad->LookupString(ATTR_OWNER, buf);
	p->owner = strdup(buf);
	ad->LookupInteger(ATTR_Q_DATE, p->q_date);
	ad->LookupInteger(ATTR_COMPLETION_DATE, p->completion_date);
	ad->LookupInteger(ATTR_JOB_STATUS, p->status);
	ad->LookupInteger(ATTR_JOB_PRIO, p->prio);
	ad->LookupInteger(ATTR_JOB_NOTIFICATION, p->notification);
	ad->LookupInteger(ATTR_IMAGE_SIZE, p->image_size);

	// There are two different syntaxes for the environment.  Since
	// the wire protocol only expects one, we pack either one into the
	// same proc variable "env_v1or2" and make sure they are
	// distinguishable.  For backward compatibility, the schedd
	// will have already ensured that we use V1 syntax if the
	// remote side only understands that.

	Env envobj;
	MyString env_v1or2;
	MyString env_error_msg;
	if(!envobj.getDelimitedStringV1or2Raw(ad,&env_v1or2,&env_error_msg)) {
		EXCEPT("Failed to parse environment string: %s\n",
			   env_error_msg.Value());
	}
	p->env_v1or2 = strdup(env_v1or2.Value());

	p->n_cmds = 1;
	p->cmd = (char **) malloc(p->n_cmds * sizeof(char *));
	p->args_v1or2 = (char **) malloc(p->n_cmds * sizeof(char *));
	p->in = (char **) malloc(p->n_cmds * sizeof(char *));
	p->out = (char **) malloc(p->n_cmds * sizeof(char *));
	p->err = (char **) malloc(p->n_cmds * sizeof(char *));
	p->exit_status = (int *) malloc(p->n_cmds * sizeof(int));

	// There are two different syntaxes for arguments.  Since
	// the wire protocol only expects one, we pack either one into the
	// same proc variable "env_v1or2" and make sure they are
	// distinguishable.  For backward compatibility, the schedd
	// will have already ensured that we use V1 syntax if the
	// remote side only understands that.

	ArgList args;
	MyString args_v1or2;
	MyString error_msg;
	if(!args.GetArgsStringV1or2Raw(ad,&args_v1or2,&error_msg)) {
		EXCEPT("Failed to get V1or2 arguments string: %s\n",error_msg.Value());
	}
	p->args_v1or2[0] = strdup(args_v1or2.Value());

	ad->LookupString(ATTR_JOB_CMD, buf);
	p->cmd[0] = strdup(buf);
	ad->LookupString(ATTR_JOB_INPUT, buf);
	p->in[0] = strdup(buf);
	ad->LookupString(ATTR_JOB_OUTPUT, buf);
	p->out[0] = strdup(buf);
	ad->LookupString(ATTR_JOB_ERROR, buf);
	p->err[0] = strdup(buf);
	ad->LookupInteger(ATTR_JOB_EXIT_STATUS, p->exit_status[0]);

	ad->LookupInteger(ATTR_MIN_HOSTS, p->min_needed);
	ad->LookupInteger(ATTR_MAX_HOSTS, p->max_needed);

	ad->LookupString(ATTR_JOB_ROOT_DIR, buf);
	p->rootdir = strdup(buf);
	ad->LookupString(ATTR_JOB_IWD, buf);
	p->iwd = strdup(buf);

	e = ad->LookupExpr(ATTR_REQUIREMENTS);
	if (e) {
		p->requirements = strdup(ExprTreeToString(e));
	} else {
	   p->requirements = NULL;
	}
	e = ad->LookupExpr(ATTR_RANK);
	if (e) {
		p->preferences = strdup(ExprTreeToString(e));
	} else {
		p->preferences = NULL;
	}

	ad->LookupFloat(ATTR_JOB_LOCAL_USER_CPU, utime);
	ad->LookupFloat(ATTR_JOB_LOCAL_SYS_CPU, stime);
	float_to_rusage(utime, stime, &(p->local_usage));

	p->remote_usage = (struct rusage *) malloc(p->n_cmds * 
		sizeof(struct rusage));

	memset(p->remote_usage, 0, sizeof( struct rusage ));

	ad->LookupFloat(ATTR_JOB_REMOTE_USER_CPU, utime);
	ad->LookupFloat(ATTR_JOB_REMOTE_SYS_CPU, stime);
	float_to_rusage(utime, stime, &(p->remote_usage[0]));
	
	return 0;
}
Esempio n. 2
0
bool 
VMType::parseCommonParamFromClassAd(bool /* is_root false*/)
{
	// Read common parameters for vm
	
	m_result_msg = "";
	// Read the amount of memory for VM
	if( m_classAd.LookupInteger( ATTR_JOB_VM_MEMORY, m_vm_mem) != 1 ) {
		vmprintf(D_ALWAYS, "%s cannot be found in job classAd\n", 
				ATTR_JOB_VM_MEMORY);
		m_result_msg = VMGAHP_ERR_JOBCLASSAD_NO_VM_MEMORY_PARAM;
		return false;
	}else {
		// Requested memory should not be larger than the maximum allowed memory
		if( ( m_vm_mem <= 0 ) || 
				(m_vm_mem > vmgahp->m_gahp_config->m_vm_max_memory) ) {
			m_result_msg = VMGAHP_ERR_JOBCLASSAD_TOO_MUCH_MEMORY_REQUEST;
			return false;
		}
	}
	vmprintf(D_FULLDEBUG, "Memory: %d\n", m_vm_mem);

	vmprintf(D_FULLDEBUG, "Looking up number of vcpus.\n");
	// Read the number of vcpus
	if( m_classAd.LookupInteger( ATTR_JOB_VM_VCPUS, m_vcpus) != 1) {
	  vmprintf(D_FULLDEBUG, "No VCPUS defined or VCPUS definition is bad.\n");
	}
	if(m_vcpus < 1) m_vcpus = 1;
	vmprintf(D_FULLDEBUG, "Setting up %d CPUS\n", m_vcpus);

	// Read parameter for networking
	m_vm_networking = false;
	m_classAd.LookupBool( ATTR_JOB_VM_NETWORKING, m_vm_networking);

	if( m_vm_networking && 
			(vmgahp->m_gahp_config->m_vm_networking == false ) ) {
		vmprintf(D_ALWAYS, "A job requests networking but " 
				"the gahp server doesn't support networking\n");
		m_result_msg = VMGAHP_ERR_JOBCLASSAD_MISMATCHED_NETWORKING;
		return false;
	}

	if( m_vm_networking ) {
		// Read parameter for networking types
		if( m_classAd.LookupString( ATTR_JOB_VM_NETWORKING_TYPE, 
					m_vm_networking_type) == 1 ) {
			// vm_networking_type is defined

			// change string to lowercase
			m_vm_networking_type.trim();
			m_vm_networking_type.lower_case();
			if( vmgahp->m_gahp_config->m_vm_networking_types.contains(m_vm_networking_type.Value()) == false ) {
				vmprintf(D_ALWAYS, "Networking type(%s) is not supported by "
						"this gahp server\n", m_vm_networking_type.Value());
				m_result_msg = VMGAHP_ERR_JOBCLASSAD_MISMATCHED_NETWORKING_TYPE;
				return false;
			}
		}else {
			// vm_networking_type is undefined
			if( vmgahp->m_gahp_config->m_vm_default_networking_type.IsEmpty() == false ) {
				m_vm_networking_type = vmgahp->m_gahp_config->m_vm_default_networking_type;
			}else {
				m_vm_networking_type = "nat";
			}
		}
		if(m_classAd.LookupString( ATTR_JOB_VM_MACADDR, m_vm_job_mac) != 1)
		  {
		    vmprintf(D_FULLDEBUG, "MAC address was not defined.\n");
		  }
	}

	// Read parameter for checkpoint
	m_vm_checkpoint = false;
	m_classAd.LookupBool(ATTR_JOB_VM_CHECKPOINT, m_vm_checkpoint);

	if( VMType::createVMName(&m_classAd, m_vm_name) == false ) {
		m_result_msg = VMGAHP_ERR_CRITICAL;
		return false;
	}

	// Insert vm_name to classAd for future use
	m_classAd.Assign("VMPARAM_VM_NAME", m_vm_name); 

	// Read the parameter of hardware VT
	m_vm_hardware_vt = false; 
	m_classAd.LookupBool(ATTR_JOB_VM_HARDWARE_VT, m_vm_hardware_vt);
	if( m_vm_hardware_vt && 
			(vmgahp->m_gahp_config->m_vm_hardware_vt == false ) ) {
		vmprintf(D_ALWAYS, "A job requests hardware virtualization but " 
				"the vmgahp server doesn't support hardware VT\n");
		m_result_msg = VMGAHP_ERR_JOBCLASSAD_MISMATCHED_HARDWARE_VT;
		return false;
	}

	// Read the parameter of vm_no_output_vm
	// This parameter is an experiment parameter
	// When this parameter is TRUE, Condor will not transfer 
	// all files for VM back to a job user.
	// This parameter would be used if a job user uses explict method 
	// to get output files from VM. 
	// For example, if a job user uses a ftp program 
	// to send output files inside VM to his/her dedicated machine for ouput, 
	// the job user doesn't want to get modified VM disk files back. 
	// So the job user can use this parameter
	m_vm_no_output_vm = false; 
	m_classAd.LookupBool(VMPARAM_NO_OUTPUT_VM, m_vm_no_output_vm);

	m_classad_arg = "";
	ArgList arglist;
	MyString error_msg;
	if(!arglist.GetArgsStringV1or2Raw(&m_classAd, &m_classad_arg, &error_msg)) {
		m_classad_arg = "";
	}

	if( m_classad_arg.IsEmpty() == false ) {

        // Create a file for arguments
		FILE *argfile_fp = safe_fopen_wrapper_follow(VM_UNIV_ARGUMENT_FILE, "w");
		if( !argfile_fp ) {
			vmprintf(D_ALWAYS, "failed to safe_fopen_wrapper the file "
					"for arguments: safe_fopen_wrapper_follow(%s) returns %s\n", 
					VM_UNIV_ARGUMENT_FILE, strerror(errno));
			m_result_msg = VMGAHP_ERR_CANNOT_CREATE_ARG_FILE;
			return false;
		}
		if( fprintf(argfile_fp, "%s", m_classad_arg.Value()) < 0) {
			fclose(argfile_fp);
			IGNORE_RETURN unlink(VM_UNIV_ARGUMENT_FILE);
			vmprintf(D_ALWAYS, "failed to fprintf in CreateConfigFile(%s:%s)\n",
					VM_UNIV_ARGUMENT_FILE, strerror(errno));
			m_result_msg = VMGAHP_ERR_CANNOT_CREATE_ARG_FILE;
			return false;
		}
		fclose(argfile_fp);

        //??
		m_arg_file.formatstr("%s%c%s", m_workingpath.Value(), 
				DIR_DELIM_CHAR, VM_UNIV_ARGUMENT_FILE);

    }
	return true;
}