Example 1: The following example shows how LoadLeveler's Data Access API can be used to obtain machine, job, and cluster information. The program consists of three steps:
#include <stdio.h> #include "llapi.h" main(int argc, char *argv[]) { LL_element *queryObject, *machine, *resource, *cluster; LL_element *job, *step, *node, *task, *credential, *resource_req; int rc, obj_count, err_code, value; double load_avg; enum StepState step_state; char **host_list, **class_list; char *name, *res_name, *step_id, *job_class, *node_req; char *task_exec, *ex_args, *startd_state; /* Step 1: Display information of selected machines in the LL cluster */ /* Initialize the query: Machine query */ queryObject = ll_query(MACHINES); if (!queryObject) { printf("Query MACHINES: ll_query() returns NULL.\n"); exit(1); } /* Set query parameters: query specific machines by name */ host_list = (char **)malloc(3*sizeof(char *)); host_list[0] = "c163n12.ppd.pok.ibm.com"; host_list[1] = "c163n11.ppd.pok.ibm.com"; host_list[2] = NULL; rc = ll_set_request(queryObject, QUERY_HOST, host_list, ALL_DATA); if (rc) { printf("Query MACHINES: ll_set_request() return code is non-zero.\n"); exit(1); } /* Get the machine objects from the LoadL_negotiator (central manager) daemon */ machine = ll_get_objs(queryObject, LL_CM, NULL, &obj_count, &err_code); if (machine == NULL) { printf("Query MACHINES: ll_get_objs() returns NULL. Error code = %d\n", err_code); } printf("Number of machines objects returned = %d\n", obj_count); /* Process the machine objects */ while(machine) { rc = ll_get_data(machine, LL_MachineName, &name); if (!rc) { printf("Machine name: %s ------------------\n", name); free(name); } rc = ll_get_data(machine, LL_MachineStartdState, &stard_state); if (rc) { printf("Query MACHINES: ll_get_data() return code is non-zero.\n"); exit(1); }
printf("Startd State: %s\n", startd_state); if (strcmp(startd_state, "Down") != 0) { rc = ll_get_data(machine, LL_MachineRealMemory, &value); if (!rc) printf("Total Real Memory: %d\n", value); rc = ll_get_data(machine, LL_MachineVirtualMemory, &value); if (!rc) printf("Free Swap Space: %d\n", value); rc = ll_get_data(machine, LL_MachineLoadAverage, &load_avg); if (!rc) printf("Load Average: %f\n", load_avg); } free(startd_state); /* Consumable Resources associated with this machine */ resource = NULL; ll_get_data(machine, LL_MachineGetFirstResource, &resource); while(resource) { rc = ll_get_data(resource, LL_ResourceName, &res_name); if (!rc) {printf("Resource Name = %s\n", res_name); free (res_name);} rc = ll_get_data(resource, LL_ResourceInitialValue, &value); if (!rc) printf(" Total: %d\n", value); rc = ll_get_data(resource, LL_ResourceAvailableValue, &value); if (!rc) printf(" Available: %d\n", value); resource = NULL; ll_get_data(machine, LL_MachineGetNextResource, &resource); } machine = ll_next_obj(queryObject); } /* Free objects obtained from Negotiator */ ll_free_objs(queryObject); /* Free query element */ ll_deallocate(queryObject); /* Step 2: Display information of selected jobs */ /* Initialize the query: Job query */ queryObject = ll_query(JOBS); if (!queryObject) { printf("Query JOBS: ll_query() returns NULL.\n"); exit(1); } /* Query all class "Parallel" and "No_Class" jobs submitted to c163n11, c163n12 */ class_list = (char **)malloc(3*sizeof(char *)); class_list[0] = "Parallel"; class_list[1] = "No_Class"; class_list[2] = NULL; rc = ll_set_request(queryObject, QUERY_HOST, host_list, ALL_DATA); if (rc) {printf("Query JOBS: ll_set_request() return code is non-zero.\n"); exit(1);} rc = ll_set_request(queryObject, QUERY_CLASS, class_list, ALL_DATA); if (rc) {printf("Query JOBS: ll_set_request() return code is non-zero.\n"); exit(1);} /* Get the requested job objects from the Central Manager */ job = ll_get_objs(queryObject, LL_CM, NULL, &obj_count, &err_code); if (job == NULL) { printf("Query JOBS: ll_get_objs() returns NULL. Error code = %d\n", err_code); } printf("Number of job objects returned = %d\n", obj_count); /* Process the job objects and display selected information of each job step.
* * Notes: * 1. Since LL_element is defined as "void" in llapi.h, when using * ll_get_data it is important that a valid "specification" * parameter be used for a given "element" argument. * 2. Checking of return code is not always made in the following * loop to minimize the length of the listing. */ while(job) { rc = ll_get_data(job, LL_JobName, &name); if (!rc) {printf("Job name: %s\n", name); free(name);} rc = ll_get_data(job, LL_JobCredential, &credential); if (!rc) { rc = ll_get_data(credential, LL_CredentialUserName, &name); if (!rc) {printf("Job owner: %s\n", name); free(name);} rc = ll_get_data(credential, LL_CredentialGroupName, &name); if (!rc) {printf("Unix Group: %s\n", name); free(name);} } step = NULL; ll_get_data(job, LL_JobGetFirstStep, &step); while(step) { rc = ll_get_data(step, LL_StepID, &step_id); if (!rc) {printf(" Step ID: %s\n", step_id); free(step_id);} rc = ll_get_data(step, LL_StepJobClass, &job_class); if (!rc) {printf(" Step Job Class: %s\n", job_class); free(job_class);} rc = ll_get_data(step, LL_StepState, &step_state); if (!rc) { if (step_state == STATE_RUNNING) { printf(" Step Status: Running\n"); printf(" Allocated Hosts:\n"); machine = NULL; ll_get_data(step, LL_StepGetFirstMachine, &machine); while(machine) { rc = ll_get_data(machine, LL_MachineName, &name); if (!rc) { printf(" %s\n", name); free(name); } machine = NULL; ll_get_data(step, LL_StepGetNextMachine, &machine); } }else { printf(" Step Status: Not Running\n"); } } node = NULL; ll_get_data(step, LL_StepGetFirstNode, &node); while(node) { rc = ll_get_data(node, LL_NodeRequirements, &node_req); if (!rc) {printf(" Node Requirements: %s\n", node_req); free(node_req);} task = NULL; ll_get_data(node, LL_NodeGetFirstTask, &task); while(task) {
rc = ll_get_data(task, LL_TaskExecutable, &task_exec); if (!rc) {printf(" Task Executable: %s\n", task_exec); free(task_exec);} rc = ll_get_data(task, LL_TaskExecutableArguments, &ex_args); if (!rc) {printf(" Task Executable Arguments: %s\n",ex_args); free(ex_args);} resource_req = NULL; ll_get_data(task, LL_TaskGetFirstResourceRequirement, &resource_req); while(resource_req) { rc = ll_get_data(resource_req, LL_ResourceRequirementName, &name); if (!rc) {printf(" Resource Req Name: %s\n", name); free(name);} rc = ll_get_data(resource_req, LL_ResourceRequirementValue, &value); if (!rc) {printf(" Resource Req Value: %d\n", value);} resource_req = NULL; ll_get_data(task, LL_TaskGetNextResourceRequirement, &resource_req); } task = NULL; ll_get_data(node, LL_NodeGetNextTask, &task); } node = NULL; ll_get_data(step, LL_StepGetNextNode, &node); } step = NULL; ll_get_data(job, LL_JobGetNextStep, &step); } job = ll_next_obj(queryObject); } ll_free_objs(queryObject); ll_deallocate(queryObject); /* Step 3: Display Floating Consumable Resources information of LL cluster. */ /* Initialize the query: Cluster query */ queryObject = ll_query(CLUSTERS); if (!queryObject) { printf("Query CLUSTERS: ll_query() returns NULL.\n"); exit(1); } ll_set_request(queryObject, QUERY_ALL, NULL, ALL_DATA); cluster = ll_get_objs(queryObject, LL_CM, NULL, &obj_count, &err_code); if (!cluster) { printf("Query CLUSTERS: ll_get_objs() returns NULL. Error code = %d\n", err_code); } printf("Number of Cluster objects = %d\n", obj_count); while(cluster) { resource = NULL; ll_get_data(cluster, LL_ClusterGetFirstResource, &resource); while(resource) { rc = ll_get_data(resource, LL_ResourceName, &res_name); if (!rc) {printf("Resource Name = %s\n", res_name); free(res_name);} rc = ll_get_data(resource, LL_ResourceInitialValue, &value); if (!rc) {printf("Resource Initial Value = %d\n", value);} rc = ll_get_data(resource, LL_ResourceAvailableValue, &value); if (!rc) {printf("Resource Available Value = %d\n", value);} resource = NULL; ll_get_data(cluster, LL_ClusterGetNextResource, &resource); } cluster = ll_next_obj(queryObject); } ll_free_objs(queryObject); ll_deallocate(queryObject); }