#include #include #include #include #include "Zentific-types.h" /** * Loads all internal job types and calls their initialization scripts. Returns a list of * zInternalJobType variables. * * Returns NULL if there was an error. */ zList *z_InitInternalJobTypes() { /* create a list to write to */ zList *list = newZTaggedList("internal"); /* open the modules directory */ char *pathname = malloc(sizeof(char) * 2048); char *init_path = malloc(sizeof(char) * 2048); DIR *dir = NULL; struct dirent *entry; /* read all modules in the sources directory */ getcwd(init_path, 2047); snprintf(pathname, 2048, "%s/jobtypes/internal", init_path); free(init_path); debugLog(DBG_INFO, "Reading internal jobtypes directory \"%s\"", pathname); /* scan the directory for all modules */ dir = opendir(pathname); while ( (entry = readdir(dir)) != NULL ) { int last = strlen(entry->d_name) - 3; if ( last > 0 ) { /* we only care about .so files */ if ( entry->d_name[last] == '.' && entry->d_name[last+1] == 's' && entry->d_name[last+2] == 'o' ) { /* attempt to load the module */ void *lib; char fullpath[2048]; sprintf(fullpath, "%s/%s", pathname, entry->d_name); debugLog(DBG_INFO, "Loading internal jobtype module %s", fullpath); lib = dlopen(fullpath, RTLD_LAZY); /* if we succesfully loaded the library, then grab the functions */ if ( lib != NULL ) { debugLog(DBG_INFO, "Shared library opened"); /* create a wrapper to store the data for later */ zInternalJobType *type = malloc(sizeof(zInternalJobType)); /* error check the allocation */ if ( type == NULL ) { debugLog(DBG_ERROR, "Cannot allocate space for a new zInternalJobType"); return NULL; } /* generate all of the necessary references */ memset(type->name, '\0', 256); int name_length = strlen(entry->d_name) - 3; if ( name_length > 255 ) name_length = 255; strncpy(type->name, entry->d_name, name_length); debugLog(DBG_INFO, "Assigned name '%s'", type->name); /* and fill in some defaults as necessary */ type->config = NULL; type->library = lib; type->init = dlsym(lib, "zJob_Init"); type->execute = dlsym(lib, "zJob_Execute"); type->speed = dlsym(lib, "zJob_Speed"); type->uninit = dlsym(lib, "zJob_Uninit"); /* make sure we got everything */ if ( type->init == NULL || type->execute == NULL || type->speed == NULL || type->uninit == NULL ) { /* record the problem */ if ( type->init == NULL ) debugLog(DBG_ERROR, "Error loading module %s. No Fetch Function", fullpath); if ( type->execute == NULL ) debugLog(DBG_ERROR, "Error loading module %s. No Uninit Function", fullpath); if ( type->speed == NULL ) debugLog(DBG_ERROR, "Error loading module %s. No Update Function", fullpath); if ( type->uninit == NULL ) debugLog(DBG_ERROR, "Error loading module %s. No Init Function", fullpath); /* cleanup this source since we can't use it */ dlclose(type->library); free(type); } /* otherwise, it is good so add it to the list */ else { addZListEntry(list, type); /* and initialize it */ type->config = type->init(); if ( type->config == NULL ) { debugLog(DBG_ERROR, "Error initializing module %s", fullpath); } } } } } } /* done */ free(pathname); closedir(dir); /* return the list of sources */ return list; } /** * Loads all addon job types and calls their initialization scripts. Returns a list of * zInternalJobType variables. * * Returns NULL if there was an error. */ zList *z_InitAddonJobTypes() { /* create a list to write to */ zList *list = newZTaggedList("addon"); /* open the modules directory */ char *pathname = malloc(sizeof(char) * 2048); char *init_path = malloc(sizeof(char) * 2048); DIR *dir = NULL; struct dirent *entry; /* read all modules in the sources directory */ getcwd(init_path, 2047); snprintf(pathname, 2048, "%s/jobtypes/addon", init_path); free(init_path); debugLog(DBG_INFO, "Reading addon jobtypes directory \"%s\"", pathname); /* scan the directory for all modules */ dir = opendir(pathname); while ( (entry = readdir(dir)) != NULL ) { int last = strlen(entry->d_name) - 3; if ( last > 0 ) { /* we only care about .so files */ if ( entry->d_name[last] == '.' && entry->d_name[last+1] == 's' && entry->d_name[last+2] == 'o' ) { /* attempt to load the module */ void *lib = NULL; char fullpath[2048]; sprintf(fullpath, "%s/%s", pathname, entry->d_name); debugLog(DBG_INFO, "Loading addon jobtype module %s", fullpath); lib = dlopen(fullpath, RTLD_LAZY); /* if we succesfully loaded the library, then grab the functions */ if ( lib != NULL ) { debugLog(DBG_INFO, "Shared library opened"); /* create a wrapper to store the data for later */ zAddonJobType *type = malloc(sizeof(zAddonJobType)); /* error check the allocation */ if ( type == NULL ) { debugLog(DBG_ERROR, "Cannot allocate space for a new zAddonJobType"); return NULL; } /* generate all of the necessary references */ memset(type->name, '\0', 256); int name_length = strlen(entry->d_name) - 3; if ( name_length > 255 ) name_length = 255; strncpy(type->name, entry->d_name, name_length); debugLog(DBG_INFO, "Assigning name '%s'", type->name); /* and fill in defaults as necessary */ type->config = NULL; type->library = lib; type->init = dlsym(lib, "zJob_Init"); type->execute = dlsym(lib, "zJob_Execute"); type->speed = dlsym(lib, "zJob_Speed"); type->uninit = dlsym(lib, "zJob_Uninit"); /* make sure we got everything */ if ( type->init == NULL || type->execute == NULL || type->speed == NULL || type->uninit == NULL ) { /* record the problem */ if ( type->init == NULL ) debugLog(DBG_ERROR, "Error loading module %s. No Fetch Function", fullpath); if ( type->execute == NULL ) debugLog(DBG_ERROR, "Error loading module %s. No Uninit Function", fullpath); if ( type->speed == NULL ) debugLog(DBG_ERROR, "Error loading module %s. No Update Function", fullpath); if ( type->uninit == NULL ) debugLog(DBG_ERROR, "Error loading module %s. No Init Function", fullpath); /* cleanup this source since we can't use it */ dlclose(type->library); free(type); } /* otherwise, it is good so add it to the list */ else { debugLog(DBG_INFO, "Adding job type '%s' to list", type->name); addZListEntry(list, type); /* and initialize it */ type->config = type->init(); if ( type->config == NULL ) { debugLog(DBG_ERROR, "Error initializing module %s", fullpath); } } } } } } /* done */ free(pathname); closedir(dir); debugLog(DBG_INFO, "Returning list with %d entries", list->count); /* return the list of sources */ return list; } /** * Unloads all sources via their uninit functions. Works on both internal and */ int z_UninitJobTypes(zList *jobtypes) { zListNode *current = jobtypes->head; zListNode *buffer = NULL; /* iterate over all entries in the list */ while ( current != NULL ) { /* extract the job source from the list node */ if ( strcmp(jobtypes->tag, "internal") ) { zInternalJobType *jobtype = (zInternalJobType *)current->data; /* let the library cleanup after itself */ jobtype->uninit(jobtype->config); /* unload the dynamic library */ dlclose(jobtype->library); } else { zAddonJobType *jobtype = (zAddonJobType *)current->data; /* let the library cleanup after itself */ jobtype->uninit(jobtype->config); /* unload the dynamic library */ dlclose(jobtype->library); } /* remove the entry from the list, freeing the data */ buffer = current; current = current->next; delZListEntry(jobtypes, buffer, 1); } /* success */ return 0; } /** * Executes a job */ int z_ExecuteJob(zJob* job, zList* addonList, zList* internalList, zList* runList, zList* threadList) { /* figure out which list to look at */ debugLog(DBG_INFO, "Deciding which jobtype module to execute with"); /* shell is a special case for an addon */ if ( strcmp(job->jobtype_class, "shell") == 0 ) { debugLog(DBG_INFO, "Executing shell job type (special case for addon)"); /* find the "shell" type in the list of addon jobs */ zListNode *current = addonList->head; debugLog(DBG_INFO, "Add-On List has %d entries", addonList->count); while ( current != NULL ) { /* extract contents */ zAddonJobType *type = current->data; /* compare names. if we find the shell type, use it */ debugLog(DBG_INFO, "Searching for shell. Looking at %s.", "shell", type->name); if ( strcmp(type->name, "shell") == 0 ) { char *(*varParse)(char*,zDomU*,zDom0*,char*,char*) = NULL; if(type->library) varParse =dlsym(type->library, "z_Parse"); zDomU *vm = (zDomU*)malloc(sizeof(zDomU)*1); zDom0 *node = (zDom0*)malloc(sizeof(zDom0)*1); vm->uuid = strdup(job->domU); node->uuid = strdup(job->dom0); node->hostname = strdup(job->host); char *parsedstring =varParse(job->jobtype_string, vm, node, job->host, job->extra); free(job->jobtype_string); job->jobtype_string = strdup(parsedstring); free(parsedstring); free(node->uuid); free(vm->uuid); free(node->hostname); free(vm); free(node); return type->execute(type->config, job); } /* look forward */ current = current->next; } /* if we get here, we found it not! */ debugLog(DBG_ERROR, "Unable to find the shell addon job type! Please put it back >:o"); return -1; } /* generic add-on job type */ else if ( strcmp(job->jobtype_class, "addon") == 0 ) { debugLog(DBG_INFO, "Executing addon job type"); /* find the matching addon type */ zListNode *current = addonList->head; while( current != NULL ) { /* extract contents */ zAddonJobType *type = current->data; /* compare names */ if ( strcmp(type->name, job->jobtype_name) == 0 ) { return type->execute(type->config, job); } /* look forward */ current = current->next; } /* not found =*( */ debugLog(DBG_ERROR, "Unable to find the addon jobtype named %s", job->jobtype_name); return -1; } /* generic internal job type */ else if ( strcmp(job->jobtype_class, "internal") == 0 ) { debugLog(DBG_INFO, "Executing internal job type"); /* find the matching internal job type */ zListNode *current = internalList->head; while( current != NULL ) { /* extract contents */ zInternalJobType *type = current->data; /* compare names */ debugLog(DBG_INFO, "INTERNAL JOB SEARCH: Comparing '%s' against '%s'", type->name, job->jobtype_name); if ( strcmp(type->name, job->jobtype_name) == 0 ) { debugLog(DBG_INFO, "INTERNAL JOB SEARCH: found"); return type->execute(type->config, runList, threadList, job); } /* look forward */ current = current->next; } /* not found =*( */ debugLog(DBG_ERROR, "Unable to find the internal jobtype named %s", job->jobtype_name); return -1; } /* WTF? */ else { debugLog(DBG_ERROR, "Unknown job type class: %s", job->jobtype_class); return -1; } /* success */ return 0; } /** * Fetch the speed of the given job. Speed is calculated internally by the job type. */ int z_JobSpeed(zJob *job, zList *addonList, zList *internalList) { /* figure out which list to look at */ debugLog(DBG_INFO, "Deciding which jobtype module to calculate the speed of"); /* shell is a special case for an addon */ if ( strcmp(job->jobtype_class, "shell") == 0 ) { debugLog(DBG_INFO, "Checking speed of shell job type"); /* find the matching addon type */ zListNode *current = addonList->head; while( current != NULL ) { /* extract contents */ zAddonJobType *type = current->data; /* compare names */ if ( strcmp(type->name, "shell") == 0 ) { return type->speed(type->config, job); } /* look forward */ current = current->next; } /* not found =*( */ debugLog(DBG_ERROR, "Unable to find the addon jobtype named shell"); return -1; } /* normal add-on */ else if ( strcmp(job->jobtype_class, "addon") == 0 ) { debugLog(DBG_INFO, "Checking speed of addon job type"); /* find the matching addon type */ zListNode *current = addonList->head; while( current != NULL ) { /* extract contents */ zAddonJobType *type = current->data; /* compare names */ if ( strcmp(type->name, job->jobtype_name) == 0 ) { return type->speed(type->config, job); } /* look forward */ current = current->next; } /* not found =*( */ debugLog(DBG_ERROR, "Unable to find the addon jobtype named %s", job->jobtype_name); return -1; } /* generic internal job type */ else if ( strcmp(job->jobtype_class, "internal") == 0 ) { debugLog(DBG_INFO, "Checking speed of addon job type"); /* find the matching addon type */ zListNode *current = internalList->head; while( current != NULL ) { /* extract contents */ zInternalJobType *type = current->data; /* compare names */ if ( strcmp(type->name, job->jobtype_name) == 0 ) { return type->speed(type->config, job); } /* look forward */ current = current->next; } /* not found =*( */ debugLog(DBG_ERROR, "Unable to find the internal jobtype named %s", job->jobtype_name); return -1; } /* WTF? */ else { debugLog(DBG_ERROR, "Unknown job type class: %s", job->jobtype_class); return -1; } }