Ejemplo n.º 1
0
static void set_usageAd (ClassAd* jobAd, ClassAd ** ppusageAd) 
{
	std::string resslist;
	if ( ! jobAd->LookupString("ProvisionedResources", resslist))
		resslist = "Cpus, Disk, Memory";

	StringList reslist(resslist.c_str());
	if (reslist.number() > 0) {
		ClassAd * puAd = new ClassAd();
		puAd->Clear(); // get rid of default "CurrentTime = time()" value.

		reslist.rewind();
		while (const char * resname = reslist.next()) {
			std::string attr;
			std::string res = resname;
			title_case(res); // capitalize it to make it print pretty.
			const int copy_ok = classad::Value::ERROR_VALUE | classad::Value::BOOLEAN_VALUE | classad::Value::INTEGER_VALUE | classad::Value::REAL_VALUE;
			classad::Value value;
			attr = res + "Provisioned";	 // provisioned value
			if (jobAd->EvalAttr(attr.c_str(), NULL, value) && (value.GetType() & copy_ok) != 0) {
				classad::ExprTree * plit = classad::Literal::MakeLiteral(value);
				if (plit) {
					puAd->Insert(resname, plit); // usage ad has attribs like they appear in Machine ad
				}
			}
			// /*for debugging*/ else { puAd->Assign(resname, 42); }
			attr = "Request"; attr += res;   	// requested value
			if (jobAd->EvalAttr(attr.c_str(), NULL, value)&& (value.GetType() & copy_ok) != 0) {
				classad::ExprTree * plit = classad::Literal::MakeLiteral(value);
				if (plit) {
					puAd->Insert(attr.c_str(), plit);
				}
			}
			// /*for debugging*/ else { puAd->Assign(attr.Value(), 99); }
			attr = res + "Usage"; // usage value
			if (jobAd->EvalAttr(attr.c_str(), NULL, value) && (value.GetType() & copy_ok) != 0) {
				classad::ExprTree * plit = classad::Literal::MakeLiteral(value);
				if (plit) {
					puAd->Insert(attr.c_str(), plit);
				}
			}
		}
		*ppusageAd = puAd;
	}
}
Ejemplo n.º 2
0
// kind defaults to US_NORMAL.
void
BaseShadow::logTerminateEvent( int exitReason, update_style_t kind )
{
	struct rusage run_remote_rusage;
	JobTerminatedEvent event;
	MyString corefile;

	memset( &run_remote_rusage, 0, sizeof(struct rusage) );

	switch( exitReason ) {
	case JOB_EXITED:
	case JOB_COREDUMPED:
		break;
	default:
		dprintf( D_ALWAYS, 
				 "UserLog logTerminateEvent with unknown reason (%d), aborting\n",
				 exitReason ); 
		return;
	}

	if (kind == US_TERMINATE_PENDING) {

		int exited_by_signal = FALSE;
		int exit_signal = 0;
		int exit_code = 0;

		getJobAdExitedBySignal(jobAd, exited_by_signal);
		if (exited_by_signal == TRUE) {
			getJobAdExitSignal(jobAd, exit_signal);
			event.normal = false;
			event.signalNumber = exit_signal;
		} else {
			getJobAdExitCode(jobAd, exit_code);
			event.normal = true;
			event.returnValue = exit_code;
		}

		/* grab usage information out of job ad */
		double real_value;
		if( jobAd->LookupFloat(ATTR_JOB_REMOTE_SYS_CPU, real_value) ) {
			run_remote_rusage.ru_stime.tv_sec = (time_t) real_value;
		}

		if( jobAd->LookupFloat(ATTR_JOB_REMOTE_USER_CPU, real_value) ) {
			run_remote_rusage.ru_utime.tv_sec = (time_t) real_value;
		}

		event.run_remote_rusage = run_remote_rusage;
		event.total_remote_rusage = run_remote_rusage;
	
		/*
		  we want to log the events from the perspective of the user
		  job, so if the shadow *sent* the bytes, then that means the
		  user job *received* the bytes
		*/
		jobAd->LookupFloat(ATTR_BYTES_SENT, event.recvd_bytes);
		jobAd->LookupFloat(ATTR_BYTES_RECVD, event.sent_bytes);

		event.total_recvd_bytes = event.recvd_bytes;
		event.total_sent_bytes = event.sent_bytes;
	
		if( exited_by_signal == TRUE ) {
			jobAd->LookupString(ATTR_JOB_CORE_FILENAME, corefile);
			event.setCoreFile( corefile.Value() );
		}

		if (!uLog.writeEvent (&event,jobAd)) {
			dprintf (D_ALWAYS,"Unable to log "
				 	"ULOG_JOB_TERMINATED event\n");
			EXCEPT("UserLog Unable to log ULOG_JOB_TERMINATED event");
		}

		return;
	}

	// the default kind == US_NORMAL path

	run_remote_rusage = getRUsage();
	
	if( exitedBySignal() ) {
		event.normal = false;
		event.signalNumber = exitSignal();
	} else {
		event.normal = true;
		event.returnValue = exitCode();
	}

		// TODO: fill in local/total rusage
		// event.run_local_rusage = r;
	event.run_remote_rusage = run_remote_rusage;
		// event.total_local_rusage = r;
	event.total_remote_rusage = run_remote_rusage;
	
		/*
		  we want to log the events from the perspective of the user
		  job, so if the shadow *sent* the bytes, then that means the
		  user job *received* the bytes
		*/
	event.recvd_bytes = bytesSent();
	event.sent_bytes = bytesReceived();

	event.total_recvd_bytes = prev_run_bytes_recvd + bytesSent();
	event.total_sent_bytes = prev_run_bytes_sent + bytesReceived();
	
	if( exitReason == JOB_COREDUMPED ) {
		event.setCoreFile( core_file_name );
	}

#if 1
	set_usageAd(jobAd, &event.pusageAd);
#else
	std::string resslist;
	if ( ! jobAd->LookupString("PartitionableResources", resslist))
		resslist = "Cpus, Disk, Memory";

	StringList reslist(resslist.c_str());
	if (reslist.number() > 0) {
		int64_t int64_value = 0;
		ClassAd * puAd = new ClassAd();

		reslist.rewind();
		char * resname = NULL;
		while ((resname = reslist.next()) != NULL) {
			MyString attr;
			int64_value = -1;
			attr.formatstr("%s", resname); // provisioned value
			if (jobAd->LookupInteger(attr.Value(), int64_value)) {
				puAd->Assign(resname, int64_value);
			} 
			// /*for debugging*/ else { puAd->Assign(resname, 42); }
			int64_value = -2;
			attr.formatstr("Request%s", resname);	// requested value
			if (jobAd->LookupInteger(attr.Value(), int64_value)) {
				puAd->Assign(attr.Value(), int64_value);
			}
			// /*for debugging*/ else { puAd->Assign(attr.Value(), 99); }
			int64_value = -3;
			attr.formatstr("%sUsage", resname); // usage value
			if (jobAd->LookupInteger(attr.Value(), int64_value)) {
				puAd->Assign(attr.Value(), int64_value);
			}
		}
		event.pusageAd = puAd;
	}
#endif
	
	if (!uLog.writeEvent (&event,jobAd)) {
		dprintf (D_ALWAYS,"Unable to log "
				 "ULOG_JOB_TERMINATED event\n");
		EXCEPT("UserLog Unable to log ULOG_JOB_TERMINATED event");
	}
}
Ejemplo n.º 3
0
void MachAttributes::init_machine_resources() {
    // defines the space of local machine resources, and their quantity
    m_machres_map.clear();

    // this may be filled from resource inventory scripts
    m_machres_attr.Clear();

    // these are reserved for standard/fixed resources
    std::set<string> fixedRes;
    fixedRes.insert("cpu");
    fixedRes.insert("cpus");
    fixedRes.insert("disk");
    fixedRes.insert("swap");
    fixedRes.insert("mem");
    fixedRes.insert("memory");
    fixedRes.insert("ram");

    // get the list of defined local resource names:
    char* ptmp = param("MACHINE_RESOURCE_NAMES");
    string resnames;
    if (NULL != ptmp) {
        // if admin defined MACHINE_RESOURCE_NAMES, then use this list
        // as the source of expected custom machine resources
        resnames = ptmp;
        free(ptmp);
    } else {
        // otherwise, build the list of custom machine resources from
        // all occurrences of MACHINE_RESOURCE_<resname>
        std::set<string> resset;
        Regex re;
        int err = 0;
        const char* pszMsg = 0;
        const string prefix = "MACHINE_RESOURCE_";
        const string invprefix = "INVENTORY_";
        const string restr = prefix + "(.+)";
        ASSERT(re.compile(restr.c_str(), &pszMsg, &err, PCRE_CASELESS));
	std::vector<std::string> resdef;
        const int n = param_names_matching(re, resdef);
        for (int j = 0;  j < n;  ++j) {
            string rname = resdef[j].substr(prefix.length());
            string testinv = rname.substr(0, invprefix.length());
            if (0 == strcasecmp(testinv.c_str(), invprefix.c_str())) {
                // if something was defined via MACHINE_RESOURCE_INVENTORY_<rname>, strip "INVENTORY_"
                rname = rname.substr(invprefix.length());
            }
            std::transform(rname.begin(), rname.end(), rname.begin(), ::tolower);
            resset.insert(rname);
        }
        for (std::set<string>::iterator j(resset.begin());  j != resset.end();  ++j) {
            resnames += " ";
            resnames += *j;
        }
    }

    // scan the list of local resources, to obtain their quantity and associated attributes (if any)
    StringList reslist(resnames.c_str());
    reslist.rewind();
    while (const char* rnp = reslist.next()) {
        string rname(rnp);
        std::transform(rname.begin(), rname.end(), rname.begin(), ::tolower);
        if (fixedRes.count(rname) > 0) {
            EXCEPT("pre-defined resource name '%s' is reserved", rname.c_str());
        }

        // If MACHINE_RESOURCE_<rname> is present, use that and move on:
        string pname;
        formatstr(pname, "MACHINE_RESOURCE_%s", rname.c_str());
        char* machresp = param(pname.c_str());
        if (machresp) {
            int v = param_integer(pname.c_str(), 0, 0, INT_MAX);
            m_machres_map[rname] = v;
            free(machresp);
            continue;
        }

        // current definition of REMIND macro is not working with gcc
        #pragma message("MACHINE_RESOURCE_INVENTORY_<rname> is deprecated, and will be removed when a solution using '|' in config files is fleshed out")
        // if we didn't find MACHINE_RESOURCE_<rname>, then try MACHINE_RESOURCE_INVENTORY_<rname>
        formatstr(pname, "MACHINE_RESOURCE_INVENTORY_%s", rname.c_str());
        char* invscriptp = param(pname.c_str());
        if (NULL == invscriptp) {
            EXCEPT("Missing configuration for local machine resource %s", rname.c_str());
        }

        // if there is an inventory script, then attempt to execute it and use its output to
        // identify the local resource quantity, and any associated attributes:
        string invscript = invscriptp;
        free(invscriptp);

        ArgList invcmd;
        StringList invcmdal(invscript.c_str());
        invcmdal.rewind();
        while (char* invarg = invcmdal.next()) {
            invcmd.AppendArg(invarg);
        }
        FILE* fp = my_popen(invcmd, "r", FALSE);
        if (NULL == fp) {
            EXCEPT("Failed to execute local resource inventory script \"%s\"\n", invscript.c_str());
        }

        ClassAd invad;
        char invline[1000];
        while (fgets(invline, sizeof(invline), fp)) {
            if (!invad.Insert(invline)) {
                dprintf(D_ALWAYS, "Failed to insert \"%s\" into machine resource attributes: ignoring\n", invline);
            }
        }
        my_pclose(fp);

        // require the detected machine resource to be present as an attribute
        string ccname(rname.c_str());
        *(ccname.begin()) = toupper(*(ccname.begin()));
        string detname;
        formatstr(detname, "%s%s", ATTR_DETECTED_PREFIX, ccname.c_str());
        int v = 0;
        if (!invad.LookupInteger(detname.c_str(), v)) {
            EXCEPT("Missing required attribute \"%s = <n>\" from output of %s\n", detname.c_str(),  invscript.c_str());
        }

        // success
        m_machres_map[rname] = v;
        invad.Delete(rname.c_str());
        m_machres_attr.Update(invad);
    }

    for (slotres_map_t::iterator j(m_machres_map.begin());  j != m_machres_map.end();  ++j) {
        dprintf(D_ALWAYS, "Local machine resource %s = %d\n", j->first.c_str(), int(j->second));
    }
}