diff --git a/src/api/allocate.c b/src/api/allocate.c index 37b4f5e38198af39d5dfb40d557d4bedc879d1a8..badf57b3a3189b1a81c570a6de864d31b8ee97a0 100644 --- a/src/api/allocate.c +++ b/src/api/allocate.c @@ -1,15 +1,15 @@ /* - * allocate.c - Allocate nodes for a job with supplied contraints - * See slurm.h for documentation on external functions and data structures + * allocate.c - allocate nodes for a job with supplied contraints + * see slurm.h for documentation on external functions and data structures * - * Author: Moe Jette, jette@llnl.gov + * author: moe jette, jette@llnl.gov */ #define DEBUG_SYSTEM 1 #ifdef HAVE_CONFIG_H # include <config.h> -#endif +#endif #include <errno.h> #include <stdio.h> @@ -22,120 +22,131 @@ #if DEBUG_MODULE /* main is used here for testing purposes only */ -main(int argc, char * argv[]) { - int Error_Code; - char *NodeList; - - Error_Code = Allocate( - "JobName=Job01 TotalNodes=400 TotalCPUs=1000 NodeList=lx[3000-3003] Partition=batch MinMemory=1024 MinTmpDisk=2034 Groups=students,employee MinCPUs=4 Contiguous Key=1234", - &NodeList); - if (Error_Code) - printf("Allocate error %d\n", Error_Code); - else { - printf("Allocate nodes %s\n", NodeList); - free(NodeList); - } /* else */ - - while (1) { - Error_Code = Allocate( - "JobName=More TotalCPUs=4000 Partition=batch Key=1234 ", - &NodeList); - if (Error_Code) { - printf("Allocate error %d\n", Error_Code); - break; - } else { - printf("Allocate nodes %s\n", NodeList); - free(NodeList); - } /* else */ - } /* while */ - - while (1) { - Error_Code = Allocate( - "JobName=More TotalCPUs=40 Partition=batch Key=1234 ", - &NodeList); - if (Error_Code) { - printf("Allocate error %d\n", Error_Code); - break; - } else { - printf("Allocate nodes %s\n", NodeList); - free(NodeList); - } /* else */ - } /* while */ - - exit(0); -} /* main */ +main (int argc, char *argv[]) { + int error_code; + char *node_list; + + error_code = slurm_allocate + ("JobName=job01 TotalNodes=400 TotalCPUs=1000 NodeList=lx[3000-3003] Partition=batch MinMemory=1024 MinTmpDisk=2034 Groups=students,employee MinCPUs=4 Contiguous Key=1234", + &node_list); + if (error_code) + printf ("allocate error %d\n", error_code); + else { + printf ("allocate nodes %s\n", node_list); + free (node_list); + } /* else */ + + while (1) { + error_code = slurm_allocate + ("JobName=more TotalCPUs=4000 Partition=batch Key=1234 ", + &node_list); + if (error_code) { + printf ("allocate error %d\n", error_code); + break; + } + else { + printf ("allocate nodes %s\n", node_list); + free (node_list); + } /* else */ + } /* while */ + + while (1) { + error_code = slurm_allocate + ("JobName=more TotalCPUs=40 Partition=batch Key=1234 ", + &node_list); + if (error_code) { + printf ("allocate error %d\n", error_code); + break; + } + else { + printf ("allocate nodes %s\n", node_list); + free (node_list); + } /* else */ + } /* while */ + + exit (0); +} #endif /* - * Allocate - Allocate nodes for a job with supplied contraints. - * Input: Spec - Specification of the job's constraints - * NodeList - Place into which a node list pointer can be placed - * Output: NodeList - List of allocated nodes - * Returns 0 if no error, EINVAL if the request is invalid, + * slurm_allocate - allocate nodes for a job with supplied contraints. + * input: spec - specification of the job's constraints + * node_list - place into which a node list pointer can be placed + * output: node_list - list of allocated nodes + * returns 0 if no error, EINVAL if the request is invalid, * EAGAIN if the request can not be satisfied at present - * NOTE: Acceptable specifications include: JobName=<name>, NodeList=<list>, + * NOTE: acceptable specifications include: JobName=<name> NodeList=<list>, * Features=<features>, Groups=<groups>, Partition=<part_name>, Contiguous, * TotalCPUs=<number>, TotalNodes=<number>, MinCPUs=<number>, * MinMemory=<number>, MinTmpDisk=<number>, Key=<number>, Shared=<0|1> - * NOTE: The calling function must free the allocated storage at NodeList[0] + * NOTE: the calling function must free the allocated storage at node_list[0] */ -int Allocate(char *Spec, char **NodeList) { - int Buffer_Offset, Buffer_Size, Error_Code, In_Size; - char *Request_Msg, *Buffer; - int sockfd; - struct sockaddr_in serv_addr; - - if ((Spec == NULL) || (NodeList == (char **)NULL)) return EINVAL; - Request_Msg = malloc(strlen(Spec)+10); - if (Request_Msg == NULL) return EAGAIN; - strcpy(Request_Msg, "Allocate "); - strcat(Request_Msg, Spec); - - if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) return EINVAL; - serv_addr.sin_family = PF_INET; - serv_addr.sin_addr.s_addr = inet_addr(SLURMCTLD_HOST); - serv_addr.sin_port = htons(SLURMCTLD_PORT); - if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { - close(sockfd); - return EAGAIN; - } /* if */ - if (send(sockfd, Request_Msg, strlen(Request_Msg)+1, 0) < strlen(Request_Msg)) { - close(sockfd); - return EAGAIN; - } /* if */ - - Buffer = NULL; - Buffer_Offset = 0; - Buffer_Size = 8 * 1024; - while (1) { - Buffer = realloc(Buffer, Buffer_Size); - if (Buffer == NULL) { - close(sockfd); - return EAGAIN; - } /* if */ - In_Size = recv(sockfd, &Buffer[Buffer_Offset], (Buffer_Size-Buffer_Offset), 0); - if (In_Size <= 0) { /* End if input */ - In_Size = 0; - break; - } /* if */ - Buffer_Offset += In_Size; - Buffer_Size += In_Size; - } /* while */ - close(sockfd); - Buffer_Size = Buffer_Offset + In_Size; - Buffer = realloc(Buffer, Buffer_Size); - if (Buffer == NULL) return EAGAIN; - - if (strcmp(Buffer, "EAGAIN") == 0) { - free(Buffer); - return EAGAIN; - } /* if */ - if (strcmp(Buffer, "EINVAL") == 0) { - free(Buffer); - return EINVAL; - } /* if */ - NodeList[0] = Buffer; - return 0; -} /* Allocate */ - +int +slurm_allocate (char *spec, char **node_list) { + int buffer_offset, buffer_size, error_code, in_size; + char *request_msg, *buffer; + int sockfd; + struct sockaddr_in serv_addr; + + if ((spec == NULL) || (node_list == (char **) NULL)) + return EINVAL; + request_msg = malloc (strlen (spec) + 10); + if (request_msg == NULL) + return EAGAIN; + strcpy (request_msg, "Allocate "); + strcat (request_msg, spec); + + if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) < 0) + return EINVAL; + serv_addr.sin_family = PF_INET; + serv_addr.sin_addr.s_addr = inet_addr (SLURMCTLD_HOST); + serv_addr.sin_port = htons (SLURMCTLD_PORT); + if (connect + (sockfd, (struct sockaddr *) &serv_addr, + sizeof (serv_addr)) < 0) { + close (sockfd); + return EAGAIN; + } /* if */ + if (send (sockfd, request_msg, strlen (request_msg) + 1, 0) < + strlen (request_msg)) { + close (sockfd); + return EAGAIN; + } /* if */ + + buffer = NULL; + buffer_offset = 0; + buffer_size = 8 * 1024; + while (1) { + buffer = realloc (buffer, buffer_size); + if (buffer == NULL) { + close (sockfd); + return EAGAIN; + } /* if */ + in_size = + recv (sockfd, &buffer[buffer_offset], + (buffer_size - buffer_offset), 0); + if (in_size <= 0) { /* end if input */ + in_size = 0; + break; + } /* if */ + buffer_offset += in_size; + buffer_size += in_size; + } /* while */ + close (sockfd); + buffer_size = buffer_offset + in_size; + buffer = realloc (buffer, buffer_size); + if (buffer == NULL) + return EAGAIN; + + if (strcmp (buffer, "EAGAIN") == 0) { + free (buffer); + return EAGAIN; + } /* if */ + if (strcmp (buffer, "EINVAL") == 0) { + free (buffer); + return EINVAL; + } /* if */ + node_list[0] = buffer; + return 0; +} diff --git a/src/api/config_info.c b/src/api/config_info.c index 142366afb990233a3a64b78a8ceee214f344a3a5..e616669c93ccc62ec10c64536a8e8578ee501892 100644 --- a/src/api/config_info.c +++ b/src/api/config_info.c @@ -1,8 +1,8 @@ /* - * partition_info.c - Get the partition information of SLURM - * See slurm.h for documentation on external functions and data structures + * partition_info.c - get the partition information of slurm + * see slurm.h for documentation on external functions and data structures * - * Author: Moe Jette, jette@llnl.gov + * author: moe jette, jette@llnl.gov */ #ifdef HAVE_CONFIG_H @@ -20,179 +20,227 @@ #include "slurm.h" #include "slurmlib.h" -char *Build_API_Buffer = NULL; -int Build_API_Buffer_Size = 0; +static char *build_api_buffer = NULL; +static int build_api_buffer_size = 0; +static pthread_mutex_t build_api_mutex = PTHREAD_MUTEX_INITIALIZER; #if DEBUG_MODULE /* main is used here for module testing purposes only */ -main(int argc, char * argv[]) { - char Req_Name[BUILD_SIZE], Next_Name[BUILD_SIZE], Value[BUILD_SIZE]; - int Error_Code; - - Error_Code = Load_Build(); - if (Error_Code) { - printf("Load_Build error %d\n", Error_Code); - exit(1); - } /* if */ - strcpy(Req_Name, ""); /* Start at beginning of build configuration list */ - while (Error_Code == 0) { - Error_Code = Load_Build_Name(Req_Name, Next_Name, Value); - if (Error_Code != 0) { - printf("Load_Build_Name error %d finding %s\n", Error_Code, Req_Name); - break; - } /* if */ - - printf("%s=%s\n", Req_Name, Value); - if (strlen(Next_Name) == 0) break; - strcpy(Req_Name, Next_Name); - } /* while */ - Free_Build_Info(); - exit(0); -} /* main */ +main (int argc, char *argv[]) { + char req_name[BUILD_SIZE], next_name[BUILD_SIZE], value[BUILD_SIZE]; + int error_code; + + error_code = slurm_load_build (); + if (error_code) { + printf ("slurm_load_build error %d\n", error_code); + exit (1); + } + strcpy (req_name, ""); /* start at beginning of build configuration list */ + while (error_code == 0) { + error_code = slurm_load_build_name (req_name, next_name, value); + if (error_code != 0) { + printf ("slurm_load_build_name error %d finding %s\n", + error_code, req_name); + break; + } + + printf ("%s=%s\n", req_name, value); + if (strlen (next_name) == 0) + break; + strcpy (req_name, next_name); + } + slurm_free_build_info (); + exit (0); +} #endif /* - * Free_Build_Info - Free the build information buffer (if allocated) + * slurm_free_build_info - free the build information buffer (if allocated) + * NOTE: buffer is loaded by load_build and used by load_build_name. */ -void Free_Build_Info(void) { - if (Build_API_Buffer) free(Build_API_Buffer); -} /* Free_Build_Info */ +void slurm_free_build_info (void) { + pthread_mutex_lock(&build_api_mutex); + if (build_api_buffer) + free (build_api_buffer); + build_api_buffer = NULL; + pthread_mutex_unlock(&build_api_mutex); +} /* - * Load_Build - Update the build information buffer for use by info gathering APIs - * Output: Returns 0 if no error, EINVAL if the buffer is invalid, ENOMEM if malloc failure + * slurm_load_build - update the build information buffer for use by info gathering APIs + * output: returns 0 if no error, EINVAL if the buffer is invalid, ENOMEM if malloc failure. + * NOTE: buffer is used by load_build_name and freed by free_build_info. */ -int Load_Build() { - int Buffer_Offset, Buffer_Size, Error_Code, In_Size, Version; - char *Buffer, *My_Line; - int sockfd; - struct sockaddr_in serv_addr; - unsigned long My_Time; - - if (Build_API_Buffer) return 0; /* Already loaded */ - - if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) return EINVAL; - serv_addr.sin_family = PF_INET; - serv_addr.sin_addr.s_addr = inet_addr(SLURMCTLD_HOST); - serv_addr.sin_port = htons(SLURMCTLD_PORT); - if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { - close(sockfd); - return EINVAL; - } /* if */ - if (send(sockfd, "DumpBuild", 10, 0) < 10) { - close(sockfd); - return EINVAL; - } /* if */ - Buffer = NULL; - Buffer_Offset = 0; - Buffer_Size = 1024; - while (1) { - Buffer = realloc(Buffer, Buffer_Size); - if (Buffer == NULL) { - close(sockfd); - return ENOMEM; - } /* if */ - In_Size = recv(sockfd, &Buffer[Buffer_Offset], (Buffer_Size-Buffer_Offset), 0); - if (In_Size <= 0) { /* End if input */ - In_Size = 0; - break; - } /* if */ - Buffer_Offset += In_Size; - Buffer_Size += In_Size; - } /* while */ - close(sockfd); - Buffer_Size = Buffer_Offset + In_Size; - Buffer = realloc(Buffer, Buffer_Size); - if (Buffer == NULL) return ENOMEM; - - Buffer_Offset = 0; - Error_Code = Read_Buffer(Buffer, &Buffer_Offset, Buffer_Size, &My_Line); - if ((Error_Code) || (strlen(My_Line) < strlen(HEAD_FORMAT))) { +int slurm_load_build () { + int buffer_offset, buffer_size, error_code, in_size, version; + char *buffer, *my_line; + int sockfd; + struct sockaddr_in serv_addr; + unsigned long my_time; + + if (build_api_buffer) + return 0; /* already loaded */ + + if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) < 0) + return EINVAL; + serv_addr.sin_family = PF_INET; + serv_addr.sin_addr.s_addr = inet_addr (SLURMCTLD_HOST); + serv_addr.sin_port = htons (SLURMCTLD_PORT); + if (connect + (sockfd, (struct sockaddr *) &serv_addr, + sizeof (serv_addr)) < 0) { + close (sockfd); + return EINVAL; + } + if (send (sockfd, "DumpBuild", 10, 0) < 10) { + close (sockfd); + return EINVAL; + } + buffer = NULL; + buffer_offset = 0; + buffer_size = 1024; + while (1) { + buffer = realloc (buffer, buffer_size); + if (buffer == NULL) { + close (sockfd); + return ENOMEM; + } + in_size = + recv (sockfd, &buffer[buffer_offset], + (buffer_size - buffer_offset), 0); + if (in_size <= 0) { /* end if input */ + in_size = 0; + break; + } + buffer_offset += in_size; + buffer_size += in_size; + } + close (sockfd); + buffer_size = buffer_offset + in_size; + buffer = realloc (buffer, buffer_size); + if (buffer == NULL) + return ENOMEM; + + buffer_offset = 0; + error_code = + read_buffer (buffer, &buffer_offset, buffer_size, &my_line); + if ((error_code) || (strlen (my_line) < strlen (HEAD_FORMAT))) { #if DEBUG_SYSTEM - fprintf(stderr, "Load_Build: Node buffer lacks valid header\n"); + fprintf (stderr, + "load_build: node buffer lacks valid header\n"); #else - syslog(LOG_ERR, "Load_Build: Node buffer lacks valid header\n"); + syslog (LOG_ERR, + "load_build: node buffer lacks valid header\n"); #endif - free(Buffer); - return EINVAL; - } /* if */ - sscanf(My_Line, HEAD_FORMAT, &My_Time, &Version); - if (Version != BUILD_STRUCT_VERSION) { + free (buffer); + return EINVAL; + } + sscanf (my_line, HEAD_FORMAT, &my_time, &version); + if (version != BUILD_STRUCT_VERSION) { #if DEBUG_SYSTEM - fprintf(stderr, "Load_Build: expect version %d, read %d\n", BUILD_STRUCT_VERSION, Version); + fprintf (stderr, "load_build: expect version %d, read %d\n", + BUILD_STRUCT_VERSION, version); #else - syslog(LOG_ERR, "Load_Build: expect version %d, read %d\n", BUILD_STRUCT_VERSION, Version); + syslog (LOG_ERR, "load_build: expect version %d, read %d\n", + BUILD_STRUCT_VERSION, version); #endif - free(Buffer); - return EINVAL; - } /* if */ - - Build_API_Buffer = Buffer; - Build_API_Buffer_Size = Buffer_Size; - return 0; -} /* Load_Build */ + free (buffer); + return EINVAL; + } + + pthread_mutex_lock(&build_api_mutex); + if (build_api_buffer) free(build_api_buffer); + build_api_buffer = buffer; + build_api_buffer_size = buffer_size; + pthread_mutex_unlock(&build_api_mutex); + return 0; +} /* - * Load_Build_Name - Load the state information about the named build parameter - * Input: Req_Name - Name of the parameter for which information is requested + * slurm_load_build_name - load the state information about the named build parameter + * input: req_name - name of the parameter for which information is requested * if "", then get info for the first parameter in list - * Next_Name - Location into which the name of the next parameter is + * next_name - location into which the name of the next parameter is * stored, "" if no more - * Value - Pointer to location into which the information is to be stored - * Output: Req_Name - The parameter's name is stored here - * Next_Name - The name of the next parameter in the list is stored here - * Value - The parameter's state information - * Returns 0 on success, ENOENT if not found, or EINVAL if buffer is bad - * NOTE: Req_Name, Next_Name, and Value must be declared by caller with have + * value - pointer to location into which the information is to be stored + * output: req_name - the parameter's name is stored here + * next_name - the name of the next parameter in the list is stored here + * value - the parameter's state information + * returns 0 on success, ENOENT if not found, or EINVAL if buffer is bad + * NOTE: req_name, next_name, and value must be declared by caller with have * length BUILD_SIZE or larger + * NOTE: buffer is loaded by load_build and freed by free_build_info. */ -int Load_Build_Name(char *Req_Name, char *Next_Name, char *Value) { - int i, Error_Code, Version, Buffer_Offset; - static char Next_Build_Name[BUILD_SIZE] = ""; - static Last_Buffer_Offset; - unsigned long My_Time; - char *My_Line; - char My_Build_Name[BUILD_SIZE], My_Build_Value[BUILD_SIZE]; - - /* Load buffer's header (data structure version and time) */ - Buffer_Offset = 0; - Error_Code = Read_Buffer(Build_API_Buffer, &Buffer_Offset, Build_API_Buffer_Size, &My_Line); - if (Error_Code) return Error_Code; - sscanf(My_Line, HEAD_FORMAT, &My_Time, &Version); - - if ((strcmp(Req_Name, Next_Build_Name) == 0) && - (strlen(Req_Name) != 0)) Buffer_Offset=Last_Buffer_Offset; - - while (1) { - /* Load all info for next parameter */ - Error_Code = Read_Buffer(Build_API_Buffer, &Buffer_Offset, Build_API_Buffer_Size, &My_Line); - if (Error_Code == EFAULT) break; /* End of buffer */ - if (Error_Code) return Error_Code; - - i=sscanf(My_Line, BUILD_STRUCT_FORMAT, My_Build_Name, My_Build_Value); - if (i == 1) strcpy(My_Build_Value, ""); /* empty string passed */ - if (strlen(Req_Name) == 0) strncpy(Req_Name, My_Build_Name, BUILD_SIZE); - - /* Check if this is requested parameter */ - if (strcmp(Req_Name, My_Build_Name) != 0) continue; - - /*Load values to be returned */ - strncpy(Value, My_Build_Value, BUILD_SIZE); - - Last_Buffer_Offset = Buffer_Offset; - Error_Code = Read_Buffer(Build_API_Buffer, &Buffer_Offset, Build_API_Buffer_Size, &My_Line); - if (Error_Code) { /* No more records */ - strcpy(Next_Build_Name, ""); - strcpy(Next_Name, ""); - } else { - sscanf(My_Line, BUILD_STRUCT_FORMAT, My_Build_Name, My_Build_Value); - strncpy(Next_Build_Name, My_Build_Name, BUILD_SIZE); - strncpy(Next_Name, My_Build_Name, BUILD_SIZE); - } /* else */ - return 0; - } /* while */ - return ENOENT; -} /* Load_Build_Name */ +int slurm_load_build_name (char *req_name, char *next_name, char *value) { + int i, error_code, version, buffer_offset; + static char next_build_name[BUILD_SIZE] = ""; + static last_buffer_offset; + unsigned long my_time; + char *my_line; + char my_build_name[BUILD_SIZE], my_build_value[BUILD_SIZE]; + + /* load buffer's header (data structure version and time) */ + pthread_mutex_lock(&build_api_mutex); + buffer_offset = 0; + error_code = + read_buffer (build_api_buffer, &buffer_offset, + build_api_buffer_size, &my_line); + if (error_code) { + pthread_mutex_unlock(&build_api_mutex); + return error_code; + } + sscanf (my_line, HEAD_FORMAT, &my_time, &version); + + if ((strcmp (req_name, next_build_name) == 0) && + (strlen (req_name) != 0)) + buffer_offset = last_buffer_offset; + + while (1) { + /* load all info for next parameter */ + error_code = + read_buffer (build_api_buffer, &buffer_offset, + build_api_buffer_size, &my_line); + if (error_code == EFAULT) + break; /* end of buffer */ + if (error_code) { + pthread_mutex_unlock(&build_api_mutex); + return error_code; + } + + i = sscanf (my_line, BUILD_STRUCT_FORMAT, my_build_name, + my_build_value); + if (i == 1) + strcpy (my_build_value, ""); /* empty string passed */ + if (strlen (req_name) == 0) + strncpy (req_name, my_build_name, BUILD_SIZE); + + /* check if this is requested parameter */ + if (strcmp (req_name, my_build_name) != 0) + continue; + + /*load values to be returned */ + strncpy (value, my_build_value, BUILD_SIZE); + + last_buffer_offset = buffer_offset; + error_code = + read_buffer (build_api_buffer, &buffer_offset, + build_api_buffer_size, &my_line); + if (error_code) { /* no more records */ + strcpy (next_build_name, ""); + strcpy (next_name, ""); + } + else { + sscanf (my_line, BUILD_STRUCT_FORMAT, my_build_name, + my_build_value); + strncpy (next_build_name, my_build_name, BUILD_SIZE); + strncpy (next_name, my_build_name, BUILD_SIZE); + } + pthread_mutex_unlock(&build_api_mutex); + return 0; + } + pthread_mutex_unlock(&build_api_mutex); + return ENOENT; +} diff --git a/src/api/node_info.c b/src/api/node_info.c index 98f7124d9966055b2cc2bed7a0f3948e24beed6a..5b1c74659193be715295676b6eeed4222bd481e5 100644 --- a/src/api/node_info.c +++ b/src/api/node_info.c @@ -1,15 +1,15 @@ /* - * node_info.c - Get the node records of SLURM - * See slurm.h for documentation on external functions and data structures + * node_info.c - get the node records of slurm + * see slurm.h for documentation on external functions and data structures * - * Author: Moe Jette, jette@llnl.gov + * author: moe jette, jette@llnl.gov */ #define DEBUG_SYSTEM 1 #ifdef HAVE_CONFIG_H # include <config.h> -#endif +#endif #include <errno.h> #include <stdio.h> @@ -20,216 +20,255 @@ #include "slurm.h" #include "slurmlib.h" -char *Node_API_Buffer = NULL; -int Node_API_Buffer_Size = 0; +char *node_api_buffer = NULL; +int node_api_buffer_size = 0; #if DEBUG_MODULE /* main is used here for testing purposes only */ -main(int argc, char * argv[]) { - static time_t Last_Update_Time = (time_t)NULL; - int Error_Code, size, i; - char Partition[MAX_NAME_LEN], Node_State[MAX_NAME_LEN], Features[FEATURE_SIZE]; - char Req_Name[MAX_NAME_LEN]; /* Name of the partition */ - char Next_Name[MAX_NAME_LEN]; /* Name of the next partition */ - int CPUs, RealMemory, TmpDisk, Weight; - char *Dump; - int Dump_Size; - time_t Update_Time; - unsigned *NodeBitMap; /* Bitmap of nodes in partition */ - int BitMapSize; /* Bytes in NodeBitMap */ - - Error_Code = Load_Node(&Last_Update_Time); - if (Error_Code) printf("Load_Node error %d\n", Error_Code); - - strcpy(Req_Name, ""); /* Start at beginning of partition list */ - for (i=1; ;i++) { - Error_Code = Load_Node_Config(Req_Name, Next_Name, &CPUs, &RealMemory, &TmpDisk, &Weight, - Features, Partition, Node_State); - if (Error_Code != 0) { - printf("Load_Node_Config error %d on %s\n", Error_Code, Req_Name); - break; - } /* if */ - if ((i<10) || (i%100 == 0)) { - printf("Found node Name=%s CPUs=%d RealMemory=%d TmpDisk=%d ", - Req_Name, CPUs, RealMemory, TmpDisk); - printf("State=%s Weight=%d Features=%s Partition=%s\n", - Node_State, Weight, Features, Partition); - } else if (i%100 == 1) - printf("Skipping...\n"); - - if (strlen(Next_Name) == 0) break; - strcpy(Req_Name, Next_Name); - } /* while */ - Free_Node_Info(); - exit(0); -} /* main */ +main (int argc, char *argv[]) { + static time_t last_update_time = (time_t) NULL; + int error_code, size, i; + char partition[MAX_NAME_LEN], node_state[MAX_NAME_LEN], + features[FEATURE_SIZE]; + char req_name[MAX_NAME_LEN]; /* name of the partition */ + char next_name[MAX_NAME_LEN]; /* name of the next partition */ + int cpus, real_memory, tmp_disk, weight; + char *dump; + int dump_size; + time_t update_time; + unsigned *node_bitmap; /* bitmap of nodes in partition */ + int bitmap_size; /* bytes in node_bitmap */ + + error_code = load_node (&last_update_time); + if (error_code) + printf ("load_node error %d\n", error_code); + + strcpy (req_name, ""); /* start at beginning of partition list */ + for (i = 1;; i++) { + error_code = + load_node_config (req_name, next_name, &cpus, + &real_memory, &tmp_disk, &weight, + features, partition, node_state); + if (error_code != 0) { + printf ("load_node_config error %d on %s\n", + error_code, req_name); + break; + } + if ((i < 10) || (i % 100 == 0)) { + printf ("found NodeName=%s CPUs=%d RealMemory=%d TmpDisk=%d ", + req_name, cpus, real_memory, tmp_disk); + printf ("State=%s Weight=%d Features=%s Partition=%s\n", + node_state, weight, features, partition); + } + else if ((i==10) || (i % 100 == 1)) + printf ("skipping...\n"); + + if (strlen (next_name) == 0) + break; + strcpy (req_name, next_name); + } + free_node_info (); + exit (0); +} #endif /* - * Free_Node_Info - Free the node information buffer (if allocated) + * free_node_info - free the node information buffer (if allocated) + * NOTE: buffer is loaded by load_node and used by load_node_name. */ -void Free_Node_Info(void) { - if (Node_API_Buffer) free(Node_API_Buffer); -} /* Free_Node_Info */ +void +free_node_info (void) +{ + if (node_api_buffer) + free (node_api_buffer); +} /* - * Load_Node - Load the supplied node information buffer for use by info gathering APIs if + * load_node - load the supplied node information buffer for use by info gathering apis if * node records have changed since the time specified. - * Input: Buffer - Pointer to node information buffer - * Buffer_Size - size of Buffer - * Output: Returns 0 if no error, EINVAL if the buffer is invalid, ENOMEM if malloc failure + * input: buffer - pointer to node information buffer + * buffer_size - size of buffer + * output: returns 0 if no error, EINVAL if the buffer is invalid, ENOMEM if malloc failure + * NOTE: buffer is used by load_node_config and freed by free_node_info. */ -int Load_Node(time_t *Last_Update_Time) { - int Buffer_Offset, Buffer_Size, Error_Code, In_Size, Version; - char Request_Msg[64], *Buffer, *My_Line; - int sockfd; - struct sockaddr_in serv_addr; - unsigned long My_Time; - - if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) return EINVAL; - serv_addr.sin_family = PF_INET; - serv_addr.sin_addr.s_addr = inet_addr(SLURMCTLD_HOST); - serv_addr.sin_port = htons(SLURMCTLD_PORT); - if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { - close(sockfd); - return EINVAL; - } /* if */ - sprintf(Request_Msg, "DumpNode LastUpdate=%lu", (long)(*Last_Update_Time)); - if (send(sockfd, Request_Msg, strlen(Request_Msg)+1, 0) < strlen(Request_Msg)) { - close(sockfd); - return EINVAL; - } /* if */ - Buffer = NULL; - Buffer_Offset = 0; - Buffer_Size = 8 * 1024; - while (1) { - Buffer = realloc(Buffer, Buffer_Size); - if (Buffer == NULL) { - close(sockfd); - return ENOMEM; - } /* if */ - In_Size = recv(sockfd, &Buffer[Buffer_Offset], (Buffer_Size-Buffer_Offset), 0); - if (In_Size <= 0) { /* End if input */ - In_Size = 0; - break; - } /* if */ - Buffer_Offset += In_Size; - Buffer_Size += In_Size; - } /* while */ - close(sockfd); - Buffer_Size = Buffer_Offset + In_Size; - Buffer = realloc(Buffer, Buffer_Size); - if (Buffer == NULL) return ENOMEM; - if (strcmp(Buffer, "NOCHANGE") == 0) { - free(Buffer); - return 0; - } /* if */ +int +load_node (time_t * last_update_time) { + int buffer_offset, buffer_size, error_code, in_size, version; + char request_msg[64], *buffer, *my_line; + int sockfd; + struct sockaddr_in serv_addr; + unsigned long my_time; + + if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) < 0) + return EINVAL; + serv_addr.sin_family = PF_INET; + serv_addr.sin_addr.s_addr = inet_addr (SLURMCTLD_HOST); + serv_addr.sin_port = htons (SLURMCTLD_PORT); + if (connect + (sockfd, (struct sockaddr *) &serv_addr, + sizeof (serv_addr)) < 0) { + close (sockfd); + return EINVAL; + } + sprintf (request_msg, "DumpNode LastUpdate=%lu", + (long) (*last_update_time)); + if (send (sockfd, request_msg, strlen (request_msg) + 1, 0) < + strlen (request_msg)) { + close (sockfd); + return EINVAL; + } + buffer = NULL; + buffer_offset = 0; + buffer_size = 8 * 1024; + while (1) { + buffer = realloc (buffer, buffer_size); + if (buffer == NULL) { + close (sockfd); + return ENOMEM; + } + in_size = + recv (sockfd, &buffer[buffer_offset], + (buffer_size - buffer_offset), 0); + if (in_size <= 0) { /* end if input */ + in_size = 0; + break; + } + buffer_offset += in_size; + buffer_size += in_size; + } + close (sockfd); + buffer_size = buffer_offset + in_size; + buffer = realloc (buffer, buffer_size); + if (buffer == NULL) + return ENOMEM; + if (strcmp (buffer, "nochange") == 0) { + free (buffer); + return 0; + } - /* Load buffer's header (data structure version and time) */ - Buffer_Offset = 0; - Error_Code = Read_Buffer(Buffer, &Buffer_Offset, Buffer_Size, &My_Line); - if ((Error_Code) || (strlen(My_Line) < strlen(HEAD_FORMAT))) { + /* load buffer's header (data structure version and time) */ + buffer_offset = 0; + error_code = + read_buffer (buffer, &buffer_offset, buffer_size, &my_line); + if ((error_code) || (strlen (my_line) < strlen (HEAD_FORMAT))) { #if DEBUG_SYSTEM - fprintf(stderr, "Load_Node: Node buffer lacks valid header\n"); + fprintf (stderr, + "load_node: node buffer lacks valid header\n"); #else - syslog(LOG_ERR, "Load_Node: Node buffer lacks valid header\n"); + syslog (LOG_ERR, + "load_node: node buffer lacks valid header\n"); #endif - free(Buffer); - return EINVAL; - } /* if */ - sscanf(My_Line, HEAD_FORMAT, &My_Time, &Version); + free (buffer); + return EINVAL; + } + sscanf (my_line, HEAD_FORMAT, &my_time, &version); - if (Version != NODE_STRUCT_VERSION) { + if (version != NODE_STRUCT_VERSION) { #if DEBUG_SYSTEM - fprintf(stderr, "Load_Part: expect version %d, read %d\n", NODE_STRUCT_VERSION, Version); + fprintf (stderr, "load_part: expect version %d, read %d\n", + NODE_STRUCT_VERSION, version); #else - syslog(LOG_ERR, "Load_Part: expect version %d, read %d\n", NODE_STRUCT_VERSION, Version); + syslog (LOG_ERR, "load_part: expect version %d, read %d\n", + NODE_STRUCT_VERSION, version); #endif - free(Buffer); - return EINVAL; - } /* if */ + free (buffer); + return EINVAL; + } - *Last_Update_Time = (time_t)My_Time; - Node_API_Buffer = Buffer; - Node_API_Buffer_Size = Buffer_Size; - return 0; -} /* Load_Node */ + *last_update_time = (time_t) my_time; + node_api_buffer = buffer; + node_api_buffer_size = buffer_size; + return 0; +} /* - * Load_Node_Config - Load the state information about the named node - * Input: Req_Name - Name of the node for which information is requested + * load_node_config - load the state information about the named node + * input: req_name - name of the node for which information is requested * if "", then get info for the first node in list - * Next_Name - Location into which the name of the next node is + * next_name - location into which the name of the next node is * stored, "" if no more - * CPUs, etc. - Pointers into which the information is to be stored - * Output: Next_Name - Name of the next node in the list - * CPUs, etc. - The node's state information - * Returns 0 on success, ENOENT if not found, or EINVAL if buffer is bad - * NOTE: Req_Name, Next_Name, Partition, and NodeState must be declared by the + * cpus, etc. - pointers into which the information is to be stored + * output: next_name - name of the next node in the list + * cpus, etc. - the node's state information + * returns 0 on success, ENOENT if not found, or EINVAL if buffer is bad + * NOTE: req_name, next_name, partition, and node_state must be declared by the * caller and have length MAX_NAME_LEN or larger - * Features must be declared by the caller and have length FEATURE_SIZE or larger + * features must be declared by the caller and have length FEATURE_SIZE or larger. + * NOTE: buffer is loaded by load_node and freed by free_node_info. */ -int Load_Node_Config(char *Req_Name, char *Next_Name, int *CPUs, - int *RealMemory, int *TmpDisk, int *Weight, char *Features, - char *Partition, char *NodeState) { - int i, Error_Code, Version, Buffer_Offset, My_Weight; - static time_t Last_Update_Time, Update_Time; - struct Node_Record My_Node; - static char Next_Name_Value[MAX_NAME_LEN]; - static Last_Buffer_Offset; - char My_NodeName[MAX_NAME_LEN], *My_Line; - unsigned long My_Time; - - /* Load buffer's header (data structure version and time) */ - Buffer_Offset = 0; - Error_Code = Read_Buffer(Node_API_Buffer, &Buffer_Offset, Node_API_Buffer_Size, &My_Line); - if (Error_Code) return Error_Code; - sscanf(My_Line, HEAD_FORMAT, &My_Time, &Version); - Update_Time = (time_t) My_Time; - - if ((Update_Time == Last_Update_Time) && (strcmp(Req_Name,Next_Name_Value) == 0) && - (strlen(Req_Name) != 0)) Buffer_Offset=Last_Buffer_Offset; - Last_Update_Time = Update_Time; - - while (1) { - /* Load all information for next node */ - Error_Code = Read_Buffer(Node_API_Buffer, &Buffer_Offset, Node_API_Buffer_Size, &My_Line); - if (Error_Code == EFAULT) break; /* End of buffer */ - if (Error_Code) return Error_Code; - sscanf(My_Line, NODE_STRUCT_FORMAT, - My_NodeName, - NodeState, - &My_Node.CPUs, - &My_Node.RealMemory, - &My_Node.TmpDisk, - &My_Weight, - Features, - Partition); - if (strlen(Req_Name) == 0) strncpy(Req_Name, My_NodeName, MAX_NAME_LEN); - - /* Check if this is requested node */ - if (strcmp(Req_Name, My_NodeName) != 0) continue; - - /*Load values to be returned */ - *CPUs = My_Node.CPUs; - *RealMemory = My_Node.RealMemory; - *TmpDisk = My_Node.TmpDisk; - *Weight = My_Weight; - - Last_Buffer_Offset = Buffer_Offset; - Error_Code = Read_Buffer(Node_API_Buffer, &Buffer_Offset, Node_API_Buffer_Size, &My_Line); - if (Error_Code) { /* No more records */ - strcpy(Next_Name_Value, ""); - strcpy(Next_Name, ""); - } else { - sscanf(My_Line, "NodeName=%s", My_NodeName); - strncpy(Next_Name_Value, My_NodeName, MAX_NAME_LEN); - strncpy(Next_Name, My_NodeName, MAX_NAME_LEN); - } /* else */ - return 0; - } /* while */ - return ENOENT; -} /* Load_Node_Config */ +int +load_node_config (char *req_name, char *next_name, int *cpus, + int *real_memory, int *tmp_disk, int *weight, + char *features, char *partition, char *node_state) { + int i, error_code, version, buffer_offset, my_weight; + static time_t last_update_time, update_time; + struct node_record my_node; + static char next_name_value[MAX_NAME_LEN]; + static last_buffer_offset; + char my_node_name[MAX_NAME_LEN], *my_line; + unsigned long my_time; + + /* load buffer's header (data structure version and time) */ + buffer_offset = 0; + error_code = + read_buffer (node_api_buffer, &buffer_offset, + node_api_buffer_size, &my_line); + if (error_code) + return error_code; + sscanf (my_line, HEAD_FORMAT, &my_time, &version); + update_time = (time_t) my_time; + + if ((update_time == last_update_time) + && (strcmp (req_name, next_name_value) == 0) + && (strlen (req_name) != 0)) + buffer_offset = last_buffer_offset; + last_update_time = update_time; + + while (1) { + /* load all information for next node */ + error_code = + read_buffer (node_api_buffer, &buffer_offset, + node_api_buffer_size, &my_line); + if (error_code == EFAULT) + break; /* end of buffer */ + if (error_code) + return error_code; + sscanf (my_line, NODE_STRUCT_FORMAT, + my_node_name, + node_state, + &my_node.cpus, + &my_node.real_memory, + &my_node.tmp_disk, &my_weight, features, partition); + if (strlen (req_name) == 0) + strncpy (req_name, my_node_name, MAX_NAME_LEN); + + /* check if this is requested node */ + if (strcmp (req_name, my_node_name) != 0) + continue; + + /*load values to be returned */ + *cpus = my_node.cpus; + *real_memory = my_node.real_memory; + *tmp_disk = my_node.tmp_disk; + *weight = my_weight; + + last_buffer_offset = buffer_offset; + error_code = + read_buffer (node_api_buffer, &buffer_offset, + node_api_buffer_size, &my_line); + if (error_code) { /* no more records */ + strcpy (next_name_value, ""); + strcpy (next_name, ""); + } + else { + sscanf (my_line, "NodeName=%s", my_node_name); + strncpy (next_name_value, my_node_name, MAX_NAME_LEN); + strncpy (next_name, my_node_name, MAX_NAME_LEN); + } /* else */ + return 0; + } + return ENOENT; +} diff --git a/src/api/partition_info.c b/src/api/partition_info.c index 5d3ac2be9cfa80ad3cbd676e17c31c2540083b4c..6d5a0e7a6fc3f7392f2bad715897e6433daf4203 100644 --- a/src/api/partition_info.c +++ b/src/api/partition_info.c @@ -1,8 +1,8 @@ /* - * partition_info.c - Get the partition information of SLURM - * See slurm.h for documentation on external functions and data structures + * partition_info.c - get the partition information of slurm + * see slurm.h for documentation on external functions and data structures * - * Author: Moe Jette, jette@llnl.gov + * author: moe jette, jette@llnl.gov */ #ifdef HAVE_CONFIG_H @@ -20,239 +20,280 @@ #include "slurm.h" #include "slurmlib.h" -char *Part_API_Buffer = NULL; -int Part_API_Buffer_Size = 0; +char *part_api_buffer = NULL; +int part_api_buffer_size = 0; #if DEBUG_MODULE /* main is used here for module testing purposes only */ -main(int argc, char * argv[]) { - static time_t Last_Update_Time = (time_t)NULL; - int Error_Code; - char Req_Name[MAX_NAME_LEN]; /* Name of the partition */ - char Next_Name[MAX_NAME_LEN]; /* Name of the next partition */ - int MaxTime; /* -1 if unlimited */ - int MaxNodes; /* -1 if unlimited */ - int TotalNodes; /* Total number of nodes in the partition */ - int TotalCPUs; /* Total number of CPUs in the partition */ - char Nodes[FEATURE_SIZE]; /* Names of nodes in partition */ - char AllowGroups[FEATURE_SIZE]; /* NULL indicates ALL */ - int Key; /* 1 if SLURM distributed key is required for use of partition */ - int StateUp; /* 1 if state is UP */ - int Shared; /* 1 if partition can be shared */ - int Default; /* 1 if default partition */ +main (int argc, char *argv[]) { + static time_t last_update_time = (time_t) NULL; + int error_code; + char req_name[MAX_NAME_LEN]; /* name of the partition */ + char next_name[MAX_NAME_LEN]; /* name of the next partition */ + int max_time; /* -1 if unlimited */ + int max_nodes; /* -1 if unlimited */ + int total_nodes; /* total number of nodes in the partition */ + int total_cpus; /* total number of cpus in the partition */ + char nodes[FEATURE_SIZE]; /* names of nodes in partition */ + char allow_groups[FEATURE_SIZE]; /* NULL indicates all */ + int key; /* 1 if slurm distributed key is required for use of partition */ + int state_up; /* 1 if state is up */ + int shared; /* 1 if partition can be shared */ + int default_flag; /* 1 if default partition */ - Error_Code = Load_Part(&Last_Update_Time); - if (Error_Code) { - printf("Load_Part error %d\n", Error_Code); - exit(1); - } /* if */ - strcpy(Req_Name, ""); /* Start at beginning of partition list */ - while (Error_Code == 0) { - Error_Code = Load_Part_Name(Req_Name, Next_Name, &MaxTime, &MaxNodes, - &TotalNodes, &TotalCPUs, &Key, &StateUp, &Shared, &Default, - Nodes, AllowGroups); - if (Error_Code != 0) { - printf("Load_Part_Name error %d finding %s\n", Error_Code, Req_Name); - break; - } /* if */ + error_code = load_part (&last_update_time); + if (error_code) { + printf ("load_part error %d\n", error_code); + exit (1); + } + strcpy (req_name, ""); /* start at beginning of partition list */ + while (error_code == 0) { + error_code = + load_part_name (req_name, next_name, &max_time, + &max_nodes, &total_nodes, &total_cpus, + &key, &state_up, &shared, &default_flag, + nodes, allow_groups); + if (error_code != 0) { + printf ("load_part_name error %d finding %s\n", + error_code, req_name); + break; + } - printf("Found partition Name=%s Nodes=%s MaxTime=%d MaxNodes=%d Default=%d \n", - Req_Name, Nodes, MaxTime, MaxNodes, Default); - printf(" TotalNodes=%d TotalCPUs=%d Key=%d StateUp=%d Shared=%d AllowGroups=%s\n", - TotalNodes, TotalCPUs, Key, StateUp, Shared, AllowGroups); - if (strlen(Next_Name) == 0) break; - strcpy(Req_Name, Next_Name); - } /* while */ - Free_Part_Info(); - exit(0); -} /* main */ + printf ("found partition NodeName=%s Nodes=%s MaxTime=%d MaxNodes=%d\n", + req_name, nodes, max_time, max_nodes, default_flag); + printf (" Default=%d TotalNodes=%d TotalCPUs=%d Key=%d StateUp=%d\n", + default_flag, total_nodes, total_cpus, key, state_up); + printf (" Shared=%d AllowGroups=%s\n", shared, allow_groups); + if (strlen (next_name) == 0) + break; + strcpy (req_name, next_name); + } + free_part_info (); + exit (0); +} #endif /* - * Free_Part_Info - Free the partition information buffer (if allocated) + * free_part_info - free the partition information buffer (if allocated) + * NOTE: buffer is loaded by load_part and used by load_part_name. */ -void Free_Part_Info(void) { - if (Part_API_Buffer) free(Part_API_Buffer); -} /* Free_Part_Info */ +void +free_part_info (void) { + if (part_api_buffer) + free (part_api_buffer); +} /* - * Load_Part - Update the partition information buffer for use by info gathering APIs if + * load_part - update the partition information buffer for use by info gathering apis if * partition records have changed since the time specified. - * Input: Last_Update_Time - Pointer to time of last buffer - * Output: Last_Update_Time - Time reset if buffer is updated - * Returns 0 if no error, EINVAL if the buffer is invalid, ENOMEM if malloc failure + * input: last_update_time - pointer to time of last buffer + * output: last_update_time - time reset if buffer is updated + * returns 0 if no error, EINVAL if the buffer is invalid, ENOMEM if malloc failure + * NOTE: buffer is used by load_part_name and free by free_part_info. */ -int Load_Part(time_t *Last_Update_Time) { - int Buffer_Offset, Buffer_Size, Error_Code, In_Size, Version; - char Request_Msg[64], *Buffer, *My_Line; - int sockfd; - struct sockaddr_in serv_addr; - unsigned long My_Time; +int +load_part (time_t * last_update_time) { + int buffer_offset, buffer_size, error_code, in_size, version; + char request_msg[64], *buffer, *my_line; + int sockfd; + struct sockaddr_in serv_addr; + unsigned long my_time; - if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) return EINVAL; - serv_addr.sin_family = PF_INET; - serv_addr.sin_addr.s_addr = inet_addr(SLURMCTLD_HOST); - serv_addr.sin_port = htons(SLURMCTLD_PORT); - if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { - close(sockfd); - return EINVAL; - } /* if */ - sprintf(Request_Msg, "DumpPart LastUpdate=%lu", (long)(*Last_Update_Time)); - if (send(sockfd, Request_Msg, strlen(Request_Msg)+1, 0) < strlen(Request_Msg)) { - close(sockfd); - return EINVAL; - } /* if */ - Buffer = NULL; - Buffer_Offset = 0; - Buffer_Size = 1024; - while (1) { - Buffer = realloc(Buffer, Buffer_Size); - if (Buffer == NULL) { - close(sockfd); - return ENOMEM; - } /* if */ - In_Size = recv(sockfd, &Buffer[Buffer_Offset], (Buffer_Size-Buffer_Offset), 0); - if (In_Size <= 0) { /* End if input */ - In_Size = 0; - break; - } /* if */ - Buffer_Offset += In_Size; - Buffer_Size += In_Size; - } /* while */ - close(sockfd); - Buffer_Size = Buffer_Offset + In_Size; - Buffer = realloc(Buffer, Buffer_Size); - if (Buffer == NULL) return ENOMEM; - if (strcmp(Buffer, "NOCHANGE") == 0) { - free(Buffer); - return 0; - } /* if */ + if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) < 0) + return EINVAL; + serv_addr.sin_family = PF_INET; + serv_addr.sin_addr.s_addr = inet_addr (SLURMCTLD_HOST); + serv_addr.sin_port = htons (SLURMCTLD_PORT); + if (connect + (sockfd, (struct sockaddr *) &serv_addr, + sizeof (serv_addr)) < 0) { + close (sockfd); + return EINVAL; + } + sprintf (request_msg, "DumpPart LastUpdate=%lu", + (long) (*last_update_time)); + if (send (sockfd, request_msg, strlen (request_msg) + 1, 0) < + strlen (request_msg)) { + close (sockfd); + return EINVAL; + } + buffer = NULL; + buffer_offset = 0; + buffer_size = 1024; + while (1) { + buffer = realloc (buffer, buffer_size); + if (buffer == NULL) { + close (sockfd); + return ENOMEM; + } + in_size = + recv (sockfd, &buffer[buffer_offset], + (buffer_size - buffer_offset), 0); + if (in_size <= 0) { /* end if input */ + in_size = 0; + break; + } + buffer_offset += in_size; + buffer_size += in_size; + } + close (sockfd); + buffer_size = buffer_offset + in_size; + buffer = realloc (buffer, buffer_size); + if (buffer == NULL) + return ENOMEM; + if (strcmp (buffer, "nochange") == 0) { + free (buffer); + return 0; + } - Buffer_Offset = 0; - Error_Code = Read_Buffer(Buffer, &Buffer_Offset, Buffer_Size, &My_Line); - if ((Error_Code) || (strlen(My_Line) < strlen(HEAD_FORMAT))) { + buffer_offset = 0; + error_code = + read_buffer (buffer, &buffer_offset, buffer_size, &my_line); + if ((error_code) || (strlen (my_line) < strlen (HEAD_FORMAT))) { #if DEBUG_SYSTEM - fprintf(stderr, "Load_Part: Node buffer lacks valid header\n"); + fprintf (stderr, + "load_part: node buffer lacks valid header\n"); #else - syslog(LOG_ERR, "Load_Part: Node buffer lacks valid header\n"); + syslog (LOG_ERR, + "load_part: node buffer lacks valid header\n"); #endif - free(Buffer); - return EINVAL; - } /* if */ - sscanf(My_Line, HEAD_FORMAT, &My_Time, &Version); - if (Version != PART_STRUCT_VERSION) { + free (buffer); + return EINVAL; + } + sscanf (my_line, HEAD_FORMAT, &my_time, &version); + if (version != PART_STRUCT_VERSION) { #if DEBUG_SYSTEM - fprintf(stderr, "Load_Part: expect version %d, read %d\n", PART_STRUCT_VERSION, Version); + fprintf (stderr, "load_part: expect version %d, read %d\n", + PART_STRUCT_VERSION, version); #else - syslog(LOG_ERR, "Load_Part: expect version %d, read %d\n", PART_STRUCT_VERSION, Version); + syslog (LOG_ERR, "load_part: expect version %d, read %d\n", + PART_STRUCT_VERSION, version); #endif - free(Buffer); - return EINVAL; - } /* if */ + free (buffer); + return EINVAL; + } - *Last_Update_Time = (time_t)My_Time; - Part_API_Buffer = Buffer; - Part_API_Buffer_Size = Buffer_Size; - return 0; -} /* Load_Part */ + *last_update_time = (time_t) my_time; + part_api_buffer = buffer; + part_api_buffer_size = buffer_size; + return 0; +} /* - * Load_Part_Name - Load the state information about the named partition - * Input: Req_Name - Name of the partition for which information is requested + * load_part_name - load the state information about the named partition + * input: req_name - name of the partition for which information is requested * if "", then get info for the first partition in list - * Next_Name - Location into which the name of the next partition is + * next_name - location into which the name of the next partition is * stored, "" if no more - * MaxTime, etc. - Pointers into which the information is to be stored - * Output: Req_Name - The partition's name is stored here - * Next_Name - The name of the next partition in the list is stored here - * MaxTime, etc. - The partition's state information - * Returns 0 on success, ENOENT if not found, or EINVAL if buffer is bad - * NOTE: Req_Name and Next_Name must be declared by caller with have length MAX_NAME_LEN or larger - * Nodes and AllowGroups must be declared by caller with length of FEATURE_SIZE or larger + * max_time, etc. - pointers into which the information is to be stored + * output: req_name - the partition's name is stored here + * next_name - the name of the next partition in the list is stored here + * max_time, etc. - the partition's state information + * returns 0 on success, ENOENT if not found, or EINVAL if buffer is bad + * NOTE: req_name and next_name must be declared by caller with have length MAX_NAME_LEN or larger. + * nodes and allow_groups must be declared by caller with length of FEATURE_SIZE or larger. + * NOTE: buffer is loaded by load_part and free by free_part_info. */ -int Load_Part_Name(char *Req_Name, char *Next_Name, int *MaxTime, int *MaxNodes, - int *TotalNodes, int *TotalCPUs, int *Key, int *StateUp, int *Shared, int *Default, - char *Nodes, char *AllowGroups) { - int i, Error_Code, Version, Buffer_Offset; - static time_t Last_Update_Time, Update_Time; - struct Part_Record My_Part; - static char Next_Name_Value[MAX_NAME_LEN]; - char My_Part_Name[MAX_NAME_LEN], My_Key[MAX_NAME_LEN], My_Default[MAX_NAME_LEN]; - char My_Shared[MAX_NAME_LEN], My_State[MAX_NAME_LEN], *My_Line; - static Last_Buffer_Offset; - unsigned long My_Time; +int +load_part_name (char *req_name, char *next_name, int *max_time, + int *max_nodes, int *total_nodes, int *total_cpus, int *key, + int *state_up, int *shared, int *default_flag, char *nodes, + char *allow_groups) { + int i, error_code, version, buffer_offset; + static time_t last_update_time, update_time; + struct part_record my_part; + static char next_name_value[MAX_NAME_LEN]; + char my_part_name[MAX_NAME_LEN], my_key[MAX_NAME_LEN], + my_default[MAX_NAME_LEN]; + char my_shared[MAX_NAME_LEN], my_state[MAX_NAME_LEN], *my_line; + static last_buffer_offset; + unsigned long my_time; - /* Load buffer's header (data structure version and time) */ - Buffer_Offset = 0; - Error_Code = Read_Buffer(Part_API_Buffer, &Buffer_Offset, Part_API_Buffer_Size, &My_Line); - if (Error_Code) return Error_Code; - sscanf(My_Line, HEAD_FORMAT, &My_Time, &Version); - Update_Time = (time_t) My_Time; + /* load buffer's header (data structure version and time) */ + buffer_offset = 0; + error_code = + read_buffer (part_api_buffer, &buffer_offset, + part_api_buffer_size, &my_line); + if (error_code) + return error_code; + sscanf (my_line, HEAD_FORMAT, &my_time, &version); + update_time = (time_t) my_time; - if ((Update_Time == Last_Update_Time) && (strcmp(Req_Name,Next_Name_Value) == 0) && - (strlen(Req_Name) != 0)) Buffer_Offset=Last_Buffer_Offset; - Last_Update_Time = Update_Time; + if ((update_time == last_update_time) + && (strcmp (req_name, next_name_value) == 0) + && (strlen (req_name) != 0)) + buffer_offset = last_buffer_offset; + last_update_time = update_time; - while (1) { - /* Load all info for next partition */ - Error_Code = Read_Buffer(Part_API_Buffer, &Buffer_Offset, Part_API_Buffer_Size, &My_Line); - if (Error_Code == EFAULT) break; /* End of buffer */ - if (Error_Code) return Error_Code; + while (1) { + /* load all info for next partition */ + error_code = + read_buffer (part_api_buffer, &buffer_offset, + part_api_buffer_size, &my_line); + if (error_code == EFAULT) + break; /* end of buffer */ + if (error_code) + return error_code; - sscanf(My_Line, PART_STRUCT_FORMAT, - My_Part_Name, - &My_Part.MaxNodes, - &My_Part.MaxTime, - Nodes, - My_Key, - My_Default, - AllowGroups, - My_Shared, - My_State, - &My_Part.TotalNodes, - &My_Part.TotalCPUs); + sscanf (my_line, PART_STRUCT_FORMAT, + my_part_name, + &my_part.max_nodes, + &my_part.max_time, + nodes, + my_key, + my_default, + allow_groups, + my_shared, + my_state, &my_part.total_nodes, &my_part.total_cpus); - if (strlen(Req_Name) == 0) strcpy(Req_Name, My_Part_Name); + if (strlen (req_name) == 0) + strcpy (req_name, my_part_name); - /* Check if this is requested partition */ - if (strcmp(Req_Name, My_Part_Name) != 0) continue; + /* check if this is requested partition */ + if (strcmp (req_name, my_part_name) != 0) + continue; - /*Load values to be returned */ - *MaxTime = My_Part.MaxTime; - *MaxNodes = My_Part.MaxNodes; - *TotalNodes = My_Part.TotalNodes; - *TotalCPUs = My_Part.TotalCPUs; - if (strcmp(My_Key, "YES") == 0) - *Key = 1; - else - *Key = 0; - if (strcmp(My_Default, "YES") == 0) - *Default = 1; - else - *Default = 0; - if (strcmp(My_State, "UP") == 0) - *StateUp = 1; - else - *StateUp = 0; - if (strcmp(My_Shared, "YES") == 0) - *Shared = 1; - else - *Shared = 0; + /*load values to be returned */ + *max_time = my_part.max_time; + *max_nodes = my_part.max_nodes; + *total_nodes = my_part.total_nodes; + *total_cpus = my_part.total_cpus; + if (strcmp (my_key, "YES") == 0) + *key = 1; + else + *key = 0; + if (strcmp (my_default, "YES") == 0) + *default_flag = 1; + else + *default_flag = 0; + if (strcmp (my_state, "UP") == 0) + *state_up = 1; + else + *state_up = 0; + if (strcmp (my_shared, "YES") == 0) + *shared = 1; + else if (strcmp (my_shared, "NO") == 0) + *shared = 0; + else /* FORCE */ + *shared = 2; - Last_Buffer_Offset = Buffer_Offset; - Error_Code = Read_Buffer(Part_API_Buffer, &Buffer_Offset, Part_API_Buffer_Size, &My_Line); - if (Error_Code) { /* No more records */ - strcpy(Next_Name_Value, ""); - strcpy(Next_Name, ""); - } else { - sscanf(My_Line, "PartitionName=%s", My_Part_Name); - strncpy(Next_Name_Value, My_Part_Name, MAX_NAME_LEN); - strncpy(Next_Name, My_Part_Name, MAX_NAME_LEN); - } /* else */ - return 0; - } /* while */ - return ENOENT; -} /* Load_Part_Name */ + last_buffer_offset = buffer_offset; + error_code = + read_buffer (part_api_buffer, &buffer_offset, + part_api_buffer_size, &my_line); + if (error_code) { /* no more records */ + strcpy (next_name_value, ""); + strcpy (next_name, ""); + } + else { + sscanf (my_line, "PartitionName=%s", my_part_name); + strncpy (next_name_value, my_part_name, MAX_NAME_LEN); + strncpy (next_name, my_part_name, MAX_NAME_LEN); + } /* else */ + return 0; + } + return ENOENT; +} diff --git a/src/api/reconfigure.c b/src/api/reconfigure.c index 12f9babb92bd85d94d9d079135535e7d4544f6bd..f1bd880e6dd308301e824d91d1a11d1d58a29ca2 100644 --- a/src/api/reconfigure.c +++ b/src/api/reconfigure.c @@ -1,12 +1,10 @@ /* - * reconfigure.c - Request that slurmctld re-read the configuration files + * reconfigure.c - request that slurmctld re-read the configuration files * - * Author: Moe Jette, jette@llnl.gov + * author: moe jette, jette@llnl.gov */ -#define PROTOTYPE_API 1 - -#ifdef HAVE_CONFIG_H +#ifdef have_config_h # include <config.h> #endif @@ -23,71 +21,78 @@ #if DEBUG_MODULE /* main is used here for module testing purposes only */ -main(int argc, char * argv[]) { - int i, count, Error_Code; +main (int argc, char *argv[]) { + int i, count, error_code; - if (argc < 2) - count = 1; - else - count = atoi(argv[1]); + if (argc < 2) + count = 1; + else + count = atoi (argv[1]); - for (i=0; i<count; i++) { - Error_Code = Reconfigure(); - if (Error_Code != 0) printf("Reconfigure error %d\n", Error_Code); - } - exit(0); -} /* main */ + for (i = 0; i < count; i++) { + error_code = reconfigure (); + if (error_code != 0) + printf ("reconfigure error %d\n", error_code); + } + exit (0); +} #endif /* - * Reconfigure - _ Request that slurmctld re-read the configuration files - * Output: Returns 0 on success, errno otherwise + * reconfigure - _ request that slurmctld re-read the configuration files + * output: returns 0 on success, errno otherwise */ -int Reconfigure() { - int Buffer_Offset, Buffer_Size, Error_Code, In_Size, Version; - char Request_Msg[64], *Buffer, *My_Line; - int sockfd; - struct sockaddr_in serv_addr; - unsigned long My_Time; - - if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) return EINVAL; - serv_addr.sin_family = PF_INET; - serv_addr.sin_addr.s_addr = inet_addr(SLURMCTLD_HOST); - serv_addr.sin_port = htons(SLURMCTLD_PORT); - if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { - close(sockfd); - return EINVAL; - } /* if */ - sprintf(Request_Msg, "Reconfigure"); - if (send(sockfd, Request_Msg, strlen(Request_Msg)+1, 0) < strlen(Request_Msg)) { - close(sockfd); - return EINVAL; - } /* if */ - Buffer = NULL; - Buffer_Offset = 0; - Buffer_Size = 1024; - while (1) { - Buffer = realloc(Buffer, Buffer_Size); - if (Buffer == NULL) { - close(sockfd); - return ENOMEM; - } /* if */ - In_Size = recv(sockfd, &Buffer[Buffer_Offset], (Buffer_Size-Buffer_Offset), 0); - if (In_Size <= 0) { /* End if input */ - In_Size = 0; - break; - } /* if */ - Buffer_Offset += In_Size; - Buffer_Size += In_Size; - } /* while */ - close(sockfd); - Buffer_Size = Buffer_Offset + In_Size; - Buffer = realloc(Buffer, Buffer_Size); - if (Buffer == NULL) return ENOMEM; - Error_Code = atoi(Buffer); - free(Buffer); - return Error_Code; -} /* Reconfigure */ - +int +reconfigure () { + int buffer_offset, buffer_size, error_code, in_size, version; + char request_msg[64], *buffer, *my_line; + int sockfd; + struct sockaddr_in serv_addr; + unsigned long my_time; + if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) < 0) + return EINVAL; + serv_addr.sin_family = PF_INET; + serv_addr.sin_addr.s_addr = inet_addr (SLURMCTLD_HOST); + serv_addr.sin_port = htons (SLURMCTLD_PORT); + if (connect + (sockfd, (struct sockaddr *) &serv_addr, + sizeof (serv_addr)) < 0) { + close (sockfd); + return EINVAL; + } + sprintf (request_msg, "Reconfigure"); + if (send (sockfd, request_msg, strlen (request_msg) + 1, 0) < + strlen (request_msg)) { + close (sockfd); + return EINVAL; + } + buffer = NULL; + buffer_offset = 0; + buffer_size = 1024; + while (1) { + buffer = realloc (buffer, buffer_size); + if (buffer == NULL) { + close (sockfd); + return ENOMEM; + } + in_size = + recv (sockfd, &buffer[buffer_offset], + (buffer_size - buffer_offset), 0); + if (in_size <= 0) { /* end if input */ + in_size = 0; + break; + } + buffer_offset += in_size; + buffer_size += in_size; + } + close (sockfd); + buffer_size = buffer_offset + in_size; + buffer = realloc (buffer, buffer_size); + if (buffer == NULL) + return ENOMEM; + error_code = atoi (buffer); + free (buffer); + return error_code; +} diff --git a/src/api/update_config b/src/api/update_config index 3adbd752fb1c05d683936028d52b054db214e416..950fb2005130aba015342f980b9560aff2a81a0c 100755 Binary files a/src/api/update_config and b/src/api/update_config differ diff --git a/src/common/bits_bytes.c b/src/common/bits_bytes.c index 2f6414b8c9da7bb86e56f1aca77621fe7ae02d4e..3870b33f9a8a051571d8453cd584ebc2633de0fb 100644 --- a/src/common/bits_bytes.c +++ b/src/common/bits_bytes.c @@ -1,13 +1,13 @@ /* - * bits_bytes.c - Tools for manipulating bitmaps and strings - * See slurm.h for documentation on external functions and data structures + * bits_bytes.c - tools for manipulating bitmaps and strings + * see slurm.h for documentation on external functions and data structures * - * Author: Moe Jette, jette@llnl.gov + * author: moe jette, jette@llnl.gov */ #define DEBUG_SYSTEM 1 -#ifdef HAVE_CONFIG_H +#ifdef have_config_h # include <config.h> #endif @@ -22,767 +22,883 @@ #define BUF_SIZE 1024 #define SEPCHARS " \n\t" -/* Tag fields of data structures dumped to API (jobs, partitions, nodes, etc.) */ -/* This is useful for API debugging, especially when changing formats */ -#define TAG_SIZE 8 -int Node_Record_Count = 0; /* Count of records in the Node Record Table */ +int node_record_count = 0; /* count of records in the node record table */ #if DEBUG_MODULE /* main is used here for module testing purposes only */ -main(int argc, char * argv[]) { - char In_Line[128]; - char *Out_Line; - int Error_Code, Int_Found, i, size; - char *String_Found; - unsigned *Map1, *Map2, *Map3; - char *Buffer, *Format; - int Buffer_Offset, Buffer_Size; - int Start_Inx, End_Inx, Count_Inx; - - printf("Testing string manipulation functions...\n"); - strcpy(In_Line, "Test1=UNLIMITED Test2=1234 Test3 LeftOver Test4=My,String"); - - Error_Code = Load_Integer(&Int_Found, "Test1=", In_Line); - if (Error_Code) printf("Load_Integer error on Test1\n"); - if (Int_Found != -1) - printf("Load_Integer parse error on Test1, got %d\n", Int_Found); - - Error_Code = Load_Integer(&Int_Found, "Test2=", In_Line); - if (Error_Code) printf("Load_Integer error on Test2\n"); - if (Int_Found != 1234) - printf("Load_Integer parse error on Test2, got %d\n", Int_Found); - - Error_Code = Load_Integer(&Int_Found, "Test3", In_Line); - if (Error_Code) printf("Load_Integer error on Test3\n"); - if (Int_Found != 1) - printf("Load_Integer parse error on Test3, got %d\n", Int_Found); - - String_Found = NULL; /* NOTE: arg1 of Load_String is freed if set */ - Error_Code = Load_String(&String_Found, "Test4=", In_Line); - if (Error_Code) printf("Load_String error on Test4\n"); - if (strcmp(String_Found,"My,String") != 0) - printf("Load_String parse error on Test4, got :%s:\n",String_Found); - free(String_Found); - - printf("NOTE: We expect this to print \"Leftover\"\n"); - Report_Leftover(In_Line, 0); - - printf("\n\nTesting bitmap manipulation functions...\n"); - Node_Record_Count = 97; - size = (Node_Record_Count + (sizeof(unsigned)*8) - 1) / (sizeof(unsigned)*8); - size *= (sizeof(unsigned)*8); - Map1 = malloc(size); - memset(Map1, 0, size); - BitMapSet(Map1, 23); - BitMapSet(Map1, 71); - Out_Line = BitMapPrint(Map1); - printf("BitMapPrint #1 Map1 shows %s\n", Out_Line); - free(Out_Line); - Map2 = BitMapCopy(Map1); - Out_Line = BitMapPrint(Map2); - printf("BitMapPrint #2 Map2 shows %s\n", Out_Line); - free(Out_Line); - Map3 = BitMapCopy(Map1); - BitMapClear(Map2, 23); - if (BitMapIsSuper(Map2,Map1) != 1) printf("ERROR: BitMapIsSuper error 1\n"); - if (BitMapIsSuper(Map1,Map2) != 0) printf("ERROR: BitMapIsSuper error 2\n"); - BitMapOR(Map3, Map2); - if (BitMapValue(Map3, 23) != 1) printf("ERROR: BitMapOR error 1\n"); - if (BitMapValue(Map3, 71) != 1) printf("ERROR: BitMapOR error 2\n"); - if (BitMapValue(Map3, 93) != 0) printf("ERROR: BitMapOR error 3\n"); - BitMapAND(Map3, Map2); - if (BitMapValue(Map3, 23) != 0) printf("ERROR: BitMapAND error 1\n"); - if (BitMapValue(Map3, 71) != 1) printf("ERROR: BitMapAND error 2\n"); - if (BitMapValue(Map3, 93) != 0) printf("ERROR: BitMapAND error 3\n"); - Out_Line = BitMapPrint(Map3); - printf("BitMapPrint #3 Map3 shows %s\n", Out_Line); - free(Out_Line); - - BitMapFill(Map1); - Out_Line = BitMapPrint(Map1); - if (BitMapValue(Map1, 34) != 1) printf("ERROR: BitMapFill error 1\n"); - printf("BitMapPrint #4 Map1 shows %s\n", Out_Line); - free(Out_Line); - - memset(Map1, 0, size); - for (i=0; i<10; i++) { - BitMapSet(Map1, (i+35)); - if (i>0) BitMapSet(Map1, (i+65)); - } /* for */ - Out_Line = BitMapPrint(Map1); - printf("BitMapPrint #6 Map1 shows %s\n", Out_Line); - size = BitMapCount(Map1); - if (size != 19) printf("ERROR: BitMapCount error, %d\n", size); - - printf("\n\nTesting buffer I/O functions...\n"); - Buffer = NULL; - Buffer_Offset = Buffer_Size= 0; - Error_Code = Write_Buffer(&Buffer, &Buffer_Offset, &Buffer_Size, "Val1\n"); - if (Error_Code) printf("Write_Buffer error on Test1\n"); - Error_Code = Write_Buffer(&Buffer, &Buffer_Offset, &Buffer_Size, "Val2\n"); - if (Error_Code) printf("Write_Buffer error on Test2\n"); - Buffer_Offset = 0; - Error_Code = Read_Buffer(Buffer, &Buffer_Offset, Buffer_Size, &Out_Line); - if (Error_Code) printf("Read_Buffer error on Test1\n"); - if (strcmp(Out_Line,"Val1\n") != 0) printf("Read_Buffer error on Test2\n"); - Error_Code = Read_Buffer(Buffer, &Buffer_Offset, Buffer_Size, &Out_Line); - if (Error_Code) printf("Read_Buffer error on Test3\n"); - if (strcmp(Out_Line,"Val2\n") != 0) printf("Read_Buffer error on Test4\n"); - - /* Check node name parsing */ - Out_Line = "linux[003-234]"; - Error_Code = Parse_Node_Name(Out_Line, &Format, &Start_Inx, &End_Inx, &Count_Inx); - if (Error_Code != 0) - printf("ERROR: Parse_Node_Name error %d\n", Error_Code); - else { - if ((Start_Inx != 3) || (End_Inx != 234)) printf("ERROR: Parse_Node_Name failure\n"); - printf("Parse_Node_Name of \"%s\" produces format \"%s\", %d to %d, %d records\n", - Out_Line, Format, Start_Inx, End_Inx, Count_Inx); - if (Format) free(Format); - } /* else */ - - exit(0); -} /* main */ +main (int argc, char *argv[]) { + char in_line[128]; + char *out_line; + int error_code, int_found, i, size; + char *string_found; + unsigned *map1, *map2, *map3; + char *buffer, *format; + int buffer_offset, buffer_size; + int start_inx, end_inx, count_inx; + + printf ("testing string manipulation functions...\n"); + strcpy (in_line, + "test1=UNLIMITED test2=1234 test3 left_over test4=my,string"); + + error_code = load_integer (&int_found, "test1=", in_line); + if (error_code) + printf ("load_integer error on test1\n"); + if (int_found != -1) + printf ("load_integer parse error on test1, got %d\n", + int_found); + + error_code = load_integer (&int_found, "test2=", in_line); + if (error_code) + printf ("load_integer error on test2\n"); + if (int_found != 1234) + printf ("load_integer parse error on test2, got %d\n", + int_found); + + error_code = load_integer (&int_found, "test3", in_line); + if (error_code) + printf ("load_integer error on test3\n"); + if (int_found != 1) + printf ("load_integer parse error on test3, got %d\n", + int_found); + + string_found = NULL; /* NOTE: arg1 of load_string is freed if set */ + error_code = load_string (&string_found, "test4=", in_line); + if (error_code) + printf ("load_string error on test4\n"); + if (strcmp (string_found, "my,string") != 0) + printf ("load_string parse error on test4, got :%s:\n", + string_found); + free (string_found); + + printf ("NOTE: we expect this to print \"leftover\"\n"); + report_leftover (in_line, 0); + + printf ("\n\n_testing bitmap manipulation functions...\n"); + node_record_count = 97; + size = (node_record_count + (sizeof (unsigned) * 8) - + 1) / (sizeof (unsigned) * 8); + size *= (sizeof (unsigned) * 8); + map1 = malloc (size); + memset (map1, 0, size); + bitmap_set (map1, 23); + bitmap_set (map1, 71); + out_line = bitmap_print (map1); + printf ("bitmap_print #1 map1 shows %s\n", out_line); + free (out_line); + map2 = bitmap_copy (map1); + out_line = bitmap_print (map2); + printf ("bitmap_print #2 map2 shows %s\n", out_line); + free (out_line); + map3 = bitmap_copy (map1); + bitmap_clear (map2, 23); + if (bitmap_is_super (map2, map1) != 1) + printf ("error: bitmap_is_super error 1\n"); + if (bitmap_is_super (map1, map2) != 0) + printf ("error: bitmap_is_super error 2\n"); + bitmap_or (map3, map2); + if (bitmap_value (map3, 23) != 1) + printf ("error: bitmap_or error 1\n"); + if (bitmap_value (map3, 71) != 1) + printf ("error: bitmap_or error 2\n"); + if (bitmap_value (map3, 93) != 0) + printf ("error: bitmap_or error 3\n"); + bitmap_and (map3, map2); + if (bitmap_value (map3, 23) != 0) + printf ("error: bitmap_and error 1\n"); + if (bitmap_value (map3, 71) != 1) + printf ("error: bitmap_and error 2\n"); + if (bitmap_value (map3, 93) != 0) + printf ("error: bitmap_and error 3\n"); + out_line = bitmap_print (map3); + printf ("bitmap_print #3 map3 shows %s\n", out_line); + free (out_line); + + bitmap_fill (map1); + out_line = bitmap_print (map1); + if (bitmap_value (map1, 34) != 1) + printf ("error: bitmap_fill error 1\n"); + printf ("bitmap_print #4 map1 shows %s\n", out_line); + free (out_line); + + memset (map1, 0, size); + for (i = 0; i < 10; i++) { + bitmap_set (map1, (i + 35)); + if (i > 0) + bitmap_set (map1, (i + 65)); + } + out_line = bitmap_print (map1); + printf ("bitmap_print #6 map1 shows %s\n", out_line); + size = bitmap_count (map1); + if (size != 19) + printf ("error: bitmap_count error, %d\n", size); + + printf ("\n\n_testing buffer i/o functions...\n"); + buffer = NULL; + buffer_offset = buffer_size = 0; + error_code = + write_buffer (&buffer, &buffer_offset, &buffer_size, + "val1\n"); + if (error_code) + printf ("write_buffer error on test1\n"); + error_code = + write_buffer (&buffer, &buffer_offset, &buffer_size, + "val2\n"); + if (error_code) + printf ("write_buffer error on test2\n"); + buffer_offset = 0; + error_code = + read_buffer (buffer, &buffer_offset, buffer_size, &out_line); + if (error_code) + printf ("read_buffer error on test1\n"); + if (strcmp (out_line, "val1\n") != 0) + printf ("read_buffer error on test2\n"); + error_code = + read_buffer (buffer, &buffer_offset, buffer_size, &out_line); + if (error_code) + printf ("read_buffer error on test3\n"); + if (strcmp (out_line, "val2\n") != 0) + printf ("read_buffer error on test4\n"); + + /* check node name parsing */ + out_line = "linux[003-234]"; + error_code = + parse_node_name (out_line, &format, &start_inx, &end_inx, + &count_inx); + if (error_code != 0) + printf ("error: parse_node_name error %d\n", error_code); + else { + if ((start_inx != 3) || (end_inx != 234)) + printf ("error: parse_node_name failure\n"); + printf ("parse_node_name of \"%s\" produces format \"%s\", %d to %d, %d records\n", out_line, format, start_inx, end_inx, count_inx); + if (format) + free (format); + } + + exit (0); +} #endif /* - * BitMapAND - AND two bitmaps together - * Input: BitMap1 and BitMap2 - The bitmaps to AND - * Output: BitMap1 is set to the value of BitMap1 & BitMap2 + * bitmap_and - and two bitmaps together + * input: bitmap1 and bitmap2 - the bitmaps to and + * output: bitmap1 is set to the value of bitmap1 & bitmap2 */ -void BitMapAND(unsigned *BitMap1, unsigned *BitMap2) { - int i, size; +void bitmap_and (unsigned *bitmap1, unsigned *bitmap2) { + int i, size; - if ((BitMap1 == NULL) || (BitMap2 == NULL)) { + if ((bitmap1 == NULL) || (bitmap2 == NULL)) { #if DEBUG_SYSTEM - fprintf(stderr, "BitMapAND: BitMap pointer is NULL\n"); + fprintf (stderr, "bitmap_and: bitmap pointer is NULL\n"); #else - syslog(LOG_ALERT, "BitMapAND: BitMap pointer is NULL\n"); + syslog (log_alert, "bitmap_and: bitmap pointer is NULL\n"); #endif - abort(); - } /* if */ + abort (); + } - size = (Node_Record_Count + (sizeof(unsigned)*8) - 1) / (sizeof(unsigned)*8); - for (i=0; i<size; i++) { - BitMap1[i] &= BitMap2[i]; - } /* for (i */ -} /* BitMapAND */ + size = (node_record_count + (sizeof (unsigned) * 8) - + 1) / (sizeof (unsigned) * 8); + for (i = 0; i < size; i++) { + bitmap1[i] &= bitmap2[i]; + } +} /* - * BitMapClear - Clear the specified bit in the specified bitmap - * Input: BitMap - The bit map to manipulate - * Position - Postition to clear - * Output: BitMap - Updated value + * bitmap_clear - clear the specified bit in the specified bitmap + * input: bitmap - the bit map to manipulate + * position - postition to clear + * output: bitmap - updated value */ -void BitMapClear(unsigned *BitMap, int Position) { - int val, bit; - unsigned mask; +void bitmap_clear (unsigned *bitmap, int position) { + int val, bit; + unsigned mask; - if (BitMap == NULL) { + if (bitmap == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "BitMapClear: BitMap pointer is NULL\n"); + fprintf (stderr, "bitmap_clear: bitmap pointer is NULL\n"); #else - syslog(LOG_ALERT, "BitMapClear: BitMap pointer is NULL\n"); + syslog (log_alert, "bitmap_clear: bitmap pointer is NULL\n"); #endif - abort(); - } /* if */ + abort (); + } - val = Position / (sizeof(unsigned)*8); - bit = Position % (sizeof(unsigned)*8); - mask = ~(0x1 << ((sizeof(unsigned)*8)-1-bit)); + val = position / (sizeof (unsigned) * 8); + bit = position % (sizeof (unsigned) * 8); + mask = ~(0x1 << ((sizeof (unsigned) * 8) - 1 - bit)); - BitMap[val] &= mask; -} /* BitMapClear */ + bitmap[val] &= mask; +} /* - * BitMapCopy - Create a copy of a bitmap - * Input: BitMap - The bitmap create a copy of - * Output: Returns pointer to copy of BitMap or NULL if error (no memory) - * NOTE: The returned value MUST BE FREED by the calling routine + * bitmap_copy - create a copy of a bitmap + * input: bitmap - the bitmap create a copy of + * output: returns pointer to copy of bitmap or NULL if error (no memory) + * NOTE: the returned value must be freed by the calling routine */ -unsigned *BitMapCopy(unsigned *BitMap) { - int size; - unsigned *Output; +unsigned * bitmap_copy (unsigned *bitmap) { + int size; + unsigned *output; - if (BitMap == NULL) { + if (bitmap == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "BitMapCopy: BitMap pointer is NULL\n"); + fprintf (stderr, "bitmap_copy: bitmap pointer is NULL\n"); #else - syslog(LOG_ALERT, "BitMapCopy: BitMap pointer is NULL\n"); + syslog (log_alert, "bitmap_copy: bitmap pointer is NULL\n"); #endif - abort(); - } /* if */ + abort (); + } - size = (Node_Record_Count + (sizeof(unsigned)*8) - 1) / 8; /* Bytes */ - Output = malloc(size); - if (Output == NULL) { + size = (node_record_count + (sizeof (unsigned) * 8) - 1) / 8; /* bytes */ + output = malloc (size); + if (output == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "BitMapCopy: unable to allocate memory\n"); + fprintf (stderr, "bitmap_copy: unable to allocate memory\n"); #else - syslog(LOG_ALERT, "BitMapCopy: unable to allocate memory\n"); + syslog (log_alert, + "bitmap_copy: unable to allocate memory\n"); #endif - abort(); - } /* if */ + abort (); + } - (void) memcpy(Output, BitMap, size); - return Output; -} /* BitMapCopy */ + (void) memcpy (output, bitmap, size); + return output; +} /* - * BitMapCount - Return the count of set bits in the specified bitmap - * Input: BitMap - The bit map to get count from - * Output: Returns the count of set bits - * NOTE: This routine adapted from Linux 2.4.9 <linux/bitops.h>. + * bitmap_count - return the count of set bits in the specified bitmap + * input: bitmap - the bit map to get count from + * output: returns the count of set bits + * NOTE: this routine adapted from linux 2.4.9 <linux/bitops.h>. */ -int BitMapCount(unsigned *BitMap) { - int count, byte, size, word, res; - unsigned scan; +int bitmap_count (unsigned *bitmap) { + int count, byte, size, word, res; + unsigned scan; - if (BitMap == NULL) { + if (bitmap == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "BitMapCount: BitMap pointer is NULL\n"); + fprintf (stderr, "bitmap_count: bitmap pointer is NULL\n"); #else - syslog(LOG_ALERT, "BitMapCount: BitMap pointer is NULL\n"); + syslog (log_alert, "bitmap_count: bitmap pointer is NULL\n"); #endif - abort(); - } /* if */ - - count = 0; - size = (Node_Record_Count + (sizeof(unsigned)*8) - 1) / 8; /* Bytes */ - size /= sizeof(unsigned); /* Count of unsigned's */ - for (word=0; word<size; word++) { - if (sizeof(unsigned) == 4) { - res = (BitMap[word] & 0x55555555) + ((BitMap[word] >> 1) & 0x55555555); - res = (res & 0x33333333) + ((res >> 2) & 0x33333333); - res = (res & 0x0F0F0F0F) + ((res >> 4) & 0x0F0F0F0F); - res = (res & 0x00FF00FF) + ((res >> 8) & 0x00FF00FF); - res = (res & 0x0000FFFF) + ((res >> 16) & 0x0000FFFF); - count += res; - } else if (sizeof(unsigned) == 8) { - res = (BitMap[word] & 0x5555555555555555) + ((BitMap[word] >> 1) & 0x5555555555555555); - res = (res & 0x3333333333333333) + ((res >> 2) & 0x3333333333333333); - res = (res & 0x0F0F0F0F0F0F0F0F) + ((res >> 4) & 0x0F0F0F0F0F0F0F0F); - res = (res & 0x00FF00FF00FF00FF) + ((res >> 8) & 0x00FF00FF00FF00FF); - res = (res & 0x0000FFFF0000FFFF) + ((res >> 16) & 0x0000FFFF0000FFFF); - res = (res & 0x00000000FFFFFFFF) + - ((res >> sizeof(unsigned)*4) & 0x00000000FFFFFFFF); - count += res; - } else { - for (byte=0; byte<(sizeof(unsigned)*8); byte+=8) { - scan = BitMap[word] >> ((sizeof(unsigned)*8)-8-byte); - if (scan & 0x01) count++; - if (scan & 0x02) count++; - if (scan & 0x04) count++; - if (scan & 0x08) count++; - if (scan & 0x10) count++; - if (scan & 0x20) count++; - if (scan & 0x40) count++; - if (scan & 0x80) count++; - } /* for (byte */ - } /* else */ - } /* for (word */ - return count; -} /* BitMapCount */ + abort (); + } + + count = 0; + size = (node_record_count + (sizeof (unsigned) * 8) - 1) / 8; /* bytes */ + size /= sizeof (unsigned); /* count of unsigned's */ + for (word = 0; word < size; word++) { + if (sizeof (unsigned) == 4) { + res = (bitmap[word] & 0x55555555) + + ((bitmap[word] >> 1) & 0x55555555); + res = (res & 0x33333333) + ((res >> 2) & 0x33333333); + res = (res & 0x0f0f0f0f) + ((res >> 4) & 0x0f0f0f0f); + res = (res & 0x00ff00ff) + ((res >> 8) & 0x00ff00ff); + res = (res & 0x0000ffff) + ((res >> 16) & 0x0000ffff); + count += res; + } + else if (sizeof (unsigned) == 8) { + res = (bitmap[word] & 0x5555555555555555) + + ((bitmap[word] >> 1) & 0x5555555555555555); + res = (res & 0x3333333333333333) + + ((res >> 2) & 0x3333333333333333); + res = (res & 0x0f0f0f0f0f0f0f0f) + + ((res >> 4) & 0x0f0f0f0f0f0f0f0f); + res = (res & 0x00ff00ff00ff00ff) + + ((res >> 8) & 0x00ff00ff00ff00ff); + res = (res & 0x0000ffff0000ffff) + + ((res >> 16) & 0x0000ffff0000ffff); + res = (res & 0x00000000ffffffff) + + ((res >> sizeof (unsigned) * + 4) & 0x00000000ffffffff); + count += res; + } + else { + for (byte = 0; byte < (sizeof (unsigned) * 8); + byte += 8) { + scan = bitmap[word] >> + ((sizeof (unsigned) * 8) - 8 - byte); + if (scan & 0x01) + count++; + if (scan & 0x02) + count++; + if (scan & 0x04) + count++; + if (scan & 0x08) + count++; + if (scan & 0x10) + count++; + if (scan & 0x20) + count++; + if (scan & 0x40) + count++; + if (scan & 0x80) + count++; + } + } + } + return count; +} /* - * BitMapFill - Fill the provided bitmap so that all bits between the highest and lowest + * bitmap_fill - fill the provided bitmap so that all bits between the highest and lowest * previously set bits are also set (i.e fill in the gaps to make it contiguous) - * Input: BitMap - Pointer to the bit map to fill in - * Output: BitMap - The filled in bitmap + * input: bitmap - pointer to the bit map to fill in + * output: bitmap - the filled in bitmap */ -void BitMapFill(unsigned *BitMap) { - int bit, size, word; - int first, last, position, gap; - unsigned mask; +void bitmap_fill (unsigned *bitmap) { + int bit, size, word; + int first, last, position, gap; + unsigned mask; - if (BitMap == NULL) { + if (bitmap == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "BitMapFill: BitMap pointer is NULL\n"); + fprintf (stderr, "bitmap_fill: bitmap pointer is NULL\n"); #else - syslog(LOG_ALERT, "BitMapFill: BitMap pointer is NULL\n"); + syslog (log_alert, "bitmap_fill: bitmap pointer is NULL\n"); #endif - abort(); - } /* if */ - - first = last = position = gap = -1; - size = (Node_Record_Count + (sizeof(unsigned)*8) - 1) / 8; /* Bytes */ - size /= sizeof(unsigned); /* Count of unsigned's */ - for (word=0; word<size; word++) { - for (bit=0; bit<(sizeof(unsigned)*8); bit++) { - position++; - mask = (0x1 << ((sizeof(unsigned)*8)-1-bit)); - if (BitMap[word] & mask) { - if (first == -1) first=position; - if ((last != (position-1)) && (last != -1)) gap=1; - last = position; - } /* else */ - } /* for (bit */ - } /* for (word */ - - if (gap == -1) return; - - position = -1; - for (word=0; word<size; word++) { - for (bit=0; bit<(sizeof(unsigned)*8); bit++) { - position++; - if (position <= first) continue; - if (position >= last) continue; - mask = (0x1 << ((sizeof(unsigned)*8)-1-bit)); - BitMap[word] |= mask; - } /* for (bit */ - } /* for (word */ -} /* BitMapFill */ + abort (); + } + + first = last = position = gap = -1; + size = (node_record_count + (sizeof (unsigned) * 8) - 1) / 8; /* bytes */ + size /= sizeof (unsigned); /* count of unsigned's */ + for (word = 0; word < size; word++) { + for (bit = 0; bit < (sizeof (unsigned) * 8); bit++) { + position++; + mask = (0x1 << ((sizeof (unsigned) * 8) - 1 - bit)); + if (bitmap[word] & mask) { + if (first == -1) + first = position; + if ((last != (position - 1)) && (last != -1)) + gap = 1; + last = position; + } + } + } + + if (gap == -1) + return; + + position = -1; + for (word = 0; word < size; word++) { + for (bit = 0; bit < (sizeof (unsigned) * 8); bit++) { + position++; + if (position <= first) + continue; + if (position >= last) + continue; + mask = (0x1 << ((sizeof (unsigned) * 8) - 1 - bit)); + bitmap[word] |= mask; + } + } +} /* - * BitMapIsSuper - Report if one bitmap's contents are a superset of another - * Input: BitMap1 and BitMap2 - The bitmaps to compare - * Output: Return 1 if if all bits in BitMap1 are also in BitMap2, 0 otherwise + * bitmap_is_super - report if one bitmap's contents are a superset of another + * input: bitmap1 and bitmap2 - the bitmaps to compare + * output: return 1 if if all bits in bitmap1 are also in bitmap2, 0 otherwise */ -int BitMapIsSuper(unsigned *BitMap1, unsigned *BitMap2) { - int i, size; +int bitmap_is_super (unsigned *bitmap1, unsigned *bitmap2) { + int i, size; - if ((BitMap1 == NULL) || (BitMap2 == NULL)) { + if ((bitmap1 == NULL) || (bitmap2 == NULL)) { #if DEBUG_SYSTEM - fprintf(stderr, "BitMapOR: BitMap pointer is NULL\n"); + fprintf (stderr, "bitmap_or: bitmap pointer is NULL\n"); #else - syslog(LOG_ALERT, "BitMapOR: BitMap pointer is NULL\n"); + syslog (log_alert, "bitmap_or: bitmap pointer is NULL\n"); #endif - abort(); - } /* if */ - - size = (Node_Record_Count + (sizeof(unsigned)*8) - 1) / (sizeof(unsigned)*8); - for (i=0; i<size; i++) { - if (BitMap1[i] != (BitMap1[i] & BitMap2[i])) return 0; - } /* for (i */ - return 1; -} /* BitMapIsSuper */ + abort (); + } + + size = (node_record_count + (sizeof (unsigned) * 8) - + 1) / (sizeof (unsigned) * 8); + for (i = 0; i < size; i++) { + if (bitmap1[i] != (bitmap1[i] & bitmap2[i])) + return 0; + } + return 1; +} /* - * BitMapOR - OR two bitmaps together - * Input: BitMap1 and BitMap2 - The bitmaps to OR - * Output: BitMap1 is set to the value of BitMap1 | BitMap2 + * bitmap_or - or two bitmaps together + * input: bitmap1 and bitmap2 - the bitmaps to or + * output: bitmap1 is set to the value of bitmap1 | bitmap2 */ -void BitMapOR(unsigned *BitMap1, unsigned *BitMap2) { - int i, size; +void bitmap_or (unsigned *bitmap1, unsigned *bitmap2) { + int i, size; - if ((BitMap1 == NULL) || (BitMap2 == NULL)) { + if ((bitmap1 == NULL) || (bitmap2 == NULL)) { #if DEBUG_SYSTEM - fprintf(stderr, "BitMapOR: BitMap pointer is NULL\n"); + fprintf (stderr, "bitmap_or: bitmap pointer is NULL\n"); #else - syslog(LOG_ALERT, "BitMapOR: BitMap pointer is NULL\n"); + syslog (log_alert, "bitmap_or: bitmap pointer is NULL\n"); #endif - abort(); - } /* if */ + abort (); + } - size = (Node_Record_Count + (sizeof(unsigned)*8) - 1) / (sizeof(unsigned)*8); - for (i=0; i<size; i++) { - BitMap1[i] |= BitMap2[i]; - } /* for (i */ -} /* BitMapOR */ + size = (node_record_count + (sizeof (unsigned) * 8) - 1) / + (sizeof (unsigned) * 8); + for (i = 0; i < size; i++) { + bitmap1[i] |= bitmap2[i]; + } +} /* - * BitMapPrint - Convert the specified bitmap into a printable hexadecimal string - * Input: BitMap - The bit map to print - * Output: Returns a string - * NOTE: The returned string must be freed by the calling program + * bitmap_print - convert the specified bitmap into a printable hexadecimal string + * input: bitmap - the bit map to print + * output: returns a string + * NOTE: the returned string must be freed by the calling program */ -char *BitMapPrint(unsigned *BitMap) { - int i, j, k, size, nibbles; - char *Output, temp_str[2]; +char * bitmap_print (unsigned *bitmap) { + int i, j, k, size, nibbles; + char *output, temp_str[2]; - if (BitMap == NULL) { + if (bitmap == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "BitMapPrint: BitMap pointer is NULL\n"); + fprintf (stderr, "bitmap_print: bitmap pointer is NULL\n"); #else - syslog(LOG_ALERT, "BitMapPrint: BitMap pointer is NULL\n"); + syslog (log_alert, "bitmap_print: bitmap pointer is NULL\n"); #endif - abort(); - } /* if */ - - size = (Node_Record_Count + (sizeof(unsigned)*8) - 1) / (sizeof(unsigned)*8); - nibbles = (Node_Record_Count + 3) / 4; - Output = (char *)malloc(nibbles+3); - if (Output == NULL) { + abort (); + } + + size = (node_record_count + (sizeof (unsigned) * 8) - + 1) / (sizeof (unsigned) * 8); + nibbles = (node_record_count + 3) / 4; + output = (char *) malloc (nibbles + 3); + if (output == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "BitMapPrint: unable to allocate memory\n"); + fprintf (stderr, "bitmap_print: unable to allocate memory\n"); #else - syslog(LOG_ALERT, "BitMapPrint: unable to allocate memory\n"); + syslog (log_alert, + "bitmap_print: unable to allocate memory\n"); #endif - abort(); - } /* if */ - - strcpy(Output, "0x"); - k = 0; - for (i=0; i<size; i++) { /* Each unsigned */ - for (j=((sizeof(unsigned)*8)-4); j>=0; j-=4) { /* Each nibble */ - sprintf(temp_str, "%x", ((BitMap[i]>>j)&0xf)); - strcat(Output, temp_str); - k++; - if (k == nibbles) return Output; - } /* for (j */ - } /* for (i */ - return Output; -} /* BitMapPrint */ + abort (); + } + + strcpy (output, "0x"); + k = 0; + for (i = 0; i < size; i++) { /* each unsigned */ + for (j = ((sizeof (unsigned) * 8) - 4); j >= 0; j -= 4) { /* each nibble */ + sprintf (temp_str, "%x", ((bitmap[i] >> j) & 0xf)); + strcat (output, temp_str); + k++; + if (k == nibbles) + return output; + } + } + return output; +} /* - * BitMapSet - Set the specified bit in the specified bitmap - * Input: BitMap - The bit map to manipulate - * Position - Postition to set - * Output: BitMap - Updated value + * bitmap_set - set the specified bit in the specified bitmap + * input: bitmap - the bit map to manipulate + * position - postition to set + * output: bitmap - updated value */ -void BitMapSet(unsigned *BitMap, int Position) { - int val, bit; - unsigned mask; +void bitmap_set (unsigned *bitmap, int position) { + int val, bit; + unsigned mask; - if (BitMap == NULL) { + if (bitmap == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "BitMapSet: BitMap pointer is NULL\n"); + fprintf (stderr, "bitmap_set: bitmap pointer is NULL\n"); #else - syslog(LOG_ALERT, "BitMapSet: BitMap pointer is NULL\n"); + syslog (log_alert, "bitmap_set: bitmap pointer is NULL\n"); #endif - abort(); - } /* if */ + abort (); + } - val = Position / (sizeof(unsigned)*8); - bit = Position % (sizeof(unsigned)*8); - mask = (0x1 << ((sizeof(unsigned)*8)-1-bit)); + val = position / (sizeof (unsigned) * 8); + bit = position % (sizeof (unsigned) * 8); + mask = (0x1 << ((sizeof (unsigned) * 8) - 1 - bit)); - BitMap[val] |= mask; -} /* BitMapSet */ + bitmap[val] |= mask; +} /* - * BitMapValue - Return the value of specified bit in the specified bitmap - * Input: BitMap - The bit map to get value from - * Position - Postition to get - * Output: Normally returns the value 0 or 1 + * bitmap_value - return the value of specified bit in the specified bitmap + * input: bitmap - the bit map to get value from + * position - postition to get + * output: normally returns the value 0 or 1 */ -int BitMapValue(unsigned *BitMap, int Position) { - int val, bit; - unsigned mask; +int bitmap_value (unsigned *bitmap, int position) { + int val, bit; + unsigned mask; - if (BitMap == NULL) { + if (bitmap == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "BitMapValue: BitMap pointer is NULL\n"); + fprintf (stderr, "bitmap_value: bitmap pointer is NULL\n"); #else - syslog(LOG_ALERT, "BitMapValue: BitMap pointer is NULL\n"); + syslog (log_alert, "bitmap_value: bitmap pointer is NULL\n"); #endif - abort(); - } /* if */ + abort (); + } - val = Position / (sizeof(unsigned)*8); - bit = Position % (sizeof(unsigned)*8); - mask = (0x1 << ((sizeof(unsigned)*8)-1-bit)); + val = position / (sizeof (unsigned) * 8); + bit = position % (sizeof (unsigned) * 8); + mask = (0x1 << ((sizeof (unsigned) * 8) - 1 - bit)); - mask &= BitMap[val]; - if (mask == 0) - return 0; - else - return 1; -} /* BitMapValue */ + mask &= bitmap[val]; + if (mask == 0) + return 0; + else + return 1; +} /* - * Load_Integer - Parse a string for a keyword, value pair - * Input: *destination - Location into which result is stored - * keyword - String to search for - * In_Line - String to search for keyword - * Output: *destination - set to value, No change if value not found, - * Set to 1 if keyword found without value, - * Set to -1 if keyword followed by "UNLIMITED" - * In_Line - The keyword and value (if present) are overwritten by spaces + * load_integer - parse a string for a keyword, value pair + * input: *destination - location into which result is stored + * keyword - string to search for + * in_line - string to search for keyword + * output: *destination - set to value, no change if value not found, + * set to 1 if keyword found without value, + * set to -1 if keyword followed by "unlimited" + * in_line - the keyword and value (if present) are overwritten by spaces * return value - 0 if no error, otherwise an error code - * NOTE: In_Line is overwritten, DO NOT USE A CONSTANT + * NOTE: in_line is overwritten, do not use a constant */ -int Load_Integer(int *destination, char *keyword, char *In_Line) { - char Scratch[BUF_SIZE]; /* Scratch area for parsing the input line */ - char *str_ptr1, *str_ptr2, *str_ptr3; - int i, str_len1, str_len2; - - str_ptr1 = (char *)strstr(In_Line, keyword); - if (str_ptr1 != NULL) { - str_len1 = strlen(keyword); - strcpy(Scratch, str_ptr1+str_len1); - if ((Scratch[0] == (char)NULL) || - (isspace((int)Scratch[0]))) { /* Keyword with no value set */ - *destination = 1; - str_len2 = 0; - } else { - str_ptr2 = (char *)strtok_r(Scratch, SEPCHARS, &str_ptr3); - str_len2 = strlen(str_ptr2); - if (strcmp(str_ptr2, "UNLIMITED") == 0) - *destination = -1; - else if ((str_ptr2[0] >= '0') && (str_ptr2[0] <= '9')) { - *destination = (int) strtol(Scratch, (char **)NULL, 10); - } else { +int load_integer (int *destination, char *keyword, char *in_line) { + char scratch[BUF_SIZE]; /* scratch area for parsing the input line */ + char *str_ptr1, *str_ptr2, *str_ptr3; + int i, str_len1, str_len2; + + str_ptr1 = (char *) strstr (in_line, keyword); + if (str_ptr1 != NULL) { + str_len1 = strlen (keyword); + strcpy (scratch, str_ptr1 + str_len1); + if ((scratch[0] == (char) NULL) || + (isspace ((int) scratch[0]))) { /* keyword with no value set */ + *destination = 1; + str_len2 = 0; + } + else { + str_ptr2 = + (char *) strtok_r (scratch, SEPCHARS, + &str_ptr3); + str_len2 = strlen (str_ptr2); + if (strcmp (str_ptr2, "UNLIMITED") == 0) + *destination = -1; + else if ((str_ptr2[0] >= '0') && (str_ptr2[0] <= '9')) { + *destination = + (int) strtol (scratch, (char **) NULL, + 10); + } + else { #if DEBUG_SYSTEM - fprintf(stderr, "Load_Integer: bad value for keyword %s\n", keyword); + fprintf (stderr, + "load_integer: bad value for keyword %s\n", + keyword); #else - syslog(LOG_ERR, "Load_Integer: bad value for keyword %s\n", keyword); + syslog (log_err, + "load_integer: bad value for keyword %s\n", + keyword); #endif - return EINVAL; - } /* else */ - } /* else */ - - for (i=0; i<(str_len1+str_len2); i++) { - str_ptr1[i] = ' '; - } /* for */ - } /* if */ - return 0; -} /* Load_Integer */ + return EINVAL; + } + } + + for (i = 0; i < (str_len1 + str_len2); i++) { + str_ptr1[i] = ' '; + } + } + return 0; +} /* - * Load_String - Parse a string for a keyword, value pair - * Input: *destination - Location into which result is stored - * keyword - String to search for - * In_Line - String to search for keyword - * Output: *destination - set to value, No change if value not found, + * load_string - parse a string for a keyword, value pair + * input: *destination - location into which result is stored + * keyword - string to search for + * in_line - string to search for keyword + * output: *destination - set to value, no change if value not found, * if *destination had previous value, that memory location is automatically freed - * In_Line - The keyword and value (if present) are overwritten by spaces + * in_line - the keyword and value (if present) are overwritten by spaces * return value - 0 if no error, otherwise an error code * NOTE: destination must be free when no longer required * NOTE: if destination is non-NULL at function call time, it will be freed - * NOTE: In_Line is overwritten, DO NOT USE A CONSTANT + * NOTE: in_line is overwritten, do not use a constant */ -int Load_String(char **destination, char *keyword, char *In_Line) { - char Scratch[BUF_SIZE]; /* Scratch area for parsing the input line */ - char *str_ptr1, *str_ptr2, *str_ptr3; - int i, str_len1, str_len2; - - str_ptr1 = (char *)strstr(In_Line, keyword); - if (str_ptr1 != NULL) { - str_len1 = strlen(keyword); - strcpy(Scratch, str_ptr1+str_len1); - if ((Scratch[0] == (char)NULL) || - (isspace((int)Scratch[0]))) { /* Keyword with no value set */ +int load_string (char **destination, char *keyword, char *in_line) { + char scratch[BUF_SIZE]; /* scratch area for parsing the input line */ + char *str_ptr1, *str_ptr2, *str_ptr3; + int i, str_len1, str_len2; + + str_ptr1 = (char *) strstr (in_line, keyword); + if (str_ptr1 != NULL) { + str_len1 = strlen (keyword); + strcpy (scratch, str_ptr1 + str_len1); + if ((scratch[0] == (char) NULL) || + (isspace ((int) scratch[0]))) { /* keyword with no value set */ #if DEBUG_SYSTEM - fprintf(stderr, "Load_String: keyword %s lacks value\n", keyword); + fprintf (stderr, + "load_string: keyword %s lacks value\n", + keyword); #else - syslog(LOG_ERR, "Load_String: keyword %s lacks value\n", keyword); + syslog (log_err, + "load_string: keyword %s lacks value\n", + keyword); #endif - return EINVAL; - } /* if */ - str_ptr2 = (char *)strtok_r(Scratch, SEPCHARS, &str_ptr3); - str_len2 = strlen(str_ptr2); - if (destination[0] != NULL) free(destination[0]); - destination[0] = (char *)malloc(str_len2+1); - if (destination[0] == NULL) { + return EINVAL; + } + str_ptr2 = (char *) strtok_r (scratch, SEPCHARS, &str_ptr3); + str_len2 = strlen (str_ptr2); + if (destination[0] != NULL) + free (destination[0]); + destination[0] = (char *) malloc (str_len2 + 1); + if (destination[0] == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "Load_String: unable to allocate memory\n"); + fprintf (stderr, + "load_string: unable to allocate memory\n"); #else - syslog(LOG_ALERT, "Load_String: unable to allocate memory\n"); + syslog (log_alert, + "load_string: unable to allocate memory\n"); #endif - abort(); - } /* if */ - strcpy(destination[0], str_ptr2); - for (i=0; i<(str_len1+str_len2); i++) { - str_ptr1[i] = ' '; - } /* for */ - } /* if */ - return 0; -} /* Load_String */ + abort (); + } + strcpy (destination[0], str_ptr2); + for (i = 0; i < (str_len1 + str_len2); i++) { + str_ptr1[i] = ' '; + } + } + return 0; +} /* - * Parse_Node_Name - Parse the node name for regular expressions and return a sprintf format - * generate multiple node names as needed. - * Input: NodeName - Node name to parse - * Output: Format - sprintf format for generating names - * Start_Inx - First index to used - * End_Inx - Last index value to use - * Count_Inx - Number of index values to use (will be zero if none) + * parse_node_name - parse the node name for regular expressions and return a sprintf + * format generate multiple node names as needed. + * input: node_name - node name to parse + * output: format - sprintf format for generating names + * start_inx - first index to used + * end_inx - last index value to use + * count_inx - number of index values to use (will be zero if none) * return 0 if no error, error code otherwise - * NOTE: The calling program must execute free(Format) when the storage location is no longer needed + * NOTE: the calling program must execute free(format) when the storage location + * is no longer needed */ -int Parse_Node_Name(char *NodeName, char **Format, int *Start_Inx, int *End_Inx, int *Count_Inx) { - int Base, Format_Pos, Precision, i; - char Type[1]; - - i = strlen(NodeName); - Format[0] = (char *)malloc(i+1); - if (Format[0] == NULL) { +int parse_node_name (char *node_name, char **format, int *start_inx, int *end_inx, + int *count_inx) { + int base, format_pos, precision, i; + char type[1]; + + i = strlen (node_name); + format[0] = (char *) malloc (i + 1); + if (format[0] == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "Parse_Node_Name: unable to allocate memory\n"); + fprintf (stderr, + "parse_node_name: unable to allocate memory\n"); #else - syslog(LOG_ERR, "Parse_Node_Name: unable to allocate memory\n"); + syslog (log_err, + "parse_node_name: unable to allocate memory\n"); #endif - abort(); - } /* if */ - - *Start_Inx = 0; - *End_Inx = 0; - *Count_Inx = 0; - Format_Pos = 0; - Base = 0; - Format[0][Format_Pos] = (char)NULL; - i = 0; - while (1) { - if (NodeName[i] == (char)NULL) break; - if (NodeName[i] == '\\') { - if (NodeName[++i] == (char)NULL) break; - Format[0][Format_Pos++] = NodeName[i++]; - } else if (NodeName[i] == '[') { /* '[' preceeding number range */ - if (NodeName[++i] == (char)NULL) break; - if (Base != 0) { + abort (); + } + + *start_inx = 0; + *end_inx = 0; + *count_inx = 0; + format_pos = 0; + base = 0; + format[0][format_pos] = (char) NULL; + i = 0; + while (1) { + if (node_name[i] == (char) NULL) + break; + if (node_name[i] == '\\') { + if (node_name[++i] == (char) NULL) + break; + format[0][format_pos++] = node_name[i++]; + } + else if (node_name[i] == '[') { /* '[' preceeding number range */ + if (node_name[++i] == (char) NULL) + break; + if (base != 0) { #if DEBUG_SYSTEM - fprintf(stderr, "Parse_Node_Name: Invalid '[' in node name %s\n", NodeName); + fprintf (stderr, + "parse_node_name: invalid '[' in node name %s\n", + node_name); #else - syslog(LOG_ERR, "Parse_Node_Name: Invalid '[' in node name %s\n", NodeName); + syslog (log_err, + "parse_node_name: invalid '[' in node name %s\n", + node_name); #endif - free(Format[0]); - return EINVAL; - } /* if */ - if (NodeName[i] == 'o') { - Type[0] = NodeName[i++]; - Base = 8; - } else { - Type[0] = 'd'; - Base = 10; - } /* else */ - Precision = 0; - while (1) { - if ((NodeName[i] >= '0') && (NodeName[i] <= '9')) { - *Start_Inx = ((*Start_Inx) * Base) + (int)(NodeName[i++] - '0'); - Precision++; - continue; - } /* if */ - if (NodeName[i] == '-') { /* '-' between numbers */ - i++; - break; - } /* if */ + free (format[0]); + return EINVAL; + } + if (node_name[i] == 'o') { + type[0] = node_name[i++]; + base = 8; + } + else { + type[0] = 'd'; + base = 10; + } + precision = 0; + while (1) { + if ((node_name[i] >= '0') + && (node_name[i] <= '9')) { + *start_inx = + ((*start_inx) * base) + + (int) (node_name[i++] - '0'); + precision++; + continue; + } + if (node_name[i] == '-') { /* '-' between numbers */ + i++; + break; + } #if DEBUG_SYSTEM - fprintf(stderr, "Parse_Node_Name: Invalid '%c' in node name %s\n", - NodeName[i], NodeName); + fprintf (stderr, + "parse_node_name: invalid '%c' in node name %s\n", + node_name[i], node_name); #else - syslog(LOG_ERR, "Parse_Node_Name: Invalid '%c' in node name %s\n", - NodeName[i], NodeName); + syslog (log_err, + "parse_node_name: invalid '%c' in node name %s\n", + node_name[i], node_name); #endif - free(Format[0]); - return EINVAL; - } /* while */ - while (1) { - if ((NodeName[i] >= '0') && (NodeName[i] <= '9')) { - *End_Inx = ((*End_Inx) * Base) + (int)(NodeName[i++] - '0'); - continue; - } /* if */ - if (NodeName[i] == ']') { /* ']' terminating number range */ - i++; - break; - } /* if */ + free (format[0]); + return EINVAL; + } + while (1) { + if ((node_name[i] >= '0') + && (node_name[i] <= '9')) { + *end_inx = + ((*end_inx) * base) + + (int) (node_name[i++] - '0'); + continue; + } + if (node_name[i] == ']') { /* ']' terminating number range */ + i++; + break; + } #if DEBUG_SYSTEM - fprintf(stderr, "Parse_Node_Name: Invalid '%c' in node name %s\n", - NodeName[i], NodeName); + fprintf (stderr, + "parse_node_name: invalid '%c' in node name %s\n", + node_name[i], node_name); #else - syslog(LOG_ERR, "Parse_Node_Name: Invalid '%c' in node name %s\n", - NodeName[i], NodeName); + syslog (log_err, + "parse_node_name: invalid '%c' in node name %s\n", + node_name[i], node_name); #endif - free(Format[0]); - return EINVAL; - } /* while */ - *Count_Inx = (*End_Inx - *Start_Inx) + 1; - Format[0][Format_Pos++] = '%'; - Format[0][Format_Pos++] = '.'; - if (Precision > 9) Format[0][Format_Pos++] = '0' + (Precision/10); - Format[0][Format_Pos++] = '0' + (Precision%10); - Format[0][Format_Pos++] = Type[0]; - } else { - Format[0][Format_Pos++] = NodeName[i++]; - } /* else */ - } /* while */ - Format[0][Format_Pos] = (char)NULL; - return 0; -} /* Parse_Node_Name */ + free (format[0]); + return EINVAL; + } + *count_inx = (*end_inx - *start_inx) + 1; + format[0][format_pos++] = '%'; + format[0][format_pos++] = '.'; + if (precision > 9) + format[0][format_pos++] = + '0' + (precision / 10); + format[0][format_pos++] = '0' + (precision % 10); + format[0][format_pos++] = type[0]; + } + else { + format[0][format_pos++] = node_name[i++]; + } + } + format[0][format_pos] = (char) NULL; + return 0; +} /* - * Read_Buffer - Read a line from the specified buffer - * Input: Buffer - Pointer to read buffer, must be allocated by alloc() - * Buffer_Offset - Byte offset in Buffer, read location - * Buffer_Size - Byte size of Buffer - * Line - Pointer to location to be loaded with POINTER TO THE LINE - * Output: Buffer_Offset - Incremented by size of size plus the Value size itself - * Line - Set to pointer to the line - * Returns 0 if no error or EFAULT on end of buffer, EINVAL on bad tag + * read_buffer - read a line from the specified buffer + * input: buffer - pointer to read buffer, must be allocated by alloc() + * buffer_offset - byte offset in buffer, read location + * buffer_size - byte size of buffer + * line - pointer to location to be loaded with pointer to the line + * output: buffer_offset - incremented by size of size plus the value size itself + * line - set to pointer to the line + * returns 0 if no error or EFAULT on end of buffer, EINVAL on bad tag */ -int Read_Buffer(char *Buffer, int *Buffer_Offset, int Buffer_Size, char **Line) { - if ((*Buffer_Offset) >= Buffer_Size) return EFAULT; - Line[0] = &Buffer[*Buffer_Offset]; - (*Buffer_Offset) += (strlen(Line[0]) + 1); - - if ((*Buffer_Offset) > Buffer_Size) return EFAULT; - return 0; -} /* Read_Buffer */ +int read_buffer (char *buffer, int *buffer_offset, int buffer_size, char **line) { + if ((*buffer_offset) >= buffer_size) + return EFAULT; + line[0] = &buffer[*buffer_offset]; + (*buffer_offset) += (strlen (line[0]) + 1); + + if ((*buffer_offset) > buffer_size) + return EFAULT; + return 0; +} /* - * Report_Leftover - Report any un-parsed (non-whitespace) characters on the + * report_leftover - report any un-parsed (non-whitespace) characters on the * configuration input line. - * Input: In_Line - What is left of the configuration input line. - * Line_Num - Line number of the configuration file. - * Output: NONE + * input: in_line - what is left of the configuration input line. + * line_num - line number of the configuration file. + * output: none */ -void Report_Leftover(char *In_Line, int Line_Num) { - int Bad_Index, i; - - Bad_Index = -1; - for (i=0; i<strlen(In_Line); i++) { - if (isspace((int)In_Line[i]) || (In_Line[i] == '\n')) continue; - Bad_Index=i; - break; - } /* if */ - - if (Bad_Index == -1) return; +void report_leftover (char *in_line, int line_num) { + int bad_index, i; + + bad_index = -1; + for (i = 0; i < strlen (in_line); i++) { + if (isspace ((int) in_line[i]) || (in_line[i] == '\n')) + continue; + bad_index = i; + break; + } + + if (bad_index == -1) + return; #if DEBUG_SYSTEM - fprintf(stderr, "Report_Leftover: Ignored input on line %d of configuration: %s\n", - Line_Num, &In_Line[Bad_Index]); + fprintf (stderr, + "report_leftover: ignored input on line %d of configuration: %s\n", + line_num, &in_line[bad_index]); #else - syslog(LOG_ERR, "Report_Leftover: Ignored input on line %d of configuration: %s\n", - Line_Num, &In_Line[Bad_Index]); + syslog (log_err, + "report_leftover: ignored input on line %d of configuration: %s\n", + line_num, &in_line[bad_index]); #endif - return; -} /* Report_Leftover */ + return; +} /* - * Write_Buffer - Write the specified line to the specified buffer, + * write_buffer - write the specified line to the specified buffer, * enlarging the buffer as needed - * Input: Buffer - Pointer to write buffer, must be allocated by alloc() - * Buffer_Offset - Byte offset in Buffer, write location - * Buffer_Size - Byte size of Buffer - * Line - Pointer to data to be writen - * Output: Buffer - Value is written here, buffer may be relocated by realloc() - * Buffer_Offset - Incremented by Value_Size - * Returns 0 if no error or errno otherwise + * input: buffer - pointer to write buffer, must be allocated by alloc() + * buffer_offset - byte offset in buffer, write location + * buffer_size - byte size of buffer + * line - pointer to data to be writen + * output: buffer - value is written here, buffer may be relocated by realloc() + * buffer_offset - incremented by value_size + * returns 0 if no error or errno otherwise */ -int Write_Buffer(char **Buffer, int *Buffer_Offset, int *Buffer_Size, char *Line) { - int Line_Size; - - Line_Size = strlen(Line) + 1; - if ((*Buffer_Offset + Line_Size) >= *Buffer_Size) { - (*Buffer_Size) += Line_Size + 8096; - Buffer[0] = realloc(Buffer[0], *Buffer_Size); - if (Buffer[0] == NULL) { +int write_buffer (char **buffer, int *buffer_offset, int *buffer_size, char *line) { + int line_size; + + line_size = strlen (line) + 1; + if ((*buffer_offset + line_size) >= *buffer_size) { + (*buffer_size) += line_size + 8096; + buffer[0] = realloc (buffer[0], *buffer_size); + if (buffer[0] == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "Write_Buffer: unable to allocate memory\n"); + fprintf (stderr, + "write_buffer: unable to allocate memory\n"); #else - syslog(LOG_ALERT, "Write_Buffer: unable to allocate memory\n"); + syslog (log_alert, + "write_buffer: unable to allocate memory\n"); #endif - abort(); - } /* if */ - } /* if */ - - memcpy(Buffer[0]+(*Buffer_Offset), Line, Line_Size); - (*Buffer_Offset) += Line_Size; - return 0; -} /* Write_Buffer */ + abort (); + } + } + + memcpy (buffer[0] + (*buffer_offset), line, line_size); + (*buffer_offset) += line_size; + return 0; +} diff --git a/src/common/slurm.h b/src/common/slurm.h index 1841cb6d796b6a0499b3cc15af25c74c811aa06b..18727c702d848e5c200d91ee81a023d131f5ce58 100644 --- a/src/common/slurm.h +++ b/src/common/slurm.h @@ -1,16 +1,16 @@ /* - * slurm.h - Definitions for slurm API use + * slurm.h - definitions for slurm api use * - * Note: The job, node, and partition specifications are all of the + * NOTE: the job, node, and partition specifications are all of the * same basic format: - * If the first character of a line is "#" then it is a comment. - * Place all information for a single node, partition, or job on a + * if the first character of a line is "#" then it is a comment. + * place all information for a single node, partition, or job on a * single line. - * Space delimit collection of keywords and values and separate - * the keyword from value with an equal sign (e.g. "CPUs=3"). - * List entries should be comma separated (e.g. "Nodes=lx01,lx02"). + * space delimit collection of keywords and values and separate + * the keyword from value with an equal sign (e.g. "cpus=3"). + * list entries should be comma separated (e.g. "nodes=lx01,lx02"). * - * See the SLURM administrator guide for more details. + * see the slurm administrator guide for more details. */ #ifndef _HAVE_SLURM_H @@ -25,8 +25,8 @@ #define DEBUG_SYSTEM 1 #define BACKUP_INTERVAL 60 -#define BACKUP_LOCATION "/usr/local/SLURM/Slurm.State" -#define CONTROL_DAEMON "/usr/local/SLURM/Slurmd.Control" +#define BACKUP_LOCATION "/usr/local/slurm/slurm.state" +#define CONTROL_DAEMON "/usr/local/slurm/slurmd.control" #define CONTROLLER_TIMEOUT 300 #define EPILOG "" #define HASH_BASE 10 @@ -35,451 +35,458 @@ #define KILL_WAIT 30 #define PRIORITIZE "" #define PROLOG "" -#define SERVER_DAEMON "/usr/local/SLURM/Slurmd.Server" +#define SERVER_DAEMON "/usr/local/slurm/slurmd.server" #define SERVER_TIMEOUT 300 -#define SLURM_CONF "/g/g0/jette/slurm/etc/SLURM.conf2" +#define SLURM_CONF "/g/g0/jette/slurm/etc/slurm.conf2" #define TMP_FS "/tmp" -/* NOTE: Change BUILD_STRUCT_VERSION value whenever the contents of BUILD_STRUCT_FORMAT change */ +/* NOTE: change BUILD_STRUCT_VERSION value whenever the contents of BUILD_STRUCT_FORMAT change */ #define BUILD_STRUCT_VERSION 1 -#define HEAD_FORMAT "#Time=%lu Version=%d\n" +#define HEAD_FORMAT "#time=%lu version=%d\n" #define BUILD_STRUCT_FORMAT "%s %s\n" #define BUILD_STRUCT2_FORMAT "%s %d\n" -extern char *ControlMachine; /* Name of computer acting as SLURM controller */ -extern char *BackupController; /* Name of computer acting as SLURM backup controller */ +extern char *control_machine; /* name of computer acting as slurm controller */ +extern char *backup_controller; /* name of computer acting as slurm backup controller */ -/* NOTE: Change JOB_STRUCT_VERSION value whenever the contents of "struct Job_Record" - * change with respect to the API structures */ +/* NOTE: change JOB_STRUCT_VERSION value whenever the contents of "struct job_record" + * change with respect to the api structures */ #define JOB_STRUCT_VERSION 1 -struct Job_Record { - int Job_Id; - int User_Id; - int MaxTime; /* -1 if unlimited */ +struct job_record { + int job_id; + int user_id; + int max_time; /* -1 if unlimited */ }; -/* NOTE: Change NODE_STRUCT_VERSION value whenever the contents of NODE_STRUCT_FORMAT change */ +/* NOTE: change NODE_STRUCT_VERSION value whenever the contents of NODE_STRUCT_FORMAT change */ #define NODE_STRUCT_VERSION 1 -#define NODE_STRUCT_FORMAT "NodeName=%s State=%s CPUs=%d RealMemory=%d TmpDisk=%d Weight=%d Feature=%s #Partition=%s\n" -#define CONFIG_MAGIC 'C' -#define NODE_MAGIC 'N' -struct Config_Record { +#define NODE_STRUCT_FORMAT "NodeName=%s Atate=%s CPUs=%d RealMemory=%d TmpDisk=%d Weight=%d Feature=%s #Partition=%s\n" +#define CONFIG_MAGIC 'c' +#define NODE_MAGIC 'n' +struct config_record { #if DEBUG_SYSTEM - char Magic; /* Magic cookie to test data integrity */ + char magic; /* magic cookie to test data integrity */ #endif - int CPUs; /* Count of CPUs running on the node */ - int RealMemory; /* Megabytes of real memory on the node */ - int TmpDisk; /* Megabytes of total storage in TMP_FS file system */ - int Weight; /* Arbitrary priority of node for scheduling work on */ - char *Feature; /* Arbitrary list of features associated with a node */ - char *Nodes; /* Names of nodes in partition configuration record */ - unsigned *NodeBitMap; /* Bitmap of nodes in configuration record */ + int cpus; /* count of cpus running on the node */ + int real_memory; /* megabytes of real memory on the node */ + int tmp_disk; /* megabytes of total storage in TMP_FS file system */ + int weight; /* arbitrary priority of node for scheduling work on */ + char *feature; /* arbitrary list of features associated with a node */ + char *nodes; /* names of nodes in partition configuration record */ + unsigned *node_bitmap; /* bitmap of nodes in configuration record */ }; -extern List Config_List; /* List of Config_Record entries */ +extern List config_list; /* list of config_record entries */ -/* Last entry must be STATE_END, keep in sync with Node_State_String */ -/* Any value less than or equal to zero is down. If a node was in state */ +/* last entry must be STATE_END, keep in sync with node_state_string */ +/* any value less than or equal to zero is down. if a node was in state */ /* STATE_BUSY and stops responding, its state becomes -(STATE_BUSY), etc. */ -enum Node_State { - STATE_DOWN, /* Node is not responding */ - STATE_UNKNOWN, /* Node's initial state, unknown */ - STATE_IDLE, /* Node idle and available for use */ - STATE_STAGE_IN, /* Node has been allocated to a job, which has not yet begun execution */ - STATE_BUSY, /* Node allocated to a job and that job is actively running */ - STATE_STAGE_OUT, /* Node has been allocated to a job, which has completed execution */ - STATE_DRAINED, /* Node idle and not to be allocated future work */ - STATE_DRAINING, /* Node in use, but not to be allocated future work */ - STATE_END }; /* LAST ENTRY IN TABLE */ -/* Last entry must be "END", keep in sync with Node_State */ -extern char *Node_State_String[]; - -extern time_t Last_BitMap_Update; /* Time of last node creation or deletion */ -extern time_t Last_Node_Update; /* Time of last update to Node Records */ -struct Node_Record { +enum node_state { + STATE_DOWN, /* node is not responding */ + STATE_UNKNOWN, /* node's initial state, unknown */ + STATE_IDLE, /* node idle and available for use */ + STATE_STAGE_IN, /* node has been allocated to a job, which has not yet begun execution */ + STATE_BUSY, /* node allocated to a job and that job is actively running */ + STATE_STAGE_OUT, /* node has been allocated to a job, which has completed execution */ + STATE_DRAINED, /* node idle and not to be allocated future work */ + STATE_DRAINING, /* node in use, but not to be allocated future work */ + STATE_END +}; /* last entry in table */ +/* last entry must be "end", keep in sync with node_state */ +extern char *node_state_string[]; + +extern time_t last_bitmap_update; /* time of last node creation or deletion */ +extern time_t last_node_update; /* time of last update to node records */ +struct node_record { #if DEBUG_SYSTEM - char Magic; /* Magic cookie to test data integrity */ + char magic; /* magic cookie to test data integrity */ #endif - char Name[MAX_NAME_LEN]; /* Name of the node. A NULL name indicates defunct node */ - int NodeState; /* State of the node, see Node_State above, negative if down */ - time_t LastResponse; /* Last response from the node */ - int CPUs; /* Actual count of CPUs running on the node */ - int RealMemory; /* Actual megabytes of real memory on the node */ - int TmpDisk; /* Actual megabytes of total storage in TMP_FS file system */ - struct Config_Record *Config_Ptr; /* Configuration specification for this node */ - struct Part_Record *Partition_Ptr; /* Partition for this node */ + char name[MAX_NAME_LEN]; /* name of the node. a null name indicates defunct node */ + int node_state; /* state of the node, see node_state above, negative if down */ + time_t last_response; /* last response from the node */ + int cpus; /* actual count of cpus running on the node */ + int real_memory; /* actual megabytes of real memory on the node */ + int tmp_disk; /* actual megabytes of total storage in TMP_FS file system */ + struct config_record *config_ptr; /* configuration specification for this node */ + struct part_record *partition_ptr; /* partition for this node */ }; -extern struct Node_Record *Node_Record_Table_Ptr; /* Location of the node records */ -extern int Node_Record_Count; /* Count of records in the Node Record Table */ -extern int *Hash_Table; /* Table of hashed indicies into Node_Record */ -extern unsigned *Up_NodeBitMap; /* Bitmap of nodes are UP */ -extern unsigned *Idle_NodeBitMap; /* Bitmap of nodes are IDLE */ -extern struct Config_Record Default_Config_Record; -extern struct Node_Record Default_Node_Record; - -/* NOTE: Change PART_STRUCT_VERSION value whenever the contents of PART_STRUCT_FORMAT change */ +extern struct node_record *node_record_table_ptr; /* location of the node records */ +extern int node_record_count; /* count of records in the node record table */ +extern int *hash_table; /* table of hashed indicies into node_record */ +extern unsigned *up_node_bitmap; /* bitmap of nodes are up */ +extern unsigned *idle_node_bitmap; /* bitmap of nodes are idle */ +extern struct config_record default_config_record; +extern struct node_record default_node_record; + +/* NOTE: change PART_STRUCT_VERSION value whenever the contents of PART_STRUCT_FORMAT change */ #define PART_STRUCT_VERSION 1 #define PART_STRUCT_FORMAT "PartitionName=%s MaxNodes=%d MaxTime=%d Nodes=%s Key=%s Default=%s AllowGroups=%s Shared=%s State=%s #TotalNodes=%d TotalCPUs=%d\n" -#define PART_MAGIC 'P' -extern time_t Last_Part_Update; /* Time of last update to Part Records */ -struct Part_Record { +#define PART_MAGIC 'p' +extern time_t last_part_update; /* time of last update to part records */ +struct part_record { #if DEBUG_SYSTEM - char Magic; /* Magic cookie to test data integrity */ + char magic; /* magic cookie to test data integrity */ #endif - char Name[MAX_NAME_LEN]; /* Name of the partition */ - int MaxTime; /* -1 if unlimited */ - int MaxNodes; /* -1 if unlimited */ - int TotalNodes; /* Total number of nodes in the partition */ - int TotalCPUs; /* Total number of CPUs in the partition */ - unsigned Key:1; /* 1 if SLURM distributed key is required for use of partition */ - unsigned Shared:2; /* 1 if more than one job can execute on a node, 2 if required */ - unsigned StateUp:1; /* 1 if state is UP, 0 if DOWN */ - char *Nodes; /* Names of nodes in partition */ - char *AllowGroups; /* NULL indicates ALL */ - unsigned *NodeBitMap; /* Bitmap of nodes in partition */ + char name[MAX_NAME_LEN]; /* name of the partition */ + int max_time; /* -1 if unlimited */ + int max_nodes; /* -1 if unlimited */ + int total_nodes; /* total number of nodes in the partition */ + int total_cpus; /* total number of cpus in the partition */ + unsigned key:1; /* 1 if slurm distributed key is required for use of partition */ + unsigned shared:2; /* 1 if more than one job can execute on a node, 2 if required */ + unsigned state_up:1; /* 1 if state is up, 0 if down */ + char *nodes; /* names of nodes in partition */ + char *allow_groups; /* null indicates all */ + unsigned *node_bitmap; /* bitmap of nodes in partition */ }; -extern List Part_List; /* List of Part_Record entries */ -extern struct Part_Record Default_Part; /* Default configuration values */ -extern char Default_Part_Name[MAX_NAME_LEN]; /* Name of default partition */ -extern struct Part_Record *Default_Part_Loc; /* Location of default partition */ +extern List part_list; /* list of part_record entries */ +extern struct part_record default_part; /* default configuration values */ +extern char default_part_name[MAX_NAME_LEN]; /* name of default partition */ +extern struct part_record *default_part_loc; /* location of default partition */ /* - * BitMap2NodeName - Given a bitmap, build a node list representation - * Input: BitMap - Bitmap pointer - * Node_List - Place to put node list - * Output: Node_List - Set to node list or NULL on error - * Returns 0 if no error, otherwise EINVAL or ENOMEM - * NOTE: Consider returning the node list as a regular expression if helpful - * NOTE: The caller must free memory at Node_List when no longer required + * bitmap2node_name - given a bitmap, build a node list representation + * input: bitmap - bitmap pointer + * node_list - place to put node list + * output: node_list - set to node list or null on error + * returns 0 if no error, otherwise einval or enomem + * NOTE: consider returning the node list as a regular expression if helpful + * NOTE: the caller must free memory at node_list when no longer required */ -extern int BitMap2NodeName(unsigned *BitMap, char **Node_List); +extern int bitmap2node_name (unsigned *bitmap, char **node_list); /* - * BitMapAND - AND two bitmaps together - * Input: BitMap1 and BitMap2 - The bitmaps to AND - * Output: BitMap1 is set to the value of BitMap1 & BitMap2 + * bitmap_and - and two bitmaps together + * input: bitmap1 and bitmap2 - the bitmaps to and + * output: bitmap1 is set to the value of bitmap1 & bitmap2 */ -extern void BitMapAND(unsigned *BitMap1, unsigned *BitMap2); +extern void bitmap_and (unsigned *bitmap1, unsigned *bitmap2); /* - * BitMapClear - Clear the specified bit in the specified bitmap - * Input: BitMap - The bit map to manipulate - * Position - Postition to clear - * Output: BitMap - Updated value + * bitmap_clear - clear the specified bit in the specified bitmap + * input: bitmap - the bit map to manipulate + * position - postition to clear + * output: bitmap - updated value */ -extern void BitMapClear(unsigned *BitMap, int Position); +extern void bitmap_clear (unsigned *bitmap, int position); /* - * BitMapCopy - Create a copy of a bitmap - * Input: BitMap - The bitmap create a copy of - * Output: Returns pointer to copy of BitMap or NULL if error (no memory) - * The returned value MUST BE FREED by the calling routine + * bitmap_copy - create a copy of a bitmap + * input: bitmap - the bitmap create a copy of + * output: returns pointer to copy of bitmap or null if error (no memory) + * the returned value must be freed by the calling routine */ -extern unsigned * BitMapCopy(unsigned *BitMap); +extern unsigned *bitmap_copy (unsigned *bitmap); /* - * BitMapCount - Return the count of set bits in the specified bitmap - * Input: BitMap - The bit map to get count from - * Output: Returns the count of set bits + * bitmap_count - return the count of set bits in the specified bitmap + * input: bitmap - the bit map to get count from + * output: returns the count of set bits */ -extern int BitMapCount(unsigned *BitMap); +extern int bitmap_count (unsigned *bitmap); /* - * BitMapFill - Fill the provided bitmap so that all bits between the highest and lowest + * bitmap_fill - fill the provided bitmap so that all bits between the highest and lowest * previously set bits are also set (i.e fill in the gaps to make it contiguous) - * Input: BitMap - Pointer to the bit map to fill in - * Output: BitMap - The filled in bitmap + * input: bitmap - pointer to the bit map to fill in + * output: bitmap - the filled in bitmap */ -extern void BitMapFill(unsigned *BitMap); +extern void bitmap_fill (unsigned *bitmap); /* - * BitMapIsSuper - Report if one bitmap's contents are a superset of another - * Input: BitMap1 and BitMap2 - The bitmaps to compare - * Output: Return 1 if if all bits in BitMap1 are also in BitMap2, 0 otherwise + * bitmap_is_super - report if one bitmap's contents are a superset of another + * input: bitmap1 and bitmap2 - the bitmaps to compare + * output: return 1 if if all bits in bitmap1 are also in bitmap2, 0 otherwise */ -extern int BitMapIsSuper(unsigned *BitMap1, unsigned *BitMap2); +extern int bitmap_is_super (unsigned *bitmap1, unsigned *bitmap2); /* - * BitMapOR - OR two bitmaps together - * Input: BitMap1 and BitMap2 - The bitmaps to OR - * Output: BitMap1 is set to the value of BitMap1 | BitMap2 + * bitmap_or - or two bitmaps together + * input: bitmap1 and bitmap2 - the bitmaps to or + * output: bitmap1 is set to the value of bitmap1 | bitmap2 */ -extern void BitMapOR(unsigned *BitMap1, unsigned *BitMap2); +extern void bitmap_or (unsigned *bitmap1, unsigned *bitmap2); /* - * BitMapPrint - Convert the specified bitmap into a printable hexadecimal string - * Input: BitMap - The bit map to print - * Output: Returns a string - * NOTE: The returned string must be freed by the calling program + * bitmap_print - convert the specified bitmap into a printable hexadecimal string + * input: bitmap - the bit map to print + * output: returns a string + * NOTE: the returned string must be freed by the calling program */ -extern char *BitMapPrint(unsigned *BitMap); +extern char *bitmap_print (unsigned *bitmap); /* - * BitMapSet - Set the specified bit in the specified bitmap - * Input: BitMap - The bit map to manipulate - * Position - Postition to set - * Output: BitMap - Updated value + * bitmap_set - set the specified bit in the specified bitmap + * input: bitmap - the bit map to manipulate + * position - postition to set + * output: bitmap - updated value */ -extern void BitMapSet(unsigned *BitMap, int Position); +extern void bitmap_set (unsigned *bitmap, int position); /* - * BitMapValue - Return the value of specified bit in the specified bitmap - * Input: BitMap - The bit map to get value from - * Position - Postition to get - * Output: Normally returns the value 0 or 1, returns -1 if given bad BitMap ponter + * bitmap_value - return the value of specified bit in the specified bitmap + * input: bitmap - the bit map to get value from + * position - postition to get + * output: normally returns the value 0 or 1, returns -1 if given bad bitmap ponter */ -extern int BitMapValue(unsigned *BitMap, int Position); +extern int bitmap_value (unsigned *bitmap, int position); /* - * Create_Config_Record - Create a Config_Record entry, append it to the Config_List, - * and set is values to the defaults in Default_Config_Record. - * Input: Error_Code - Pointer to an error code - * Output: Returns pointer to the Config_Record - * Error_Code - set to zero if no error, errno otherwise - * NOTE: The pointer returned is allocated memory that must be freed when no longer needed. + * create_config_record - create a config_record entry, append it to the config_list, + * and set is values to the defaults in default_config_record. + * input: error_code - pointer to an error code + * output: returns pointer to the config_record + * error_code - set to zero if no error, errno otherwise + * NOTE: the pointer returned is allocated memory that must be freed when no longer needed. */ -extern struct Config_Record *Create_Config_Record(int *Error_Code); +extern struct config_record *create_config_record (int *error_code); /* - * Create_Node_Record - Create a node record - * Input: Error_Code - Location to store error value in - * Config_Point - Pointer to node's configuration information - * Node_Name - Name of the node - * Output: Error_Code - Set to zero if no error, errno otherwise - * Returns a pointer to the record or NULL if error - * NOTE The record's values are initialized to those of Default_Node_Record, Node_Name and - * Config_Point's CPUs, RealMemory, and TmpDisk values - * NOTE: Allocates memory that should be freed with Delete_Part_Record - */ -extern struct Node_Record *Create_Node_Record(int *Error_Code, struct Config_Record *Config_Point, - char *Node_Name); + * create_node_record - create a node record + * input: error_code - location to store error value in + * config_point - pointer to node's configuration information + * node_name - name of the node + * output: error_code - set to zero if no error, errno otherwise + * returns a pointer to the record or null if error + * note the record's values are initialized to those of default_node_record, node_name and + * config_point's cpus, real_memory, and tmp_disk values + * NOTE: allocates memory that should be freed with delete_part_record + */ +extern struct node_record *create_node_record (int *error_code, + struct config_record + *config_point, + char *node_name); /* - * Create_Part_Record - Create a partition record - * Input: Error_Code - Location to store error value in - * Output: Error_Code - Set to zero if no error, errno otherwise - * Returns a pointer to the record or NULL if error - * NOTE: The record's values are initialized to those of Default_Part + * create_part_record - create a partition record + * input: error_code - location to store error value in + * output: error_code - set to zero if no error, errno otherwise + * returns a pointer to the record or null if error + * NOTE: the record's values are initialized to those of default_part */ -extern struct Part_Record *Create_Part_Record(int *Error_Code); +extern struct part_record *create_part_record (int *error_code); /* - * Delete_Node_Record - Delete record for node with specified name - * To avoid invalidating the bitmaps and hash table, we just clear the name + * delete_node_record - delete record for node with specified name + * to avoid invalidating the bitmaps and hash table, we just clear the name * set its state to STATE_DOWN - * Input: name - name of the desired node - * Output: return 0 on success, errno otherwise + * input: name - name of the desired node + * output: return 0 on success, errno otherwise */ -extern int Delete_Node_Record(char *name); +extern int delete_node_record (char *name); /* - * Delete_Part_Record - Delete record for partition with specified name - * Input: name - name of the desired node - * Output: return 0 on success, errno otherwise + * delete_part_record - delete record for partition with specified name + * input: name - name of the desired node + * output: return 0 on success, errno otherwise */ -extern int Delete_Part_Record(char *name); +extern int delete_part_record (char *name); /* - * Dump_Node - Dump all configuration and node information to a buffer - * Input: Buffer_Ptr - Location into which a pointer to the data is to be stored. - * The data buffer is actually allocated by Dump_Node and the + * dump_node - dump all configuration and node information to a buffer + * input: buffer_ptr - location into which a pointer to the data is to be stored. + * the data buffer is actually allocated by dump_node and the * calling function must free the storage. - * Buffer_Size - Location into which the size of the created buffer is in bytes - * Update_Time - Dump new data only if partition records updated since time + * buffer_size - location into which the size of the created buffer is in bytes + * update_time - dump new data only if partition records updated since time * specified, otherwise return empty buffer - * Output: Buffer_Ptr - The pointer is set to the allocated buffer. - * Buffer_Size - Set to size of the buffer in bytes - * Update_Time - set to time partition records last updated - * Returns 0 if no error, errno otherwise - * NOTE: In this prototype, the buffer at *Buffer_Ptr must be freed by the caller - * NOTE: This is a prototype for a function to ship data partition to an API. + * output: buffer_ptr - the pointer is set to the allocated buffer. + * buffer_size - set to size of the buffer in bytes + * update_time - set to time partition records last updated + * returns 0 if no error, errno otherwise + * NOTE: in this prototype, the buffer at *buffer_ptr must be freed by the caller + * NOTE: this is a prototype for a function to ship data partition to an api. */ -extern int Dump_Node(char **Buffer_Ptr, int *Buffer_Size, time_t *Update_Time); +extern int dump_node (char **buffer_ptr, int *buffer_size, + time_t * update_time); /* - * Dump_Part - Dump all partition information to a buffer - * Input: Buffer_Ptr - Location into which a pointer to the data is to be stored. - * The data buffer is actually allocated by Dump_Part and the + * dump_part - dump all partition information to a buffer + * input: buffer_ptr - location into which a pointer to the data is to be stored. + * the data buffer is actually allocated by dump_part and the * calling function must free the storage. - * Buffer_Size - Location into which the size of the created buffer is in bytes - * Update_Time - Dump new data only if partition records updated since time + * buffer_size - location into which the size of the created buffer is in bytes + * update_time - dump new data only if partition records updated since time * specified, otherwise return empty buffer - * Output: Buffer_Ptr - The pointer is set to the allocated buffer. - * Buffer_Size - Set to size of the buffer in bytes - * Update_Time - set to time partition records last updated - * Returns 0 if no error, errno otherwise - * NOTE: In this prototype, the buffer at *Buffer_Ptr must be freed by the caller - * NOTE: This is a prototype for a function to ship data partition to an API. + * output: buffer_ptr - the pointer is set to the allocated buffer. + * buffer_size - set to size of the buffer in bytes + * update_time - set to time partition records last updated + * returns 0 if no error, errno otherwise + * NOTE: in this prototype, the buffer at *buffer_ptr must be freed by the caller + * NOTE: this is a prototype for a function to ship data partition to an api. */ -extern int Dump_Part(char **Buffer_Ptr, int *Buffer_Size, time_t *Update_Time); +extern int dump_part (char **buffer_ptr, int *buffer_size, + time_t * update_time); /* - * Find_Node_Record - Find a record for node with specified name, - * Input: name - name of the desired node - * Output: return pointer to node record or NULL if not found + * find_node_record - find a record for node with specified name, + * input: name - name of the desired node + * output: return pointer to node record or null if not found */ -extern struct Node_Record *Find_Node_Record(char *name); +extern struct node_record *find_node_record (char *name); /* - * Find_Part_Record - Find a record for partition with specified name, - * Input: name - name of the desired partition - * Output: return pointer to node partition or NULL if not found + * find_part_record - find a record for partition with specified name, + * input: name - name of the desired partition + * output: return pointer to node partition or null if not found */ -extern struct Part_Record *Find_Part_Record(char *name); +extern struct part_record *find_part_record (char *name); /* - * Init_Node_Conf - Initialize the node configuration values. - * This should be called before creating any node or configuration entries. - * Output: return value - 0 if no error, otherwise an error code + * init_node_conf - initialize the node configuration values. + * this should be called before creating any node or configuration entries. + * output: return value - 0 if no error, otherwise an error code */ -extern int Init_Node_Conf(); +extern int init_node_conf (); /* - * Init_Part_Conf - Initialize the partition configuration values. - * This should be called before creating any partition entries. - * Output: return value - 0 if no error, otherwise an error code + * init_part_conf - initialize the partition configuration values. + * this should be called before creating any partition entries. + * output: return value - 0 if no error, otherwise an error code */ -extern int Init_Part_Conf(); +extern int init_part_conf (); -/* List_Compare_Config - Compare two entry from the config list based upon weight, +/* list_compare_config - compare two entry from the config list based upon weight, * see list.h for documentation */ -extern int List_Compare_Config(void *Config_Entry1, void *Config_Entry2); +extern int list_compare_config (void *config_entry1, void *config_entry2); -/* List_Delete_Config - Delete an entry from the configuration list, see list.h for documentation */ -extern void List_Delete_Config(void *Config_Entry); +/* list_delete_config - delete an entry from the configuration list, see list.h for documentation */ +extern void list_delete_config (void *config_entry); -/* List_Find_Config - Find an entry in the configuration list, see list.h for documentation - * Key is partition name or "UNIVERSAL_KEY" for all configuration */ -extern int List_Find_Config(void *Config_Entry, void *key); +/* list_find_config - find an entry in the configuration list, see list.h for documentation + * key is partition name or "universal_key" for all configuration */ +extern int list_find_config (void *config_entry, void *key); -/* List_Delete_Part - Delete an entry from the partition list, see list.h for documentation */ -extern void List_Delete_Part(void *Part_Entry); +/* list_delete_part - delete an entry from the partition list, see list.h for documentation */ +extern void list_delete_part (void *part_entry); -/* List_Find_Part - Find an entry in the partition list, see list.h for documentation - * Key is partition name or "UNIVERSAL_KEY" for all partitions */ -extern int List_Find_Part(void *Part_Entry, void *key); +/* list_find_part - find an entry in the partition list, see list.h for documentation + * key is partition name or "universal_key" for all partitions */ +extern int list_find_part (void *part_entry, void *key); /* - * Load_Integer - Parse a string for a keyword, value pair - * Input: *destination - Location into which result is stored - * keyword - String to search for - * In_Line - String to search for keyword - * Output: *destination - set to value, No change if value not found, - * Set to 1 if keyword found without value, - * Set to -1 if keyword followed by "UNLIMITED" - * In_Line - The keyword and value (if present) are overwritten by spaces + * load_integer - parse a string for a keyword, value pair + * input: *destination - location into which result is stored + * keyword - string to search for + * in_line - string to search for keyword + * output: *destination - set to value, no change if value not found, + * set to 1 if keyword found without value, + * set to -1 if keyword followed by "unlimited" + * in_line - the keyword and value (if present) are overwritten by spaces * return value - 0 if no error, otherwise an error code - * NOTE: In_Line is overwritten, DO NOT USE A CONSTANT + * NOTE: in_line is overwritten, do not use a constant */ -extern int Load_Integer(int *destination, char *keyword, char *In_Line); +extern int load_integer (int *destination, char *keyword, char *in_line); /* - * Load_String - Parse a string for a keyword, value pair - * Input: *destination - Location into which result is stored - * keyword - String to search for - * In_Line - String to search for keyword - * Output: *destination - set to value, No change if value not found, + * load_string - parse a string for a keyword, value pair + * input: *destination - location into which result is stored + * keyword - string to search for + * in_line - string to search for keyword + * output: *destination - set to value, no change if value not found, * if *destination had previous value, that memory location is automatically freed - * In_Line - The keyword and value (if present) are overwritten by spaces + * in_line - the keyword and value (if present) are overwritten by spaces * return value - 0 if no error, otherwise an error code * NOTE: destination must be free when no longer required - * NOTE: if destination is non-NULL at function call time, it will be freed - * NOTE: In_Line is overwritten, DO NOT USE A CONSTANT + * NOTE: if destination is non-null at function call time, it will be freed + * NOTE: in_line is overwritten, do not use a constant */ -extern int Load_String(char **destination, char *keyword, char *In_Line); +extern int load_string (char **destination, char *keyword, char *in_line); -/* Node_Lock - Lock the node and configuration information */ -extern void Node_Lock(); +/* node_lock - lock the node and configuration information */ +extern void node_lock (); -/* Node_Unlock - Unlock the node and configuration information */ -extern void Node_Unlock(); +/* node_unlock - unlock the node and configuration information */ +extern void node_unlock (); /* - * NodeName2BitMap - Given a node list, build a bitmap representation - * Input: Node_List - List of nodes - * BitMap - Place to put bitmap pointer - * Output: BitMap - Set to bitmap or NULL on error - * Returns 0 if no error, otherwise EINVAL or ENOMEM - * NOTE: The caller must free memory at BitMap when no longer required + * node_name2bitmap - given a node list, build a bitmap representation + * input: node_list - list of nodes + * bitmap - place to put bitmap pointer + * output: bitmap - set to bitmap or null on error + * returns 0 if no error, otherwise einval or enomem + * NOTE: the caller must free memory at bitmap when no longer required */ -extern int NodeName2BitMap(char *Node_List, unsigned **BitMap); +extern int node_name2bitmap (char *node_list, unsigned **bitmap); -/* Part_Lock - Lock the partition information */ -extern void Part_Lock(); +/* part_lock - lock the partition information */ +extern void part_lock (); -/* Part_Unlock - Unlock the partition information */ -extern void Part_Unlock(); +/* part_unlock - unlock the partition information */ +extern void part_unlock (); /* - * Read_Buffer - Read a line from the specified buffer - * Input: Buffer - Pointer to read buffer, must be allocated by alloc() - * Buffer_Offset - Byte offset in Buffer, read location - * Buffer_Size - Byte size of Buffer - * Line - Pointer to location to be loaded with POINTER TO THE LINE - * Output: Buffer_Offset - Incremented by size of size plus the Value size itself - * Line - Set to pointer to the line - * Returns 0 if no error or EFAULT on end of buffer, EINVAL on bad tag - */ -extern int Read_Buffer(char *Buffer, int *Buffer_Offset, int Buffer_Size, char **Line); + * read_buffer - read a line from the specified buffer + * input: buffer - pointer to read buffer, must be allocated by alloc() + * buffer_offset - byte offset in buffer, read location + * buffer_size - byte size of buffer + * line - pointer to location to be loaded with pointer to the line + * output: buffer_offset - incremented by size of size plus the value size itself + * line - set to pointer to the line + * returns 0 if no error or efault on end of buffer, einval on bad tag + */ +extern int read_buffer (char *buffer, int *buffer_offset, int buffer_size, + char **line); /* - * Read_SLURM_Conf - Load the SLURM configuration from the specified file - * Call Init_SLURM_Conf before ever calling Read_SLURM_Conf. - * Read_SLURM_Conf can be called more than once if so desired. - * Input: File_Name - Name of the file containing SLURM configuration information - * Output: Return - 0 if no error, otherwise an error code + * read_SLURM_CONF - load the slurm configuration from the specified file + * call init_SLURM_CONF before ever calling read_SLURM_CONF. + * read_SLURM_CONF can be called more than once if so desired. + * input: file_name - name of the file containing slurm configuration information + * output: return - 0 if no error, otherwise an error code */ -extern int Read_SLURM_Conf (char *File_Name); +extern int read_SLURM_CONF (char *file_name); /* - * Report_Leftover - Report any un-parsed (non-whitespace) characters on the + * report_leftover - report any un-parsed (non-whitespace) characters on the * configuration input line. - * Input: In_Line - What is left of the configuration input line. - * Line_Num - Line number of the configuration file. - * Output: NONE + * input: in_line - what is left of the configuration input line. + * line_num - line number of the configuration file. + * output: none */ -extern void Report_Leftover(char *In_Line, int Line_Num); +extern void report_leftover (char *in_line, int line_num); /* - * Update_Node - Update a node configuration data - * Input: NodeName - Node name specification (can include real expression) - * Spec - The updates to the node's specification - * Output: Return - 0 if no error, otherwise an error code + * update_node - update a node configuration data + * input: node_name - node name specification (can include real expression) + * spec - the updates to the node's specification + * output: return - 0 if no error, otherwise an error code */ -extern int Update_Node(char *NodeName, char *Spec); +extern int update_node (char *node_name, char *spec); /* - * Update_Part - Update a partition's configuration data - * Input: PartitionName - Partition's name - * Spec - The updates to the partition's specification - * Output: Return - 0 if no error, otherwise an error code - * NOTE: The contents of Spec are overwritten by white space + * update_part - update a partition's configuration data + * input: partition_name - partition's name + * spec - the updates to the partition's specification + * output: return - 0 if no error, otherwise an error code + * NOTE: the contents of spec are overwritten by white space */ -extern int Update_Part(char *PartitionName, char *Spec); +extern int update_part (char *partition_name, char *spec); /* - * Validate_Node_Specs - Validate the node's specifications as valid, - * if not set state to DOWN, in any case update LastResponse - * Input: NodeName - Name of the node - * CPUs - Number of CPUs measured - * RealMemory - MegaBytes of RealMemory measured - * TmpDisk - MegaBytes of TmpDisk measured - * Output: Returns 0 if no error, ENOENT if no such node, EINVAL if values too low - */ -extern int Validate_Node_Specs(char *NodeName, - int CPUs, int RealMemory, int TmpDisk); + * validate_node_specs - validate the node's specifications as valid, + * if not set state to down, in any case update last_response + * input: node_name - name of the node + * cpus - number of cpus measured + * real_memory - mega_bytes of real_memory measured + * tmp_disk - mega_bytes of tmp_disk measured + * output: returns 0 if no error, enoent if no such node, einval if values too low + */ +extern int validate_node_specs (char *node_name, + int cpus, int real_memory, int tmp_disk); /* - * Write_Buffer - Write the specified line to the specified buffer, + * write_buffer - write the specified line to the specified buffer, * enlarging the buffer as needed - * Input: Buffer - Pointer to write buffer, must be allocated by alloc() - * Buffer_Offset - Byte offset in Buffer, write location - * Buffer_Size - Byte size of Buffer - * Line - Pointer to data to be writen - * Output: Buffer - Value is written here, buffer may be relocated by realloc() - * Buffer_Offset - Incremented by Value_Size - * Returns 0 if no error or errno otherwise - */ -extern int Write_Buffer(char **Buffer, int *Buffer_Offset, int *Buffer_Size, char *Line); + * input: buffer - pointer to write buffer, must be allocated by alloc() + * buffer_offset - byte offset in buffer, write location + * buffer_size - byte size of buffer + * line - pointer to data to be writen + * output: buffer - value is written here, buffer may be relocated by realloc() + * buffer_offset - incremented by value_size + * returns 0 if no error or errno otherwise + */ +extern int write_buffer (char **buffer, int *buffer_offset, int *buffer_size, + char *line); #endif /* !_HAVE_SLURM_H */ diff --git a/src/common/slurmlib.h b/src/common/slurmlib.h index 6e139c1eb8e89959b5c2d19d46477f9af2e6c636..c7b4c77855d8fc23f69e0b9982cf8bfa6dd09f9b 100644 --- a/src/common/slurmlib.h +++ b/src/common/slurmlib.h @@ -1,8 +1,8 @@ /* - * slurmlib.h - Descriptions of SLURM APIs - * See slurm.h for documentation on external functions and data structures + * slurmlib.h - descriptions of slurm APIs + * see slurm.h for documentation on external functions and data structures * - * Author: Moe Jette, jette@llnl.gov + * author: moe jette, jette@llnl.gov */ #define MAX_NAME_LEN 16 @@ -11,136 +11,146 @@ #define SLURMCTLD_HOST "134.9.55.42" #define SLURMCTLD_PORT 1543 - - /* - * Allocate - Allocate nodes for a job with supplied contraints. - * Input: Spec - Specification of the job's constraints - * NodeList - Place into which a node list pointer can be placed - * Output: NodeList - List of allocated nodes - * Returns 0 if no error, EINVAL if the request is invalid, - * EAGAIN if the request can not be satisfied at present - * NOTE: Acceptable specifications include: JobName=<name> NodeList=<list>, + * slurm_allocate - allocate nodes for a job with supplied contraints. + * input: spec - specification of the job's constraints + * node_list - place into which a node list pointer can be placed + * output: node_list - list of allocated nodes + * returns 0 if no error, einval if the request is invalid, + * eagain if the request can not be satisfied at present + * NOTE: acceptable specifications include: JobName=<name> NodeList=<list>, * Features=<features>, Groups=<groups>, Partition=<part_name>, Contiguous, * TotalCPUs=<number>, TotalNodes=<number>, MinCPUs=<number>, * MinMemory=<number>, MinTmpDisk=<number>, Key=<number>, Shared=<0|1> - * NOTE: The calling function must free the allocated storage at NodeList[0] + * NOTE: the calling function must free the allocated storage at node_list[0] */ -extern int Allocate(char *Spec, char **NodeList); +extern int slurm_allocate (char *spec, char **node_list); /* - * Free_Build_Info - Free the build information buffer (if allocated) + * slurm_free_build_info - free the build information buffer (if allocated). + * NOTE: buffer is loaded by slurm_load_build and used by slurm_load_build_name. */ -extern void Free_Build_Info(void); +extern void slurm_free_build_info (void); /* - * Free_Node_Info - Free the node information buffer (if allocated) + * free_node_info - free the node information buffer (if allocated) + * NOTE: buffer is loaded by load_node and used by load_node_name. */ -extern void Free_Node_Info(void); +extern void free_node_info (void); /* - * Free_Part_Info - Free the partition information buffer (if allocated) + * free_part_info - free the partition information buffer (if allocated) + * NOTE: buffer is loaded by load_part and used by load_part_name. */ -extern void Free_Part_Info(void); +extern void free_part_info (void); /* - * Load_Build - Update the build information buffer for use by info gathering APIs - * Output: Returns 0 if no error, EINVAL if the buffer is invalid, ENOMEM if malloc failure + * slurm_load_build - update the build information buffer for use by info gathering APIs + * output: returns 0 if no error, einval if the buffer is invalid, enomem if malloc failure. + * NOTE: buffer is used by slurm_load_build_name and freed by slurm_free_build_info. */ -extern int Load_Build(); +extern int slurm_load_build (); /* - * Load_Build_Name - Load the state information about the named build parameter - * Input: Req_Name - Name of the parameter for which information is requested + * slurm_load_build_name - load the state information about the named build parameter + * input: req_name - name of the parameter for which information is requested * if "", then get info for the first parameter in list - * Next_Name - Location into which the name of the next parameter is + * next_name - location into which the name of the next parameter is * stored, "" if no more - * Value - Pointer to location into which the information is to be stored - * Output: Req_Name - The parameter's name is stored here - * Next_Name - The name of the next parameter in the list is stored here - * Value - The parameter's state information - * Returns 0 on success, ENOENT if not found, or EINVAL if buffer is bad - * NOTE: Req_Name, Next_Name, and Value must be declared by caller with have + * value - pointer to location into which the information is to be stored + * output: req_name - the parameter's name is stored here + * next_name - the name of the next parameter in the list is stored here + * value - the parameter's state information + * returns 0 on success, enoent if not found, or einval if buffer is bad + * NOTE: req_name, next_name, and value must be declared by caller with have * length BUILD_SIZE or larger + * NOTE: buffer is loaded by slurm_load_build and freed by slurm_free_build_info. */ -extern int Load_Build_Name(char *Req_Name, char *Next_Name, char *Value); - +extern int slurm_load_build_name (char *req_name, char *next_name, char *value); + /* - * Load_Node - Load the supplied node information buffer for use by info gathering APIs if + * load_node - load the supplied node information buffer for use by info gathering APIs if * node records have changed since the time specified. - * Input: Buffer - Pointer to node information buffer - * Buffer_Size - size of Buffer - * Output: Returns 0 if no error, EINVAL if the buffer is invalid, ENOMEM if malloc failure + * input: buffer - pointer to node information buffer + * buffer_size - size of buffer + * output: returns 0 if no error, einval if the buffer is invalid, enomem if malloc failure + * NOTE: buffer is used by load_node_config and freed by free_node_info. */ -extern int Load_Node(time_t *Last_Update_Time); - +extern int load_node (time_t * last_update_time); + /* - * Load_Node_Config - Load the state information about the named node - * Input: Req_Name - Name of the node for which information is requested + * load_node_config - load the state information about the named node + * input: req_name - name of the node for which information is requested * if "", then get info for the first node in list - * Next_Name - Location into which the name of the next node is + * next_name - location into which the name of the next node is * stored, "" if no more - * CPUs, etc. - Pointers into which the information is to be stored - * Output: Next_Name - Name of the next node in the list - * CPUs, etc. - The node's state information - * Returns 0 on success, ENOENT if not found, or EINVAL if buffer is bad - * NOTE: Req_Name, Next_Name, Partition, and NodeState must be declared by the + * cpus, etc. - pointers into which the information is to be stored + * output: next_name - name of the next node in the list + * cpus, etc. - the node's state information + * returns 0 on success, enoent if not found, or einval if buffer is bad + * NOTE: req_name, next_name, partition, and node_state must be declared by the * caller and have length MAX_NAME_LEN or larger - * Features must be declared by the caller and have length FEATURE_SIZE or larger + * features must be declared by the caller and have length FEATURE_SIZE or larger + * NOTE: buffer is loaded by load_node and freed by free_node_info. */ -extern int Load_Node_Config(char *Req_Name, char *Next_Name, int *CPUs, - int *RealMemory, int *TmpDisk, int *Weight, char *Features, - char *Partition, char *NodeState); +extern int load_node_config (char *req_name, char *next_name, int *cpus, + int *real_memory, int *tmp_disk, int *weight, + char *features, char *partition, + char *node_state); /* - * Load_Part - Update the partition information buffer for use by info gathering APIs if + * load_part - update the partition information buffer for use by info gathering APIs if * partition records have changed since the time specified. - * Input: Last_Update_Time - Pointer to time of last buffer - * Output: Last_Update_Time - Time reset if buffer is updated - * Returns 0 if no error, EINVAL if the buffer is invalid, ENOMEM if malloc failure + * input: last_update_time - pointer to time of last buffer + * output: last_update_time - time reset if buffer is updated + * returns 0 if no error, einval if the buffer is invalid, enomem if malloc failure + * NOTE: buffer is used by load_part_name and free by free_part_info. */ -int Load_Part(time_t *Last_Update_Time); +extern int load_part (time_t * last_update_time); /* - * Load_Part_Name - Load the state information about the named partition - * Input: Req_Name - Name of the partition for which information is requested + * load_part_name - load the state information about the named partition + * input: req_name - name of the partition for which information is requested * if "", then get info for the first partition in list - * Next_Name - Location into which the name of the next partition is + * next_name - location into which the name of the next partition is * stored, "" if no more - * MaxTime, etc. - Pointers into which the information is to be stored - * Output: Req_Name - The partition's name is stored here - * Next_Name - The name of the next partition in the list is stored here - * MaxTime, etc. - The partition's state information - * Returns 0 on success, ENOENT if not found, or EINVAL if buffer is bad - * NOTE: Req_Name and Next_Name must be declared by caller with have length MAX_NAME_LEN or larger - * Nodes and AllowGroups must be declared by caller with length of FEATURE_SIZE or larger + * max_time, etc. - pointers into which the information is to be stored + * output: req_name - the partition's name is stored here + * next_name - the name of the next partition in the list is stored here + * max_time, etc. - the partition's state information + * returns 0 on success, enoent if not found, or einval if buffer is bad + * NOTE: req_name and next_name must be declared by caller with have length MAX_NAME_LEN or larger. + * nodes and allow_groups must be declared by caller with length of FEATURE_SIZE or larger. + * NOTE: buffer is loaded by load_part and free by free_part_info. */ -int Load_Part_Name(char *Req_Name, char *Next_Name, int *MaxTime, int *MaxNodes, - int *TotalNodes, int *TotalCPUs, int *Key, int *StateUp, int *Shared, int *Default, - char *Nodes, char *AllowGroups); +extern int load_part_name (char *req_name, char *next_name, int *max_time, + int *max_nodes, int *total_nodes, int *total_cpus, + int *key, int *state_up, int *shared, int *default_flag, + char *nodes, char *allow_groups); /* - * Parse_Node_Name - Parse the node name for regular expressions and return a sprintf format + * parse_node_name - parse the node name for regular expressions and return a sprintf format * generate multiple node names as needed. - * Input: NodeName - Node name to parse - * Output: Format - sprintf format for generating names - * Start_Inx - First index to used - * End_Inx - Last index value to use - * Count_Inx - Number of index values to use (will be zero if none) + * input: node_name - node name to parse + * output: format - sprintf format for generating names + * start_inx - first index to used + * end_inx - last index value to use + * count_inx - number of index values to use (will be zero if none) * return 0 if no error, error code otherwise - * NOTE: The calling program must execute free(Format) when the storage location is no longer needed + * NOTE: the calling program must execute free(format) when the storage location is no longer needed */ -extern int Parse_Node_Name(char *NodeName, char **Format, int *Start_Inx, int *End_Inx, int *Count_Inx); +extern int parse_node_name (char *node_name, char **format, int *start_inx, + int *end_inx, int *count_inx); /* - * Reconfigure - _ Request that slurmctld re-read the configuration files - * Output: Returns 0 on success, errno otherwise + * reconfigure - _ request that slurmctld re-read the configuration files + * output: returns 0 on success, errno otherwise */ -extern int Reconfigure(); +extern int reconfigure (); /* - * Update_Config - _ Request that slurmctld update its configuration per request - * Input: A line containing configuration information per the configuration file format - * Output: Returns 0 on success, errno otherwise + * update_config - _ request that slurmctld update its configuration per request + * input: a line containing configuration information per the configuration file format + * output: returns 0 on success, errno otherwise */ -extern int Update_Config(char *Spec); +extern int update_config (char *spec); diff --git a/src/scontrol/scontrol.c b/src/scontrol/scontrol.c index 84d6c84d5033078cc156c8eb5ed7413f8700897e..4528212957c60c6d169497f3f41a9ea20641b457 100644 --- a/src/scontrol/scontrol.c +++ b/src/scontrol/scontrol.c @@ -1,6 +1,6 @@ /* - * scontrol - Administration tool for SLURM. - * Provides interface to read, write, update, and configurations. + * scontrol - administration tool for slurm. + * provides interface to read, write, update, and configurations. */ #include <errno.h> @@ -10,477 +10,575 @@ #include "slurmlib.h" #define BUF_SIZE 1024 -#define MAX_INPUT_FIELDS 128 - -char *Command_Name; -int Exit_Flag; /* Program to terminate if =1 */ -int Quiet_Flag; /* Quiet=1, verbose=-1, normal=0 */ -int Input_Words; /* Number of words of input permitted */ - -void Dump_Command(int argc, char *argv[]); -int Get_Command(int *argc, char *argv[]); -void Print_Build(char *build_param); -void Print_Node(char *node_name); -void Print_Node_List(char *node_list); -void Print_Part(char *partition_name); -int Process_Command(int argc, char *argv[]); -int Update_It(int argc, char *argv[]); -void Usage(); - -main(int argc, char *argv[]) { - int Error_Code, i, Input_Field_Count; - char **Input_Fields; - - Command_Name = argv[0]; - Exit_Flag = 0; - Input_Field_Count = 0; - Quiet_Flag = 0; - if (argc > MAX_INPUT_FIELDS) /* Bogus input, but let's continue anyway */ - Input_Words = argc; - else - Input_Words = 128; - Input_Fields = (char **)malloc(sizeof(char *) * Input_Words); - for (i=1; i<argc; i++) { - if (strcmp(argv[i], "-q") == 0) { - Quiet_Flag = 1; - } else if (strcmp(argv[i], "quiet") == 0) { - Quiet_Flag = 1; - } else if (strcmp(argv[i], "-v") == 0) { - Quiet_Flag = -1; - } else if (strcmp(argv[i], "verbose") == 0) { - Quiet_Flag = -1; - } else { - Input_Fields[Input_Field_Count++] = argv[i]; - } /* else */ - } /* for */ - - if (Input_Field_Count) - Exit_Flag = 1; - else - Error_Code = Get_Command(&Input_Field_Count, Input_Fields); - - while (1) { +#define max_input_fields 128 + +static char *command_name; +static int exit_flag; /* program to terminate if =1 */ +static int quiet_flag; /* quiet=1, verbose=-1, normal=0 */ +static int input_words; /* number of words of input permitted */ + +void dump_command (int argc, char *argv[]); +int get_command (int *argc, char *argv[]); +void print_build (char *build_param); +void print_node (char *node_name); +void print_node_list (char *node_list); +void print_part (char *partition_name); +int process_command (int argc, char *argv[]); +int update_it (int argc, char *argv[]); +void usage (); + +main (int argc, char *argv[]) { + int error_code, i, input_field_count; + char **input_fields; + + command_name = argv[0]; + exit_flag = 0; + input_field_count = 0; + quiet_flag = 0; + if (argc > max_input_fields) /* bogus input, but let's continue anyway */ + input_words = argc; + else + input_words = 128; + input_fields = (char **) malloc (sizeof (char *) * input_words); + for (i = 1; i < argc; i++) { + if (strcmp (argv[i], "-q") == 0) { + quiet_flag = 1; + } + else if (strcmp (argv[i], "quiet") == 0) { + quiet_flag = 1; + } + else if (strcmp (argv[i], "-v") == 0) { + quiet_flag = -1; + } + else if (strcmp (argv[i], "verbose") == 0) { + quiet_flag = -1; + } + else { + input_fields[input_field_count++] = argv[i]; + } /* else */ + } + + if (input_field_count) + exit_flag = 1; + else + error_code = get_command (&input_field_count, input_fields); + + while (1) { #if DEBUG_MODULE - Dump_Command(Input_Field_Count, Input_Fields); + dump_command (input_field_count, input_fields); #endif - Error_Code = Process_Command(Input_Field_Count, Input_Fields); - if (Error_Code != 0) break; - if (Exit_Flag == 1) break; - Error_Code = Get_Command(&Input_Field_Count, Input_Fields); - if (Error_Code != 0) break; - } /* while */ + error_code = + process_command (input_field_count, input_fields); + if (error_code != 0) + break; + if (exit_flag == 1) + break; + error_code = get_command (&input_field_count, input_fields); + if (error_code != 0) + break; + } - exit(Error_Code); -} /* main */ + exit (error_code); +} /* - * Dump_Command - Dump the user's command - * Input: argc - count of arguments + * dump_command - dump the user's command + * input: argc - count of arguments * argv - the arguments */ -void Dump_Command(int argc, char *argv[]) { - int i; +void +dump_command (int argc, char *argv[]) { + int i; - for (i=0; i<argc; i++) { - printf("Arg %d:%s:\n", i, argv[i]); - } /* for */ -} /* Dump_Command */ + for (i = 0; i < argc; i++) { + printf ("arg %d:%s:\n", i, argv[i]); + } +} /* - * Get_Command - Get a command from the user - * Input: argc - location to store count of arguments + * get_command - get a command from the user + * input: argc - location to store count of arguments * argv - location to store the argument list - * Output: returns error code, 0 if no problems + * output: returns error code, 0 if no problems */ -int Get_Command(int *argc, char **argv) { - static char *In_Line; - static int In_Line_Size = 0; - int In_Line_Pos = 0; - int Temp_Char, i; - - if (In_Line_Size == 0) { - In_Line_Size += BUF_SIZE; - In_Line = (char *)malloc(In_Line_Size); - if (In_Line == NULL) { - fprintf(stderr, "%s: Error %d allocating memory\n", Command_Name, errno); - In_Line_Size = 0; - return ENOMEM; - } /* if */ - } /* if */ - - printf("scontrol: "); - *argc = 0; - In_Line_Pos = 0; - - while (1) { - Temp_Char = getc(stdin); - if (Temp_Char == EOF) break; - if (Temp_Char == (int)'\n') break; - if ((In_Line_Pos+2) >= In_Line_Size) { - In_Line_Size += BUF_SIZE; - In_Line = (char *)realloc(In_Line, In_Line_Size); - if (In_Line == NULL) { - fprintf(stderr, "%s: Error %d allocating memory\n", Command_Name, errno); - In_Line_Size = 0; - return ENOMEM; - } /* if */ - } /* if */ - In_Line[In_Line_Pos++] = (char)Temp_Char; - } /* while */ - In_Line[In_Line_Pos] = (char)NULL; - - for (i=0; i<In_Line_Pos; i++) { - if (isspace((int)In_Line[i])) continue; - if (((*argc)+1) > MAX_INPUT_FIELDS) { /* Really bogus input line */ - fprintf(stderr, "%s: Over %d fields in line: %s\n", Command_Name, Input_Words ,In_Line); - return E2BIG; - } /* if */ - argv[(*argc)++] = &In_Line[i]; - for (i++ ; i<In_Line_Pos; i++) { - if (!isspace((int)In_Line[i])) continue; - In_Line[i] = (char)NULL; - break; - } /* for */ - } /* for */ - return 0; -} /* Get_Command */ +int get_command (int *argc, char **argv) { + static char *in_line; + static int in_line_size = 0; + int in_line_pos = 0; + int temp_char, i; + + if (in_line_size == 0) { + in_line_size += BUF_SIZE; + in_line = (char *) malloc (in_line_size); + if (in_line == NULL) { + fprintf (stderr, "%s: error %d allocating memory\n", + command_name, errno); + in_line_size = 0; + return ENOMEM; + } + } + + printf ("scontrol: "); + *argc = 0; + in_line_pos = 0; + + while (1) { + temp_char = getc (stdin); + if (temp_char == EOF) + break; + if (temp_char == (int) '\n') + break; + if ((in_line_pos + 2) >= in_line_size) { + in_line_size += BUF_SIZE; + in_line = (char *) realloc (in_line, in_line_size); + if (in_line == NULL) { + fprintf (stderr, + "%s: error %d allocating memory\n", + command_name, errno); + in_line_size = 0; + return ENOMEM; + } + } + in_line[in_line_pos++] = (char) temp_char; + } + in_line[in_line_pos] = (char) NULL; + + for (i = 0; i < in_line_pos; i++) { + if (isspace ((int) in_line[i])) + continue; + if (((*argc) + 1) > max_input_fields) { /* really bogus input line */ + fprintf (stderr, "%s: over %d fields in line: %s\n", + command_name, input_words, in_line); + return E2BIG; + } + argv[(*argc)++] = &in_line[i]; + for (i++; i < in_line_pos; i++) { + if (!isspace ((int) in_line[i])) + continue; + in_line[i] = (char) NULL; + break; + } + } + return 0; +} /* - * Print_Build - Print the specified build parameter and value - * Input: build_param - NULL to print all parameters and values + * print_build - print the specified build parameter and value + * input: build_param - NULL to print all parameters and values */ -void Print_Build(char *build_param) { - char Req_Name[BUILD_SIZE], Next_Name[BUILD_SIZE], Value[BUILD_SIZE]; - int Error_Code; - - Error_Code = Load_Build(); - if (Error_Code) { - if (Quiet_Flag != 1) printf("Load_Build error %d\n", Error_Code); - return; - } /* if */ - - - if (build_param) - strncpy(Req_Name, build_param, BUILD_SIZE); - else - strcpy(Req_Name, ""); /* Start at beginning of node list */ - - while (1) { - Error_Code = Load_Build_Name(Req_Name, Next_Name, Value); - if (Error_Code != 0) { - if (Quiet_Flag != 1) { - if (Error_Code == ENOENT) - printf("No parameter %s found\n", Req_Name); - else - printf("Error %d finding value for parameter %s\n", Error_Code, Req_Name); - } /* if */ - break; - } /* if */ - printf("%s=%s\n", Req_Name, Value); - - if (build_param || (strlen(Next_Name) == 0)) break; - strcpy(Req_Name, Next_Name); - } /* while */ -/* Free_Build_Info(); Keep data for reuse, cleaned on exit */ -} /* Print_Build */ +void print_build (char *build_param) { + char req_name[BUILD_SIZE], next_name[BUILD_SIZE], value[BUILD_SIZE]; + int error_code; + + error_code = slurm_load_build (); + if (error_code) { + if (quiet_flag != 1) + printf ("slurm_load_build error %d\n", error_code); + return; + } + + + if (build_param) + strncpy (req_name, build_param, BUILD_SIZE); + else + strcpy (req_name, ""); /* start at beginning of node list */ + + while (1) { + error_code = slurm_load_build_name (req_name, next_name, value); + if (error_code != 0) { + if (quiet_flag != 1) { + if (error_code == ENOENT) + printf ("no parameter %s found\n", + req_name); + else + printf ("error %d finding value for parameter %s\n", + error_code, req_name); + } + break; + } + printf ("%s=%s\n", req_name, value); + + if (build_param || (strlen (next_name) == 0)) + break; + strcpy (req_name, next_name); + } +/* slurm_free_build_info(); keep data for reuse, cleaned on exit */ +} /* - * Print_Node - Print the specified node's information - * Input: node_name - NULL to print all node information - * NOTE: Call this only after executing Load_Node, called from Print_Node_List + * print_node - print the specified node's information + * input: node_name - NULL to print all node information + * NOTE: call this only after executing load_node, called from print_node_list */ -void Print_Node(char *node_name) { - int Error_Code, size, i; - char Partition[MAX_NAME_LEN], Node_State[MAX_NAME_LEN], Features[FEATURE_SIZE]; - char Req_Name[MAX_NAME_LEN]; /* Name of the partition */ - char Next_Name[MAX_NAME_LEN]; /* Name of the next partition */ - int CPUs, RealMemory, TmpDisk, Weight; - char *Dump; - int Dump_Size; - time_t Update_Time; - unsigned *NodeBitMap; /* Bitmap of nodes in partition */ - int BitMapSize; /* Bytes in NodeBitMap */ - - if (node_name) - strncpy(Req_Name, node_name, MAX_NAME_LEN); - else - strcpy(Req_Name, ""); /* Start at beginning of node list */ - - while (1) { - Error_Code = Load_Node_Config(Req_Name, Next_Name, &CPUs, &RealMemory, &TmpDisk, &Weight, - Features, Partition, Node_State); - if (Error_Code != 0) { - if (Quiet_Flag != 1) { - if (Error_Code == ENOENT) - printf("No node %s found\n", Req_Name); - else - printf("Error %d finding information for node %s\n", Error_Code, Req_Name); - } /* if */ - break; - } /* if */ - printf("NodeName=%s CPUs=%d RealMemory=%d TmpDisk=%d ", - Req_Name, CPUs, RealMemory, TmpDisk); - printf("State=%s Weight=%d Features=%s Partition=%s\n", - Node_State, Weight, Features, Partition); - - if (node_name || (strlen(Next_Name) == 0)) break; - strcpy(Req_Name, Next_Name); - } /* while */ -} /* Print_Node */ +void +print_node (char *node_name) { + int error_code, size, i; + char partition[MAX_NAME_LEN], node_state[MAX_NAME_LEN], + features[FEATURE_SIZE]; + char req_name[MAX_NAME_LEN]; /* name of the partition */ + char next_name[MAX_NAME_LEN]; /* name of the next partition */ + int cpus, real_memory, tmp_disk, weight; + char *dump; + int dump_size; + time_t update_time; + unsigned *node_bitmap; /* bitmap of nodes in partition */ + int bitmap_size; /* bytes in node_bitmap */ + + if (node_name) + strncpy (req_name, node_name, MAX_NAME_LEN); + else + strcpy (req_name, ""); /* start at beginning of node list */ + + while (1) { + error_code = + load_node_config (req_name, next_name, &cpus, + &real_memory, &tmp_disk, &weight, + features, partition, node_state); + if (error_code != 0) { + if (quiet_flag != 1) { + if (error_code == ENOENT) + printf ("no node %s found\n", + req_name); + else + printf ("error %d finding information for node %s\n", error_code, req_name); + } + break; + } + printf ("NodeName=%s CPUs=%d RealMemory=%d TmpDisk=%d ", + req_name, cpus, real_memory, tmp_disk); + printf ("State=%s Weight=%d Features=%s Partition=%s\n", + node_state, weight, features, partition); + + if (node_name || (strlen (next_name) == 0)) + break; + strcpy (req_name, next_name); + } +} /* - * Print_Node_List - Print information about the supplied node list (or regular expression) - * Input: node_list - Print information about the supplied node list (or regular expression) + * print_node_list - print information about the supplied node list (or regular expression) + * input: node_list - print information about the supplied node list (or regular expression) */ -void Print_Node_List(char *node_list) { - static time_t Last_Update_Time = (time_t)NULL; - int Start_Inx, End_Inx, Count_Inx, Error_Code, i; - char *str_ptr1, *str_ptr2, *Format, *My_Node_List, This_Node_Name[BUF_SIZE];; - - Error_Code = Load_Node(&Last_Update_Time); - if (Error_Code) { - if (Quiet_Flag != 1) printf("Load_Node error %d\n", Error_Code); +void +print_node_list (char *node_list) { + static time_t last_update_time = (time_t) NULL; + int start_inx, end_inx, count_inx, error_code, i; + char *str_ptr1, *str_ptr2, *format, *my_node_list, + this_node_name[BUF_SIZE];; + + error_code = load_node (&last_update_time); + if (error_code) { + if (quiet_flag != 1) + printf ("load_node error %d\n", error_code); + return; + } + if (quiet_flag == -1) + printf ("last_update_time=%ld\n", (long) last_update_time); + + if (node_list == NULL) { + print_node (NULL); + } + else { + my_node_list = malloc (strlen (node_list) + 1); + if (my_node_list == NULL) { + if (quiet_flag != 1) + fprintf (stderr, + "unable to allocate memory\n"); + abort (); + } + + strcpy (my_node_list, node_list); + str_ptr2 = (char *) strtok_r (my_node_list, ",", &str_ptr1); + while (str_ptr2) { /* break apart by comma separators */ + error_code = + parse_node_name (str_ptr2, &format, + &start_inx, &end_inx, + &count_inx); + if (error_code) { + if (quiet_flag != 1) + fprintf (stderr, + "invalid node name specification: %s\n", + str_ptr2); + break; + } + if (strlen (format) >= sizeof (this_node_name)) { + if (quiet_flag != 1) + fprintf (stderr, + "invalid node name specification: %s\n", + format); + free (format); + break; + } + for (i = start_inx; i <= end_inx; i++) { + if (count_inx == 0) + strncpy (this_node_name, format, + sizeof (this_node_name)); + else + sprintf (this_node_name, format, i); + print_node (this_node_name); + } + free (format); + str_ptr2 = (char *) strtok_r (NULL, ",", &str_ptr1); + } + free (my_node_list); + } /* else */ + +/* free_node_info(); keep data for reuse, cleaned on exit */ return; - } /* if */ - if (Quiet_Flag == -1) printf("Last_Update_Time=%ld\n", (long)Last_Update_Time); - - if (node_list == NULL) { - Print_Node(NULL); - } else { - My_Node_List = malloc(strlen(node_list)+1); - if (My_Node_List == NULL) { - if (Quiet_Flag != 1) fprintf(stderr, "Unable to allocate memory\n"); - abort(); - } /* if */ - - strcpy(My_Node_List, node_list); - str_ptr2 = (char *)strtok_r(My_Node_List, ",", &str_ptr1); - while (str_ptr2) { /* Break apart by comma separators */ - Error_Code = Parse_Node_Name(str_ptr2, &Format, &Start_Inx, &End_Inx, &Count_Inx); - if (Error_Code) { - if (Quiet_Flag != 1) fprintf(stderr, "Invalid node name specification: %s\n", str_ptr2); - break; - } /* if */ - if (strlen(Format) >= sizeof(This_Node_Name)) { - if (Quiet_Flag != 1) fprintf(stderr, "Invalid node name specification: %s\n", Format); - free(Format); - break; - } /* if */ - for (i=Start_Inx; i<=End_Inx; i++) { - if (Count_Inx == 0) - strncpy(This_Node_Name, Format, sizeof(This_Node_Name)); - else - sprintf(This_Node_Name, Format, i); - Print_Node(This_Node_Name); - } /* for */ - free(Format); - str_ptr2 = (char *)strtok_r(NULL, ",", &str_ptr1); - } /* while */ - free(My_Node_List); - } /* else */ - -/* Free_Node_Info(); Keep data for reuse, cleaned on exit */ - return; -} /* Print_Node_List */ +} /* - * Print_Part - Print the specified partition's information - * Input: partition_name - NULL to print all partition information + * print_part - print the specified partition's information + * input: partition_name - NULL to print all partition information */ -void Print_Part(char *partition_name) { - static time_t Last_Update_Time = (time_t)NULL; /* Time desired for data */ - static char *Yes_No[0] = {"NO", "YES"}; - static char *Up_Down[0] = {"DOWN", "UP"}; - char Req_Name[MAX_NAME_LEN]; /* Name of the partition */ - char Next_Name[MAX_NAME_LEN]; /* Name of the next partition */ - int MaxTime; /* -1 if unlimited */ - int MaxNodes; /* -1 if unlimited */ - int TotalNodes; /* Total number of nodes in the partition */ - int TotalCPUs; /* Total number of CPUs in the partition */ - char Nodes[FEATURE_SIZE]; /* Names of nodes in partition */ - char AllowGroups[FEATURE_SIZE]; /* NULL indicates ALL */ - int Key; /* 1 if SLURM distributed key is required for use of partition */ - int StateUp; /* 1 if state is UP */ - int Shared; /* 1 if partition can be shared */ - int Default; /* 1 if default partition */ - int Error_Code; - - Error_Code = Load_Part(&Last_Update_Time); - if (Error_Code) { - if (Quiet_Flag != 1) printf("Load_Part error %d\n", Error_Code); - return; - } /* if */ - if (Quiet_Flag == -1) printf("Last_Update_Time=%ld\n", (long)Last_Update_Time); - - if (partition_name) - strncpy(Req_Name, partition_name, MAX_NAME_LEN); - else - strcpy(Req_Name, ""); /* Start at beginning of partition list */ - - while (1) { - Error_Code = Load_Part_Name(Req_Name, Next_Name, &MaxTime, &MaxNodes, - &TotalNodes, &TotalCPUs, &Key, &StateUp, &Shared, &Default, - Nodes, AllowGroups); - if (Error_Code != 0) { - if (Quiet_Flag != 1) { - if (Error_Code == ENOENT) - printf("No partition %s found\n", Req_Name); - else - printf("Error %d finding information for partition %s\n", Error_Code, Req_Name); - } /* if */ - break; - } /* if */ - - printf("PartitionName=%s Nodes=%s MaxTime=%d MaxNodes=%d Default=%s ", - Req_Name, Nodes, MaxTime, MaxNodes, Yes_No[Default]); - printf("Key=%s State=%s Shared=%s AllowGroups=%s TotalNodes=%d TotalCPUs=%d \n", - Yes_No[Key], Up_Down[StateUp], Yes_No[Shared], AllowGroups, TotalNodes, TotalCPUs); - - if (partition_name || (strlen(Next_Name) == 0)) break; - strcpy(Req_Name, Next_Name); - } /* while */ -/* Free_Part_Info(); Keep data for reuse, cleaned on exit */ -} /* Print_Part */ +void print_part (char *partition_name) { + static time_t last_update_time = (time_t) NULL; /* time desired for data */ + static char *yes_no[0] = { "NO", "YES" }; + static char *up_down[0] = { "DOWN", "UP" }; + char req_name[MAX_NAME_LEN]; /* name of the partition */ + char next_name[MAX_NAME_LEN]; /* name of the next partition */ + int max_time; /* -1 if unlimited */ + int max_nodes; /* -1 if unlimited */ + int total_nodes; /* total number of nodes in the partition */ + int total_cpus; /* total number of cpus in the partition */ + char nodes[FEATURE_SIZE]; /* names of nodes in partition */ + char allow_groups[FEATURE_SIZE];/* NULL indicates all */ + int key; /* 1 if slurm distributed key is required */ + int state_up; /* 1 if state is up */ + int shared; /* 1 if partition can be shared */ + int default_flag; /* 1 if default partition */ + int error_code; + + error_code = load_part (&last_update_time); + if (error_code) { + if (quiet_flag != 1) + printf ("load_part error %d\n", error_code); + return; + } + if (quiet_flag == -1) + printf ("last_update_time=%ld\n", (long) last_update_time); + + if (partition_name) + strncpy (req_name, partition_name, MAX_NAME_LEN); + else + strcpy (req_name, ""); /* start at beginning of partition list */ + + while (1) { + error_code = + load_part_name (req_name, next_name, &max_time, + &max_nodes, &total_nodes, &total_cpus, + &key, &state_up, &shared, &default_flag, + nodes, allow_groups); + if (error_code != 0) { + if (quiet_flag != 1) { + if (error_code == ENOENT) + printf ("no partition %s found\n", + req_name); + else + printf ("error %d finding information for partition %s\n", error_code, req_name); + } + break; + } + + printf ("PartitionName=%s Nodes=%s MaxTime=%d MaxNodes=%d Default=%s ", + req_name, nodes, max_time, max_nodes, yes_no[default_flag]); + printf ("Key=%s State=%s Shared=%s AllowGroups=%s ", + yes_no[key], up_down[state_up], yes_no[shared], allow_groups); + printf ("TotalNodes=%d total_cpus=%d \n", total_nodes, total_cpus); + + if (partition_name || (strlen (next_name) == 0)) + break; + strcpy (req_name, next_name); + } +/* free_part_info(); keep data for reuse, cleaned on exit */ +} /* - * Process_Command - Process the user's command - * Input: argc - count of arguments + * process_command - process the user's command + * input: argc - count of arguments * argv - the arguments - * Ourput: Return code is 0 or errno (ONLY for errors fatal to scontrol) + * ourput: return code is 0 or errno (only for errors fatal to scontrol) */ -int Process_Command(int argc, char *argv[]) { - int Error_Code; - - if ((strcmp(argv[0], "exit") == 0) || - (strcmp(argv[0], "quit") == 0)) { - if (argc > 1) fprintf(stderr, "Too many arguments for keyword:%s\n", argv[0]); - Exit_Flag = 1; - - } else if (strcmp(argv[0], "help") == 0) { - if (argc > 1) fprintf(stderr, "Too many arguments for keyword:%s\n", argv[0]); - Usage(); - - } else if (strcmp(argv[0], "quiet") == 0) { - if (argc > 1) fprintf(stderr, "Too many arguments for keyword:%s\n", argv[0]); - Quiet_Flag = 1; - - } else if (strncmp(argv[0], "reconfigure", 7) == 0) { - if (argc > 2) fprintf(stderr, "Too many arguments for keyword:%s\n", argv[0]); - Error_Code = Reconfigure(); - if ((Error_Code != 0) && (Quiet_Flag != 1)) - fprintf(stderr, "Error %d from reconfigure\n", Error_Code); - - } else if (strcmp(argv[0], "show") == 0) { - if (argc > 3) { - if (Quiet_Flag != 1) fprintf(stderr, "Too many arguments for keyword:%s\n", argv[0]); - } else if (argc < 2) { - if (Quiet_Flag != 1) fprintf(stderr, "Too few arguments for keyword:%s\n", argv[0]); - } else if (strncmp(argv[1],"build", 3) == 0) { - if (argc > 2) - Print_Build(argv[2]); - else - Print_Build(NULL); - } else if (strncmp(argv[1],"jobs", 3) == 0) { - if (Quiet_Flag != 1) printf("keyword:%s entity:%s command not yet implemented\n", argv[0], argv[1]); - } else if (strncmp(argv[1],"nodes", 3) == 0) { - if (argc > 2) - Print_Node_List(argv[2]); - else - Print_Node_List(NULL); - } else if (strncmp(argv[1],"partitions", 3) == 0) { - if (argc > 2) - Print_Part(argv[2]); - else - Print_Part(NULL); - } else if (Quiet_Flag != 1) { - fprintf(stderr, "Invalid entity:%s for keyword:%s \n", argv[1], argv[0]); - } /* if */ - - } else if (strcmp(argv[0], "update") == 0) { - if (argc < 2) { - fprintf(stderr, "Too few arguments for %s keyword\n", argv[0]); - return 0; - } /* if */ - Update_It((argc-1), &argv[1]); - - } else if (strcmp(argv[0], "verbose") == 0) { - if (argc > 1) { - fprintf(stderr, "Too many arguments for %s keyword\n", argv[0]); - } /* if */ - Quiet_Flag = -1; - - } else if (strcmp(argv[0], "version") == 0) { - if (argc > 1) { - fprintf(stderr, "Too many arguments for %s keyword\n", argv[0]); - } /* if */ - printf("%s version 0.1\n", Command_Name); - - } else - fprintf(stderr, "Invalid keyword: %s\n", argv[0]); - - return 0; -} /* Process_Command */ +int +process_command (int argc, char *argv[]) { + int error_code; + + if ((strcmp (argv[0], "exit") == 0) || + (strcmp (argv[0], "quit") == 0)) { + if (argc > 1) + fprintf (stderr, + "too many arguments for keyword:%s\n", + argv[0]); + exit_flag = 1; + + } + else if (strcmp (argv[0], "help") == 0) { + if (argc > 1) + fprintf (stderr, + "too many arguments for keyword:%s\n", + argv[0]); + usage (); + + } + else if (strcmp (argv[0], "quiet") == 0) { + if (argc > 1) + fprintf (stderr, + "too many arguments for keyword:%s\n", + argv[0]); + quiet_flag = 1; + + } + else if (strncmp (argv[0], "reconfigure", 7) == 0) { + if (argc > 2) + fprintf (stderr, + "too many arguments for keyword:%s\n", + argv[0]); + error_code = reconfigure (); + if ((error_code != 0) && (quiet_flag != 1)) + fprintf (stderr, "error %d from reconfigure\n", + error_code); + + } + else if (strcmp (argv[0], "show") == 0) { + if (argc > 3) { + if (quiet_flag != 1) + fprintf (stderr, + "too many arguments for keyword:%s\n", + argv[0]); + } + else if (argc < 2) { + if (quiet_flag != 1) + fprintf (stderr, + "too few arguments for keyword:%s\n", + argv[0]); + } + else if (strncmp (argv[1], "build", 3) == 0) { + if (argc > 2) + print_build (argv[2]); + else + print_build (NULL); + } + else if (strncmp (argv[1], "jobs", 3) == 0) { + if (quiet_flag != 1) + printf ("keyword:%s entity:%s command not yet implemented\n", argv[0], argv[1]); + } + else if (strncmp (argv[1], "nodes", 3) == 0) { + if (argc > 2) + print_node_list (argv[2]); + else + print_node_list (NULL); + } + else if (strncmp (argv[1], "partitions", 3) == 0) { + if (argc > 2) + print_part (argv[2]); + else + print_part (NULL); + } + else if (quiet_flag != 1) { + fprintf (stderr, + "invalid entity:%s for keyword:%s \n", + argv[1], argv[0]); + } + + } + else if (strcmp (argv[0], "update") == 0) { + if (argc < 2) { + fprintf (stderr, "too few arguments for %s keyword\n", + argv[0]); + return 0; + } + update_it ((argc - 1), &argv[1]); + + } + else if (strcmp (argv[0], "verbose") == 0) { + if (argc > 1) { + fprintf (stderr, + "too many arguments for %s keyword\n", + argv[0]); + } + quiet_flag = -1; + + } + else if (strcmp (argv[0], "version") == 0) { + if (argc > 1) { + fprintf (stderr, + "too many arguments for %s keyword\n", + argv[0]); + } + printf ("%s version 0.1\n", command_name); + + } + else + fprintf (stderr, "invalid keyword: %s\n", argv[0]); + + return 0; +} /* - * Update_It - Update the SLURM configuration per the supplied arguments - * Input: argc - count of arguments + * update_it - update the slurm configuration per the supplied arguments + * input: argc - count of arguments * argv - list of arguments - * Output: Returns 0 if no error, errno otherwise + * output: returns 0 if no error, errno otherwise */ -int Update_It(int argc, char *argv[]) { - char *In_Line; - int Error_Code, i, In_Line_Size; - - In_Line_Size = BUF_SIZE; - In_Line = (char *)malloc(In_Line_Size); - if (In_Line == NULL) { - fprintf(stderr, "%s: Error %d allocating memory\n", Command_Name, errno); - return ENOMEM; - } /* if */ - strcpy(In_Line, ""); - - for (i=0; i<argc; i++) { - if ((strlen(In_Line) + strlen(argv[i]) + 2) > In_Line_Size) { - In_Line_Size += BUF_SIZE; - In_Line = (char *)realloc(In_Line, In_Line_Size); - if (In_Line == NULL) { - fprintf(stderr, "%s: Error %d allocating memory\n", Command_Name, errno); +int +update_it (int argc, char *argv[]) { + char *in_line; + int error_code, i, in_line_size; + + in_line_size = BUF_SIZE; + in_line = (char *) malloc (in_line_size); + if (in_line == NULL) { + fprintf (stderr, "%s: error %d allocating memory\n", + command_name, errno); return ENOMEM; - } /* if */ - } /* if */ - - strcat(In_Line, argv[i]); - strcat(In_Line, " "); - } /* for */ - - Error_Code = Update_Config(In_Line); - free(In_Line); - return Error_Code; -} /* Update_It */ - -/* Usage - Show the valid scontrol commands */ -void Usage() { - printf("%s [-q | -v] [<keyword>]\n", Command_Name); - printf(" -q is equivalent to the keyword \"quiet\" described below.\n"); - printf(" -v is equivalent to the keyword \"verbose\" described below.\n"); - printf(" <keyword> may be omitted from the execute line and %s will execute in interactive\n"); - printf(" mode to process multiple keywords (i.e. commands). Valid <entity> values are:\n"); - printf(" build, job, node, and partition. Node names may be sepcified using regular simple \n"); - printf(" expressions. Valid <keyword> values are:\n"); - printf(" exit Terminate this command.\n"); - printf(" help Print this description of use.\n"); - printf(" quiet Print no messages other than error messages.\n"); - printf(" quit Terminate this command.\n"); - printf(" reconfigure Re-read configuration files.\n"); - printf(" show <entity> [<ID>] Display state of identified entity, default is all records.\n"); - printf(" update <options> Update configuration per configuration file format.\n"); - printf(" verbose Enable detailed logging.\n"); - printf(" version Display tool version number.\n"); -} /* Usage */ + } + strcpy (in_line, ""); + + for (i = 0; i < argc; i++) { + if ((strlen (in_line) + strlen (argv[i]) + 2) > in_line_size) { + in_line_size += BUF_SIZE; + in_line = (char *) realloc (in_line, in_line_size); + if (in_line == NULL) { + fprintf (stderr, + "%s: error %d allocating memory\n", + command_name, errno); + return ENOMEM; + } + } + + strcat (in_line, argv[i]); + strcat (in_line, " "); + } + + error_code = update_config (in_line); + free (in_line); + return error_code; +} + +/* usage - show the valid scontrol commands */ +void +usage () { + printf ("%s [-q | -v] [<keyword>]\n", command_name); + printf (" -q is equivalent to the keyword \"quiet\" described below.\n"); + printf (" -v is equivalent to the keyword \"verbose\" described below.\n"); + printf (" <keyword> may be omitted from the execute line and %s will execute in interactive\n"); + printf (" mode to process multiple keywords (i.e. commands). valid <entity> values are:\n"); + printf (" build, job, node, and partition. node names may be sepcified using regular simple \n"); + printf (" expressions. valid <keyword> values are:\n"); + printf (" exit terminate this command.\n"); + printf (" help print this description of use.\n"); + printf (" quiet print no messages other than error messages.\n"); + printf (" quit terminate this command.\n"); + printf (" reconfigure re-read configuration files.\n"); + printf (" show <entity> [<id>] display state of identified entity, default is all records.\n"); + printf (" update <options> update configuration per configuration file format.\n"); + printf (" verbose enable detailed logging.\n"); + printf (" version display tool version number.\n"); +} /* usage */ diff --git a/src/slurmctld/controller.c b/src/slurmctld/controller.c index 7e3a98b4828e8dbe7760bf646873bd3d94d21a23..4d41632fe676221a85bec9f5c95a28ce0f226fcc 100644 --- a/src/slurmctld/controller.c +++ b/src/slurmctld/controller.c @@ -1,14 +1,14 @@ /* - * controller.c - Main control machine daemon for SLURM - * See slurm.h for documentation on external functions and data structures + * controller.c - main control machine daemon for slurm + * see slurm.h for documentation on external functions and data structures * * NOTE: DEBUG_MODULE of read_config requires that it be loaded with * bits_bytes, partition_mgr, read_config, and node_mgr * - * Author: Moe Jette, jette@llnl.gov + * author: moe jette, jette@llnl.gov */ -#ifdef HAVE_CONFIG_H +#ifdef have_config_h # include <config.h> #endif @@ -24,427 +24,565 @@ #include "slurmlib.h" #define BUF_SIZE 1024 +#define NO_VAL (-99) -int Msg_From_Root(void); -void Slurmctld_Req(int sockfd); +int msg_from_root (void); +void slurmctld_req (int sockfd); -main(int argc, char * argv[]) { - int Error_Code; - int child_pid, cli_len, newsockfd, sockfd; - struct sockaddr_in cli_addr, serv_addr; - char Node_Name[MAX_NAME_LEN]; +main (int argc, char *argv[]) { + int error_code; + int child_pid, cli_len, newsockfd, sockfd; + struct sockaddr_in cli_addr, serv_addr; + char node_name[MAX_NAME_LEN]; - Error_Code = Init_SLURM_Conf(); - if (Error_Code) { + error_code = init_slurm_conf (); + if (error_code) { #if DEBUG_SYSTEM - fprintf(stderr, "slurmctld: Init_SLURM_Conf error %d\n", Error_Code); + fprintf (stderr, "slurmctld: init_slurm_conf error %d\n", + error_code); #else - syslog(LOG_ALERT, "slurmctld: Init_SLURM_Conf error %d\n", Error_Code); + syslog (LOG_ALERT, "slurmctld: init_slurm_conf error %d\n", + error_code); #endif - abort(); - } /* if */ + abort (); + } - Error_Code = Read_SLURM_Conf(SLURM_CONF); - if (Error_Code) { + error_code = read_slurm_conf (SLURM_CONF); + if (error_code) { #if DEBUG_SYSTEM - fprintf(stderr, "slurmctld: Error %d from Read_SLURM_Conf reading %s\n", - Error_Code, SLURM_CONF); + fprintf (stderr, + "slurmctld: error %d from read_slurm_conf reading %s\n", + error_code, SLURM_CONF); #else - syslog(LOG_ALERT, "slurmctld: Error %d from Read_SLURM_Conf reading %s\n", - Error_Code, SLURM_CONF); + syslog (LOG_ALERT, + "slurmctld: error %d from read_slurm_conf reading %s\n", + error_code, SLURM_CONF); #endif - abort(); - } /* if */ + abort (); + } - Error_Code = gethostname(Node_Name, MAX_NAME_LEN); - if (Error_Code != 0) { + error_code = gethostname (node_name, MAX_NAME_LEN); + if (error_code != 0) { #if DEBUG_SYSTEM - fprintf(stderr, "slurmctld: Error %d from gethostname\n", Error_Code); + fprintf (stderr, "slurmctld: error %d from gethostname\n", + error_code); #else - syslog(LOG_ALERT, "slurmctld: Error %d from gethostname\n", Error_Code); + syslog (LOG_ALERT, "slurmctld: error %d from gethostname\n", + error_code); #endif - abort(); - } /* if */ - if (strcmp(Node_Name, ControlMachine) != 0) { + abort (); + } + if (strcmp (node_name, control_machine) != 0) { #if DEBUG_SYSTEM - fprintf(stderr, "slurmctld: This machine (%s) is not the primary control machine (%s)\n", - Node_Name, ControlMachine); + fprintf (stderr, + "slurmctld: this machine (%s) is not the primary control machine (%s)\n", + node_name, control_machine); #else - syslog(LOG_ERR, "slurmctld: This machine (%s) is not the primary control machine (%s)\n", - Node_Name, ControlMachine); + syslog (LOG_ERR, + "slurmctld: this machine (%s) is not the primary control machine (%s)\n", + node_name, control_machine); #endif - exit(1); - } /* if */ + exit (1); + } - if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) < 0) { #if DEBUG_SYSTEM - fprintf(stderr, "slurmctld: Error %d from socket\n", errno); + fprintf (stderr, "slurmctld: error %d from socket\n", errno); #else - syslog(LOG_ALERT, "slurmctld: Error %d from socket\n", errno); + syslog (LOG_ALERT, "slurmctld: error %d from socket\n", + errno); #endif - abort(); - } /* if */ - memset(&serv_addr, 0, sizeof(serv_addr)); - serv_addr.sin_family = PF_INET; - serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); - serv_addr.sin_port = htons(SLURMCTLD_PORT); - if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { + abort (); + } + memset (&serv_addr, 0, sizeof (serv_addr)); + serv_addr.sin_family = PF_INET; + serv_addr.sin_addr.s_addr = htonl (INADDR_ANY); + serv_addr.sin_port = htons (SLURMCTLD_PORT); + if (bind (sockfd, (struct sockaddr *) &serv_addr, sizeof (serv_addr)) + < 0) { #if DEBUG_SYSTEM - fprintf(stderr, "slurmctld: Error %d from bind\n", errno); + fprintf (stderr, "slurmctld: error %d from bind\n", errno); #else - syslog(LOG_ALERT, "slurmctld: Error %d from bind\n", errno); + syslog (LOG_ALERT, "slurmctld: error %d from bind\n", errno); #endif - abort(); - } /* if */ - listen(sockfd, 5); - while (1) { - cli_len = sizeof(cli_addr); - if ((newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &cli_len)) < 0) { + abort (); + } + listen (sockfd, 5); + while (1) { + cli_len = sizeof (cli_addr); + if ((newsockfd = + accept (sockfd, (struct sockaddr *) &cli_addr, + &cli_len)) < 0) { #if DEBUG_SYSTEM - fprintf(stderr, "slurmctld: Error %d from accept\n", errno); + fprintf (stderr, "slurmctld: error %d from accept\n", + errno); #else - syslog(LOG_ALERT, "slurmctld: Error %d from accept\n", errno); + syslog (LOG_ALERT, + "slurmctld: error %d from accept\n", errno); #endif - abort(); - } /* if */ + abort (); + } -/* Convert to pthread, TBD */ -Slurmctld_Req(newsockfd); /* Process the request */ -close(newsockfd); /* close the new socket */ +/* convert to pthread, tbd */ + slurmctld_req (newsockfd); /* process the request */ + close (newsockfd); /* close the new socket */ - } /* while */ -} /* main */ + } +} /* main */ /* - * Dump_Build - Dump all build parameters to a buffer - * Input: Buffer_Ptr - Location into which a pointer to the data is to be stored. - * The data buffer is actually allocated by Dump_Part and the + * dump_build - dump all build parameters to a buffer + * input: buffer_ptr - location into which a pointer to the data is to be stored. + * the data buffer is actually allocated by dump_part and the * calling function must free the storage. - * Buffer_Size - Location into which the size of the created buffer is in bytes - * Output: Buffer_Ptr - The pointer is set to the allocated buffer. - * Buffer_Size - Set to size of the buffer in bytes - * Returns 0 if no error, errno otherwise - * NOTE: The buffer at *Buffer_Ptr must be freed by the caller - * NOTE: IF YOU MAKE ANY CHANGES HERE be sure to increment the value of BUILD_STRUCT_VERSION - * and make the corresponding changes to Load_Build_Name in api/build_info.c + * buffer_size - location into which the size of the created buffer is in bytes + * output: buffer_ptr - the pointer is set to the allocated buffer. + * buffer_size - set to size of the buffer in bytes + * returns 0 if no error, errno otherwise + * NOTE: the buffer at *buffer_ptr must be freed by the caller + * NOTE: if you make any changes here be sure to increment the value of BUILD_STRUCT_VERSION + * and make the corresponding changes to load_build_name in api/build_info.c */ -int Dump_Build(char **Buffer_Ptr, int *Buffer_Size) { - char *Buffer; - int Buffer_Offset, Buffer_Allocated, i, Record_Size; - char Out_Line[BUILD_SIZE*2]; - - Buffer_Ptr[0] = NULL; - *Buffer_Size = 0; - Buffer = NULL; - Buffer_Offset = 0; - Buffer_Allocated = 0; - - /* Write haeader, version and time */ - sprintf(Out_Line, HEAD_FORMAT, (unsigned long)time(NULL), BUILD_STRUCT_VERSION); - if (Write_Buffer(&Buffer, &Buffer_Offset, &Buffer_Allocated, Out_Line)) goto cleanup; - - /* Write paramter records */ - sprintf(Out_Line, BUILD_STRUCT2_FORMAT, "BACKUP_INTERVAL", BACKUP_INTERVAL); - if (Write_Buffer(&Buffer, &Buffer_Offset, &Buffer_Allocated, Out_Line)) goto cleanup; - - sprintf(Out_Line, BUILD_STRUCT_FORMAT, "BACKUP_LOCATION", BACKUP_LOCATION); - if (Write_Buffer(&Buffer, &Buffer_Offset, &Buffer_Allocated, Out_Line)) goto cleanup; - - sprintf(Out_Line, BUILD_STRUCT_FORMAT, "CONTROL_DAEMON", CONTROL_DAEMON); - if (Write_Buffer(&Buffer, &Buffer_Offset, &Buffer_Allocated, Out_Line)) goto cleanup; - - sprintf(Out_Line, BUILD_STRUCT2_FORMAT, "CONTROLLER_TIMEOUT", CONTROLLER_TIMEOUT); - if (Write_Buffer(&Buffer, &Buffer_Offset, &Buffer_Allocated, Out_Line)) goto cleanup; - - sprintf(Out_Line, BUILD_STRUCT_FORMAT, "EPILOG", EPILOG); - if (Write_Buffer(&Buffer, &Buffer_Offset, &Buffer_Allocated, Out_Line)) goto cleanup; - - sprintf(Out_Line, BUILD_STRUCT2_FORMAT, "HASH_BASE", HASH_BASE); - if (Write_Buffer(&Buffer, &Buffer_Offset, &Buffer_Allocated, Out_Line)) goto cleanup; - - sprintf(Out_Line, BUILD_STRUCT2_FORMAT, "HEARTBEAT_INTERVAL", HEARTBEAT_INTERVAL); - if (Write_Buffer(&Buffer, &Buffer_Offset, &Buffer_Allocated, Out_Line)) goto cleanup; - - sprintf(Out_Line, BUILD_STRUCT_FORMAT, "INIT_PROGRAM", INIT_PROGRAM); - if (Write_Buffer(&Buffer, &Buffer_Offset, &Buffer_Allocated, Out_Line)) goto cleanup; - - sprintf(Out_Line, BUILD_STRUCT2_FORMAT, "KILL_WAIT", KILL_WAIT); - if (Write_Buffer(&Buffer, &Buffer_Offset, &Buffer_Allocated, Out_Line)) goto cleanup; - - sprintf(Out_Line, BUILD_STRUCT_FORMAT, "PRIORITIZE", PRIORITIZE); - if (Write_Buffer(&Buffer, &Buffer_Offset, &Buffer_Allocated, Out_Line)) goto cleanup; - - sprintf(Out_Line, BUILD_STRUCT_FORMAT, "PROLOG", PROLOG); - if (Write_Buffer(&Buffer, &Buffer_Offset, &Buffer_Allocated, Out_Line)) goto cleanup; - - sprintf(Out_Line, BUILD_STRUCT_FORMAT, "SERVER_DAEMON", SERVER_DAEMON); - if (Write_Buffer(&Buffer, &Buffer_Offset, &Buffer_Allocated, Out_Line)) goto cleanup; - - sprintf(Out_Line, BUILD_STRUCT2_FORMAT, "SERVER_TIMEOUT", SERVER_TIMEOUT); - if (Write_Buffer(&Buffer, &Buffer_Offset, &Buffer_Allocated, Out_Line)) goto cleanup; - - sprintf(Out_Line, BUILD_STRUCT_FORMAT, "SLURM_CONF", SLURM_CONF); - if (Write_Buffer(&Buffer, &Buffer_Offset, &Buffer_Allocated, Out_Line)) goto cleanup; - - sprintf(Out_Line, BUILD_STRUCT_FORMAT, "TMP_FS", TMP_FS); - if (Write_Buffer(&Buffer, &Buffer_Offset, &Buffer_Allocated, Out_Line)) goto cleanup; - - Buffer = realloc(Buffer, Buffer_Offset); - if (Buffer == NULL) { +int +dump_build (char **buffer_ptr, int *buffer_size) +{ + char *buffer; + int buffer_offset, buffer_allocated, i, record_size; + char out_line[BUILD_SIZE * 2]; + + buffer_ptr[0] = NULL; + *buffer_size = 0; + buffer = NULL; + buffer_offset = 0; + buffer_allocated = 0; + + /* write haeader, version and time */ + sprintf (out_line, HEAD_FORMAT, (unsigned long) time (NULL), + BUILD_STRUCT_VERSION); + if (write_buffer + (&buffer, &buffer_offset, &buffer_allocated, out_line)) + goto cleanup; + + /* write paramter records */ + sprintf (out_line, BUILD_STRUCT2_FORMAT, "BACKUP_INTERVAL", + BACKUP_INTERVAL); + if (write_buffer + (&buffer, &buffer_offset, &buffer_allocated, out_line)) + goto cleanup; + + sprintf (out_line, BUILD_STRUCT_FORMAT, "BACKUP_LOCATION", + BACKUP_LOCATION); + if (write_buffer + (&buffer, &buffer_offset, &buffer_allocated, out_line)) + goto cleanup; + + sprintf (out_line, BUILD_STRUCT_FORMAT, "CONTROL_DAEMON", + CONTROL_DAEMON); + if (write_buffer + (&buffer, &buffer_offset, &buffer_allocated, out_line)) + goto cleanup; + + sprintf (out_line, BUILD_STRUCT2_FORMAT, "CONTROLLER_TIMEOUT", + CONTROLLER_TIMEOUT); + if (write_buffer + (&buffer, &buffer_offset, &buffer_allocated, out_line)) + goto cleanup; + + sprintf (out_line, BUILD_STRUCT_FORMAT, "EPILOG", EPILOG); + if (write_buffer + (&buffer, &buffer_offset, &buffer_allocated, out_line)) + goto cleanup; + + sprintf (out_line, BUILD_STRUCT2_FORMAT, "HASH_BASE", HASH_BASE); + if (write_buffer + (&buffer, &buffer_offset, &buffer_allocated, out_line)) + goto cleanup; + + sprintf (out_line, BUILD_STRUCT2_FORMAT, "HEARTBEAT_INTERVAL", + HEARTBEAT_INTERVAL); + if (write_buffer + (&buffer, &buffer_offset, &buffer_allocated, out_line)) + goto cleanup; + + sprintf (out_line, BUILD_STRUCT_FORMAT, "INIT_PROGRAM", INIT_PROGRAM); + if (write_buffer + (&buffer, &buffer_offset, &buffer_allocated, out_line)) + goto cleanup; + + sprintf (out_line, BUILD_STRUCT2_FORMAT, "KILL_WAIT", KILL_WAIT); + if (write_buffer + (&buffer, &buffer_offset, &buffer_allocated, out_line)) + goto cleanup; + + sprintf (out_line, BUILD_STRUCT_FORMAT, "PRIORITIZE", PRIORITIZE); + if (write_buffer + (&buffer, &buffer_offset, &buffer_allocated, out_line)) + goto cleanup; + + sprintf (out_line, BUILD_STRUCT_FORMAT, "PROLOG", PROLOG); + if (write_buffer + (&buffer, &buffer_offset, &buffer_allocated, out_line)) + goto cleanup; + + sprintf (out_line, BUILD_STRUCT_FORMAT, "SERVER_DAEMON", + SERVER_DAEMON); + if (write_buffer + (&buffer, &buffer_offset, &buffer_allocated, out_line)) + goto cleanup; + + sprintf (out_line, BUILD_STRUCT2_FORMAT, "SERVER_TIMEOUT", + SERVER_TIMEOUT); + if (write_buffer + (&buffer, &buffer_offset, &buffer_allocated, out_line)) + goto cleanup; + + sprintf (out_line, BUILD_STRUCT_FORMAT, "SLURM_CONF", SLURM_CONF); + if (write_buffer + (&buffer, &buffer_offset, &buffer_allocated, out_line)) + goto cleanup; + + sprintf (out_line, BUILD_STRUCT_FORMAT, "TMP_FS", TMP_FS); + if (write_buffer + (&buffer, &buffer_offset, &buffer_allocated, out_line)) + goto cleanup; + + buffer = realloc (buffer, buffer_offset); + if (buffer == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "Dump_Build: unable to allocate memory\n"); + fprintf (stderr, "dump_build: unable to allocate memory\n"); #else - syslog(LOG_ALERT, "Dump_Build: unable to allocate memory\n"); + syslog (LOG_ALERT, "dump_build: unable to allocate memory\n"); #endif - abort(); - } /* if */ + abort (); + } - Buffer_Ptr[0] = Buffer; - *Buffer_Size = Buffer_Offset; - return 0; + buffer_ptr[0] = buffer; + *buffer_size = buffer_offset; + return 0; -cleanup: - if (Buffer) free(Buffer); - return EINVAL; -} /* Dump_Build */ + cleanup: + if (buffer) + free (buffer); + return EINVAL; +} /* - * Slurmctld_Req - Process a slurmctld request from the given socket - * Input: sockfd - The socket with a request to be processed + * slurmctld_req - process a slurmctld request from the given socket + * input: sockfd - the socket with a request to be processed */ -void Slurmctld_Req(int sockfd) { - int Error_Code, In_Size, i; - char In_Line[BUF_SIZE], Node_Name[MAX_NAME_LEN]; - int CPUs, RealMemory, TmpDisk; - char *NodeName, *PartName, *TimeStamp; - time_t Last_Update; - clock_t Start_Time; - char *Dump; - int Dump_Size, Dump_Loc; - - In_Size = recv(sockfd, In_Line, sizeof(In_Line), 0); - - /* Allocate: Allocate resources for a job */ - if (strncmp("Allocate", In_Line, 8) == 0) { - Start_Time = clock(); - NodeName = NULL; - Error_Code = Select_Nodes(&In_Line[8], &NodeName); /* Skip over "Allocate" */ +void +slurmctld_req (int sockfd) { + int error_code, in_size, i; + char in_line[BUF_SIZE], node_name[MAX_NAME_LEN]; + int cpus, real_memory, tmp_disk; + char *node_name_ptr, *part_name, *time_stamp; + time_t last_update; + clock_t start_time; + char *dump; + int dump_size, dump_loc; + + in_size = recv (sockfd, in_line, sizeof (in_line), 0); + + /* Allocate: allocate resources for a job */ + if (strncmp ("Allocate", in_line, 8) == 0) { + start_time = clock (); + node_name_ptr = NULL; + error_code = select_nodes (&in_line[8], &node_name_ptr); /* skip "Allocate" */ #if DEBUG_SYSTEM - if (Error_Code) - fprintf(stderr, "Slurmctld_Req: Error %d allocating resources for %s, ", - Error_Code, &In_Line[8]); - else - fprintf(stderr, "Slurmctld_Req: Allocated nodes %s to job %s, ", - NodeName, &In_Line[8]); - fprintf(stderr, "time = %ld usec\n", (long)(clock() - Start_Time)); + if (error_code) + fprintf (stderr, + "slurmctld_req: error %d allocating resources for %s, ", + error_code, &in_line[8]); + else + fprintf (stderr, + "slurmctld_req: allocated nodes %s to job %s, ", + node_name_ptr, &in_line[8]); + fprintf (stderr, "time = %ld usec\n", + (long) (clock () - start_time)); #endif - if (Error_Code == 0) - send(sockfd, NodeName, strlen(NodeName)+1, 0); - else if (Error_Code == EAGAIN) - send(sockfd, "EAGAIN", 7, 0); - else - send(sockfd, "EINVAL", 7, 0); - - if (NodeName) free(NodeName); - - /* DumpBuild: Dump build parameters to a buffer */ - } else if (strncmp("DumpBuild", In_Line, 9) == 0) { - Start_Time = clock(); - Error_Code = Dump_Build(&Dump, &Dump_Size); + if (error_code == 0) + send (sockfd, node_name_ptr, strlen (node_name_ptr) + 1, 0); + else if (error_code == EAGAIN) + send (sockfd, "EAGAIN", 7, 0); + else + send (sockfd, "EINVAL", 7, 0); + + if (node_name_ptr) + free (node_name_ptr); + } + else if (strncmp ("DumpBuild", in_line, 9) == 0) { + start_time = clock (); + error_code = dump_build (&dump, &dump_size); #if DEBUG_SYSTEM - if (Error_Code) - fprintf(stderr, "Slurmctld_Req: Dump_Build error %d, ", Error_Code); - else - fprintf(stderr, "Slurmctld_Req: Dump_Build returning %d bytes, ", Dump_Size); - fprintf(stderr, "time = %ld usec\n", (long)(clock() - Start_Time)); + if (error_code) + fprintf (stderr, + "slurmctld_req: dump_build error %d, ", + error_code); + else + fprintf (stderr, + "slurmctld_req: dump_build returning %d bytes, ", + dump_size); + fprintf (stderr, "time = %ld usec\n", + (long) (clock () - start_time)); #endif - if (Error_Code == 0) { - Dump_Loc = 0; - while (Dump_Size > 0) { - i = send(sockfd, &Dump[Dump_Loc], Dump_Size, 0); - Dump_Loc += i; - Dump_Size -= i; - } /* while */ - } else - send(sockfd, "EINVAL", 7, 0); - if (Dump) free(Dump); - - /* DumpNode: Dump node state information to a buffer */ - } else if (strncmp("DumpNode", In_Line, 8) == 0) { - Start_Time = clock(); - TimeStamp = NULL; - Error_Code = Load_String(&TimeStamp, "LastUpdate=", In_Line); - if (TimeStamp) { - Last_Update = strtol(TimeStamp, (char **)NULL, 10); - free(TimeStamp); - } else - Last_Update = (time_t) 0; - Error_Code = Dump_Node(&Dump, &Dump_Size, &Last_Update); + if (error_code == 0) { + dump_loc = 0; + while (dump_size > 0) { + i = send (sockfd, &dump[dump_loc], dump_size, + 0); + dump_loc += i; + dump_size -= i; + } + } + else + send (sockfd, "EINVAL", 7, 0); + if (dump) + free (dump); + } + else if (strncmp ("DumpNode", in_line, 8) == 0) { + start_time = clock (); + time_stamp = NULL; + error_code = + load_string (&time_stamp, "LastUpdate=", in_line); + if (time_stamp) { + last_update = strtol (time_stamp, (char **) NULL, 10); + free (time_stamp); + } + else + last_update = (time_t) 0; + error_code = dump_node (&dump, &dump_size, &last_update); #if DEBUG_SYSTEM - if (Error_Code) - fprintf(stderr, "Slurmctld_Req: Dump_Node error %d, ", Error_Code); - else - fprintf(stderr, "Slurmctld_Req: Dump_Node returning %d bytes, ", Dump_Size); - fprintf(stderr, "time = %ld usec\n", (long)(clock() - Start_Time)); + if (error_code) + fprintf (stderr, + "slurmctld_req: dump_node error %d, ", + error_code); + else + fprintf (stderr, + "slurmctld_req: dump_node returning %d bytes, ", + dump_size); + fprintf (stderr, "time = %ld usec\n", + (long) (clock () - start_time)); #endif - if (Dump_Size == 0) - send(sockfd, "NOCHANGE", 9, 0); - else if (Error_Code == 0) { - Dump_Loc = 0; - while (Dump_Size > 0) { - i = send(sockfd, &Dump[Dump_Loc], Dump_Size, 0); - Dump_Loc += i; - Dump_Size -= i; - } /* while */ - } else - send(sockfd, "EINVAL", 7, 0); - if (Dump) free(Dump); - - /* DumpPart: Dump partition state information to a buffer */ - } else if (strncmp("DumpPart", In_Line, 8) == 0) { - Start_Time = clock(); - TimeStamp = NULL; - Error_Code = Load_String(&TimeStamp, "LastUpdate=", In_Line); - if (TimeStamp) { - Last_Update = strtol(TimeStamp, (char **)NULL, 10); - free(TimeStamp); - } else - Last_Update = (time_t) 0; - Error_Code = Dump_Part(&Dump, &Dump_Size, &Last_Update); + if (dump_size == 0) + send (sockfd, "nochange", 9, 0); + else if (error_code == 0) { + dump_loc = 0; + while (dump_size > 0) { + i = send (sockfd, &dump[dump_loc], dump_size, + 0); + dump_loc += i; + dump_size -= i; + } + } + else + send (sockfd, "EINVAL", 7, 0); + if (dump) + free (dump); + } + else if (strncmp ("DumpPart", in_line, 8) == 0) { + start_time = clock (); + time_stamp = NULL; + error_code = + load_string (&time_stamp, "LastUpdate=", in_line); + if (time_stamp) { + last_update = strtol (time_stamp, (char **) NULL, 10); + free (time_stamp); + } + else + last_update = (time_t) 0; + error_code = dump_part (&dump, &dump_size, &last_update); #if DEBUG_SYSTEM - if (Error_Code) - fprintf(stderr, "Slurmctld_Req: Dump_Part error %d, ", Error_Code); - else - fprintf(stderr, "Slurmctld_Req: Dump_Part returning %d bytes, ", Dump_Size); - fprintf(stderr, "time = %ld usec\n", (long)(clock() - Start_Time)); + if (error_code) + fprintf (stderr, + "slurmctld_req: dump_part error %d, ", + error_code); + else + fprintf (stderr, + "slurmctld_req: dump_part returning %d bytes, ", + dump_size); + fprintf (stderr, "time = %ld usec\n", + (long) (clock () - start_time)); #endif - if (Dump_Size == 0) - send(sockfd, "NOCHANGE", 9, 0); - else if (Error_Code == 0) { - Dump_Loc = 0; - while (Dump_Size > 0) { - i = send(sockfd, &Dump[Dump_Loc], Dump_Size, 0); - Dump_Loc += i; - Dump_Size -= i; - } /* while */ - } else - send(sockfd, "EINVAL", 7, 0); - if (Dump) free(Dump); - - /* JobSubmit: Submit job to execute, TBD */ - } else if (strncmp("JobSubmit", In_Line, 9) == 0) { - Start_Time = clock(); - TimeStamp = NULL; - Error_Code = EINVAL; + if (dump_size == 0) + send (sockfd, "nochange", 9, 0); + else if (error_code == 0) { + dump_loc = 0; + while (dump_size > 0) { + i = send (sockfd, &dump[dump_loc], dump_size, + 0); + dump_loc += i; + dump_size -= i; + } + } + else + send (sockfd, "EINVAL", 7, 0); + if (dump) + free (dump); + } + else if (strncmp ("JobSubmit", in_line, 9) == 0) { + start_time = clock (); + time_stamp = NULL; + error_code = EINVAL; #if DEBUG_SYSTEM - if (Error_Code) - fprintf(stderr, "Slurmctld_Req: JobSubmit error %d", Error_Code); - else - fprintf(stderr, "Slurmctld_Req: JobSubmit success for %s", &In_Line[10]); - fprintf(stderr, "JobSubmit Time = %ld usec\n", (long)(clock() - Start_Time)); + if (error_code) + fprintf (stderr, "slurmctld_req: job_submit error %d", + error_code); + else + fprintf (stderr, + "slurmctld_req: job_submit success for %s", + &in_line[10]); + fprintf (stderr, "job_submit time = %ld usec\n", + (long) (clock () - start_time)); #endif - if (Error_Code == 0) - send(sockfd, Dump, Dump_Size, 0); - else - send(sockfd, "EINVAL", 7, 0); - - /* JobWillRun: Will job run if submitted, TBD */ - } else if (strncmp("JobWillRun", In_Line, 10) == 0) { - Start_Time = clock(); - TimeStamp = NULL; - Error_Code = EINVAL; + if (error_code == 0) + send (sockfd, dump, dump_size, 0); + else + send (sockfd, "EINVAL", 7, 0); + } + + else if (strncmp ("JobWillRun", in_line, 10) == 0) { + start_time = clock (); + time_stamp = NULL; + error_code = EINVAL; #if DEBUG_SYSTEM - if (Error_Code) - fprintf(stderr, "Slurmctld_Req: JobWillRun error %d", Error_Code); - else - fprintf(stderr, "Slurmctld_Req: JobWillRun success for %s", &In_Line[10]); - fprintf(stderr, "JobWillRun Time = %ld usec\n", (long)(clock() - Start_Time)); + if (error_code) + fprintf (stderr, + "slurmctld_req: job_will_run error %d", + error_code); + else + fprintf (stderr, + "slurmctld_req: job_will_run success for %s", + &in_line[10]); + fprintf (stderr, "job_will_run time = %ld usec\n", + (long) (clock () - start_time)); #endif - if (Error_Code == 0) - send(sockfd, Dump, Dump_Size, 0); - else - send(sockfd, "EINVAL", 7, 0); - - /* NodeConfig: Process node configuration state on check-in */ - } else if (strncmp("NodeConfig", In_Line, 10) == 0) { - Start_Time = clock(); - TimeStamp = NULL; - Error_Code = Load_String (&NodeName, "NodeName=", In_Line); - if (NodeName == NULL) Error_Code = EINVAL; - if (Error_Code == 0) Error_Code = Load_Integer(&CPUs, "CPUs=", In_Line); - if (Error_Code == 0) Error_Code = Load_Integer(&RealMemory, "RealMemory=", In_Line); - if (Error_Code == 0) Error_Code = Load_Integer(&TmpDisk, "TmpDisk=", In_Line); - if (Error_Code == 0) Error_Code = Validate_Node_Specs(NodeName,CPUs,RealMemory,TmpDisk); + if (error_code == 0) + send (sockfd, dump, dump_size, 0); + else + send (sockfd, "EINVAL", 7, 0); + } + else if (strncmp ("NodeConfig", in_line, 10) == 0) { + start_time = clock (); + time_stamp = NULL; + node_name_ptr = NULL; + cpus = real_memory = tmp_disk = NO_VAL; + error_code = load_string (&node_name_ptr, "NodeName=", in_line); + if (node_name == NULL) + error_code = EINVAL; + if (error_code == 0) + error_code = load_integer (&cpus, "CPUs=", in_line); + if (error_code == 0) + error_code = + load_integer (&real_memory, "RealMemory=", + in_line); + if (error_code == 0) + error_code = + load_integer (&tmp_disk, "TmpDisk=", + in_line); + if (error_code == 0) + error_code = + validate_node_specs (node_name_ptr, cpus, + real_memory, tmp_disk); #if DEBUG_SYSTEM - if (Error_Code) - fprintf(stderr, "Slurmctld_Req: NodeConfig error %d for %s", Error_Code, NodeName); - else - fprintf(stderr, "Slurmctld_Req: NodeConfig for %s", NodeName); - fprintf(stderr, "NodeConfig Time = %ld usec\n", (long)(clock() - Start_Time)); + if (error_code) + fprintf (stderr, + "slurmctld_req: node_config error %d for %s", + error_code, node_name_ptr); + else + fprintf (stderr, "slurmctld_req: node_config for %s", + node_name_ptr); + fprintf (stderr, "node_config time = %ld usec\n", + (long) (clock () - start_time)); #endif - if (Error_Code == 0) - send(sockfd, Dump, Dump_Size, 0); - else - send(sockfd, "EINVAL", 7, 0); - if (NodeName) free(NodeName); - - /* Reconfigure: Re-read configuration files */ - } else if (strncmp("Reconfigure", In_Line, 11) == 0) { - Start_Time = clock(); - TimeStamp = NULL; - Error_Code = Init_SLURM_Conf(); - if (Error_Code == 0) Error_Code = Read_SLURM_Conf(SLURM_CONF); + if (error_code == 0) + send (sockfd, dump, dump_size, 0); + else + send (sockfd, "EINVAL", 7, 0); + if (node_name_ptr) + free (node_name_ptr); + } + else if (strncmp ("Reconfigure", in_line, 11) == 0) { + start_time = clock (); + time_stamp = NULL; + error_code = init_slurm_conf (); + if (error_code == 0) + error_code = read_slurm_conf (SLURM_CONF); #if DEBUG_SYSTEM - if (Error_Code) - fprintf(stderr, "Slurmctld_Req: Reconfigure error %d, ", Error_Code); - else - fprintf(stderr, "Slurmctld_Req: Reconfigure completed successfully, "); - fprintf(stderr, "time = %ld usec\n", (long)(clock() - Start_Time)); + if (error_code) + fprintf (stderr, + "slurmctld_req: reconfigure error %d, ", + error_code); + else + fprintf (stderr, + "slurmctld_req: reconfigure completed successfully, "); + fprintf (stderr, "time = %ld usec\n", + (long) (clock () - start_time)); #endif - sprintf(In_Line, "%d", Error_Code); - send(sockfd, In_Line, strlen(In_Line)+1, 0); - - /* Update: Modify the configuration of a job, node, or partition */ - } else if (strncmp("Update", In_Line, 6) == 0) { - Start_Time = clock(); - NodeName = PartName = NULL; - Error_Code = Load_String(&NodeName, "NodeName=", In_Line); - if ((Error_Code == 0) && (NodeName != NULL)) - Error_Code = Update_Node(NodeName, &In_Line[6]); /* Skip over "Update" */ - else { - Error_Code = Load_String(&PartName, "PartitionName=", In_Line); - if ((Error_Code == 0) && (PartName != NULL)) { - Error_Code = Update_Part(PartName, &In_Line[6]); /* Skip over "Update" */ - } /* if */ - } /* else */ + sprintf (in_line, "%d", error_code); + send (sockfd, in_line, strlen (in_line) + 1, 0); + } + else if (strncmp ("Update", in_line, 6) == 0) { + start_time = clock (); + node_name_ptr = part_name = NULL; + error_code = load_string (&node_name_ptr, "NodeName=", in_line); + if ((error_code == 0) && (node_name_ptr != NULL)) + error_code = update_node (node_name_ptr, &in_line[6]); /* skip "Update" */ + else { + error_code = + load_string (&part_name, "PartitionName=", in_line); + if ((error_code == 0) && (part_name != NULL)) + error_code = update_part (part_name, &in_line[6]); /* skip "Update" */ + else + error_code = EINVAL; + } #if DEBUG_SYSTEM - if (Error_Code) { - if (NodeName) - fprintf(stderr, "Slurmctld_Req: Update error %d on node %s, ", Error_Code, NodeName); - else - fprintf(stderr, "Slurmctld_Req: Update error %d on partition %s, ", Error_Code, PartName); - } else { - if (NodeName) - fprintf(stderr, "Slurmctld_Req: Updated node %s, ", NodeName); - else - fprintf(stderr, "Slurmctld_Req: Updated partition %s, ", PartName); - } /* else */ - fprintf(stderr, "time = %ld usec\n", (long)(clock() - Start_Time)); + if (error_code) { + if (node_name_ptr) + fprintf (stderr, + "slurmctld_req: update error %d on node %s, ", + error_code, node_name_ptr); + else if (part_name) + fprintf (stderr, + "slurmctld_req: update error %d on partition %s, ", + error_code, part_name); + else + fprintf (stderr, + "slurmctld_req: update error %d on request %s, ", + error_code, in_line); + + } + else { + if (node_name_ptr) + fprintf (stderr, + "slurmctld_req: updated node %s, ", + node_name_ptr); + else + fprintf (stderr, + "slurmctld_req: updated partition %s, ", + part_name); + } + fprintf (stderr, "time = %ld usec\n", + (long) (clock () - start_time)); #endif - sprintf(In_Line, "%d", Error_Code); - send(sockfd, In_Line, strlen(In_Line)+1, 0); + sprintf (in_line, "%d", error_code); + send (sockfd, in_line, strlen (in_line) + 1, 0); - if (NodeName) free(NodeName); - if (PartName) free(PartName); + if (node_name_ptr) + free (node_name_ptr); + if (part_name) + free (part_name); - } else { + } + else { #if DEBUG_SYSTEM - fprintf(stderr, "Slurmctld_Req: Invalid request %s\n", In_Line); + fprintf (stderr, "slurmctld_req: invalid request %s\n", + in_line); #else - syslog(LOG_WARNING, "Slurmctld_Req: Invalid request %s\n", In_Line); + syslog (LOG_WARNING, "slurmctld_req: invalid request %s\n", + in_line); #endif - send(sockfd, "EINVAL", 7, 0); - } /* else */ - return; -} /* main */ + send (sockfd, "EINVAL", 7, 0); + } + return; +} diff --git a/src/slurmctld/node_mgr.c b/src/slurmctld/node_mgr.c index 569aa3593b67d5784996972170ba0c81660a8f98..07a60fe8cbc399dc6dbaf4fbf0b05e457b4c2ad0 100644 --- a/src/slurmctld/node_mgr.c +++ b/src/slurmctld/node_mgr.c @@ -1,13 +1,13 @@ /* - * node_mgr.c - Manage the node records of SLURM - * See slurm.h for documentation on external functions and data structures + * node_mgr.c - manage the node records of slurm + * see slurm.h for documentation on external functions and data structures * - * Author: Moe Jette, jette@llnl.gov + * author: moe jette, jette@llnl.gov */ #ifdef HAVE_CONFIG_H # include <config.h> -#endif +#endif #include <errno.h> #include <stdio.h> @@ -21,1139 +21,1332 @@ #define NO_VAL (-99) #define SEPCHARS " \n\t" -List Config_List = NULL; /* List of Config_Record entries */ -struct Node_Record *Node_Record_Table_Ptr = NULL; /* Location of the node records */ -char *Node_State_String[] = {"DOWN", "UNKNOWN", "IDLE", "STAGE_IN", "BUSY", "STAGE_OUT", "DRAINED", "DRAINING", "END"}; -int *Hash_Table = NULL; /* Table of hashed indicies into Node_Record */ -struct Config_Record Default_Config_Record; -struct Node_Record Default_Node_Record; -time_t Last_BitMap_Update =(time_t)NULL; /* Time of last node creation or deletion */ -time_t Last_Node_Update =(time_t)NULL; /* Time of last update to Node Records */ -static pthread_mutex_t Node_Mutex= PTHREAD_MUTEX_INITIALIZER; /* Lock for Node and Config info */ - -unsigned *Up_NodeBitMap = NULL; /* Bitmap of nodes are UP */ -unsigned *Idle_NodeBitMap = NULL; /* Bitmap of nodes are IDLE */ - -int Delete_Config_Record(); -void Dump_Hash(); -int Hash_Index(char *name); -void Rehash(); -void Split_Node_Name(char *Name, char *Prefix, char *Suffix, int *Index, int *Digits); +List config_list = NULL; /* list of config_record entries */ +struct node_record *node_record_table_ptr = NULL; /* location of the node records */ +char *node_state_string[] = + { "DOWN", "UNKNOWN", "IDLE", "STAGE_IN", "BUSY", "STAGE_OUT", +"DRAINED", "DRAINING", "END" }; +int *hash_table = NULL; /* table of hashed indicies into node_record */ +struct config_record default_config_record; +struct node_record default_node_record; +time_t last_bitmap_update = (time_t) NULL; /* time of last node creation or deletion */ +time_t last_node_update = (time_t) NULL; /* time of last update to node records */ +static pthread_mutex_t node_mutex = PTHREAD_MUTEX_INITIALIZER; /* lock for node and config info */ + +unsigned *up_node_bitmap = NULL; /* bitmap of nodes are up */ +unsigned *idle_node_bitmap = NULL; /* bitmap of nodes are idle */ + +int delete_config_record (); +void dump_hash (); +int hash_index (char *name); +void rehash (); +void split_node_name (char *name, char *prefix, char *suffix, int *index, + int *digits); #if DEBUG_MODULE /* main is used here for testing purposes only */ -main(int argc, char * argv[]) { - int Error_Code, size; - char *Out_Line; - unsigned *Map1, *Map2; - unsigned U_Map[2]; - struct Config_Record *Config_Ptr; - struct Node_Record *Node_Ptr; - char *Dump; - int Dump_Size; - time_t Update_Time; - char Update_Spec[] = "State=DRAINING"; - - /* Bitmap setup */ - Node_Record_Count = 97; - size = (Node_Record_Count + 7) / 8; - Map1 = malloc(size); - memset(Map1, 0, size); - BitMapSet(Map1, 7); - BitMapSet(Map1, 23); - BitMapSet(Map1, 71); - Map2 = BitMapCopy(Map1); - BitMapSet(Map2, 11); - Node_Record_Count = 0; - - /* Now check out configuration and node structure functions */ - Error_Code = Init_Node_Conf(); - if (Error_Code) printf("ERROR: Init_Node_Conf error %d\n", Error_Code); - Default_Config_Record.CPUs = 12; - Default_Config_Record.RealMemory = 345; - Default_Config_Record.TmpDisk = 67; - Default_Config_Record.Weight = 89; - Default_Node_Record.LastResponse = (time_t)678; - - Config_Ptr = Create_Config_Record(&Error_Code); - if (Error_Code) printf("ERROR: Create_Config_Record error %d\n", Error_Code); - if (Config_Ptr->CPUs != 12) printf("ERROR: Config default CPUs not set\n"); - if (Config_Ptr->RealMemory != 345) printf("ERROR: Config default RealMemory not set\n"); - if (Config_Ptr->TmpDisk != 67) printf("ERROR: Config default TmpDisk not set\n"); - if (Config_Ptr->Weight != 89) printf("ERROR: Config default Weight not set\n"); - Config_Ptr->Feature = "for_lx01,lx02"; - Config_Ptr->Nodes = "lx[01-02]"; - Config_Ptr->NodeBitMap = Map1; - Node_Ptr = Create_Node_Record(&Error_Code, Config_Ptr, "lx01"); - if (Error_Code) printf("ERROR: Create_Node_Record error %d\n", Error_Code); - Node_Ptr = Create_Node_Record(&Error_Code, Config_Ptr, "lx02"); - if (Error_Code) printf("ERROR: Create_Node_Record error %d\n", Error_Code); - - Up_NodeBitMap = &U_Map[0]; - Idle_NodeBitMap = &U_Map[1]; - - Error_Code = Update_Node("lx[01-02]", Update_Spec); - if (Error_Code) printf("ERROR: Update_Node error1 %d\n", Error_Code); - if (Node_Ptr->NodeState != STATE_DRAINING) - printf("ERROR: Update_Node error2 NodeState=%d\n", Node_Ptr->NodeState); - Config_Ptr = Create_Config_Record(&Error_Code); - Config_Ptr->CPUs = 543; - Config_Ptr->Nodes = "lx[03-20]"; - Config_Ptr->Feature = "for_lx03,lx04"; - Config_Ptr->NodeBitMap = Map2; - Node_Ptr = Create_Node_Record(&Error_Code, Config_Ptr, "lx03"); - if (Error_Code) printf("ERROR: Create_Node_Record error %d\n", Error_Code); - if (Node_Ptr->LastResponse != (time_t)678) printf("ERROR: Node default LastResponse not set\n"); - if (Node_Ptr->CPUs != 543) printf("ERROR: Node default CPUs not set\n"); - if (Node_Ptr->RealMemory != 345) printf("ERROR: Node default RealMemory not set\n"); - if (Node_Ptr->TmpDisk != 67) printf("ERROR: Node default TmpDisk not set\n"); - Node_Ptr = Create_Node_Record(&Error_Code, Config_Ptr, "lx04"); - if (Error_Code) printf("ERROR: Create_Node_Record error %d\n", Error_Code); - - Error_Code = NodeName2BitMap("lx[01-02],lx04", &Map1); - if (Error_Code) printf("ERROR: NodeName2BitMap error %d\n", Error_Code); - Error_Code = BitMap2NodeName(Map1, &Out_Line); - if (Error_Code) printf("ERROR: BitMap2NodeName error %d\n", Error_Code); - if (strcmp(Out_Line, "lx[01-02],lx04") != 0) - printf("ERROR: BitMap2NodeName results bad %s vs %s\n", Out_Line, "lx[01-02],lx04"); - free(Map1); - free(Out_Line); - - Update_Time = (time_t)0; - U_Map[0] = 0xdeadbeef; - U_Map[1] = 0xbeefdead; - Error_Code = Validate_Node_Specs("lx01", 12, 345, 67); - if (Error_Code) printf("ERROR: Validate_Node_Specs error1\n"); - Error_Code = Dump_Node(&Dump, &Dump_Size, &Update_Time); - if (Error_Code) printf("ERROR: Dump_Node error %d\n", Error_Code); - printf("NOTE: We expect Validate_Node_Specs to report bad CPU, RealMemory and TmpDisk on lx01\n"); - Error_Code = Validate_Node_Specs("lx01", 1, 2, 3); - if (Error_Code != EINVAL) printf("ERROR: Validate_Node_Specs error2\n"); - - Rehash(); - Dump_Hash(); - Node_Ptr = Find_Node_Record("lx02"); - if (Node_Ptr == 0) - printf("ERROR: Find_Node_Record failure 1\n"); - else if (strcmp(Node_Ptr->Name, "lx02") != 0) - printf("ERROR: Find_Node_Record failure 2\n"); - else if (Node_Ptr->LastResponse != (time_t)678) - printf("ERROR: Node default LastResponse not set\n"); - printf("NOTE: We expect Delete_Node_Record to report not finding a record for lx10\n"); - Error_Code = Delete_Node_Record("lx10"); - if (Error_Code != ENOENT) printf("ERROR: Delete_Node_Record failure 1\n"); - Error_Code = Delete_Node_Record("lx02"); - if (Error_Code != 0) printf("ERROR: Delete_Node_Record failure 2\n"); - printf("NOTE: We expect Find_Node_Record to report not finding a record for lx02\n"); - Node_Ptr = Find_Node_Record("lx02"); - if (Node_Ptr != 0) printf("ERROR: Find_Node_Record failure 3\n"); - - exit(0); -} /* main */ +main (int argc, char *argv[]) { + int error_code, size; + char *out_line; + unsigned *map1, *map2; + unsigned u_map[2]; + struct config_record *config_ptr; + struct node_record *node_ptr; + char *dump; + int dump_size; + time_t update_time; + char update_spec[] = "State=DRAINING"; + + /* bitmap setup */ + node_record_count = 97; + size = (node_record_count + 7) / 8; + map1 = malloc (size); + memset (map1, 0, size); + bitmap_set (map1, 7); + bitmap_set (map1, 23); + bitmap_set (map1, 71); + map2 = bitmap_copy (map1); + bitmap_set (map2, 11); + node_record_count = 0; + + /* now check out configuration and node structure functions */ + error_code = init_node_conf (); + if (error_code) + printf ("ERROR: init_node_conf error %d\n", error_code); + default_config_record.cpus = 12; + default_config_record.real_memory = 345; + default_config_record.tmp_disk = 67; + default_config_record.weight = 89; + default_node_record.last_response = (time_t) 678; + + config_ptr = create_config_record (&error_code); + if (error_code) + printf ("ERROR: create_config_record error %d\n", error_code); + if (config_ptr->cpus != 12) + printf ("ERROR: config default cpus not set\n"); + if (config_ptr->real_memory != 345) + printf ("ERROR: config default real_memory not set\n"); + if (config_ptr->tmp_disk != 67) + printf ("ERROR: config default tmp_disk not set\n"); + if (config_ptr->weight != 89) + printf ("ERROR: config default weight not set\n"); + config_ptr->feature = "for_lx01,lx02"; + config_ptr->nodes = "lx[01-02]"; + config_ptr->node_bitmap = map1; + node_ptr = create_node_record (&error_code, config_ptr, "lx01"); + if (error_code) + printf ("ERROR: create_node_record error %d\n", error_code); + node_ptr = create_node_record (&error_code, config_ptr, "lx02"); + if (error_code) + printf ("ERROR: create_node_record error %d\n", error_code); + + up_node_bitmap = &u_map[0]; + idle_node_bitmap = &u_map[1]; + + error_code = update_node ("lx[01-02]", update_spec); + if (error_code) + printf ("ERROR: update_node error1 %d\n", error_code); + if (node_ptr->node_state != STATE_DRAINING) + printf ("ERROR: update_node error2 node_state=%d\n", + node_ptr->node_state); + config_ptr = create_config_record (&error_code); + config_ptr->cpus = 543; + config_ptr->nodes = "lx[03-20]"; + config_ptr->feature = "for_lx03,lx04"; + config_ptr->node_bitmap = map2; + node_ptr = create_node_record (&error_code, config_ptr, "lx03"); + if (error_code) + printf ("ERROR: create_node_record error %d\n", error_code); + if (node_ptr->last_response != (time_t) 678) + printf ("ERROR: node default last_response not set\n"); + if (node_ptr->cpus != 543) + printf ("ERROR: node default cpus not set\n"); + if (node_ptr->real_memory != 345) + printf ("ERROR: node default real_memory not set\n"); + if (node_ptr->tmp_disk != 67) + printf ("ERROR: node default tmp_disk not set\n"); + node_ptr = create_node_record (&error_code, config_ptr, "lx04"); + if (error_code) + printf ("ERROR: create_node_record error %d\n", error_code); + + error_code = node_name2bitmap ("lx[01-02],lx04", &map1); + if (error_code) + printf ("ERROR: node_name2bitmap error %d\n", error_code); + error_code = bitmap2node_name (map1, &out_line); + if (error_code) + printf ("ERROR: bitmap2node_name error %d\n", error_code); + if (strcmp (out_line, "lx[01-02],lx04") != 0) + printf ("ERROR: bitmap2node_name results bad %s vs %s\n", + out_line, "lx[01-02],lx04"); + free (map1); + free (out_line); + + update_time = (time_t) 0; + u_map[0] = 0xdeadbeef; + u_map[1] = 0xbeefdead; + error_code = validate_node_specs ("lx01", 12, 345, 67); + if (error_code) + printf ("ERROR: validate_node_specs error1\n"); + error_code = dump_node (&dump, &dump_size, &update_time); + if (error_code) + printf ("ERROR: dump_node error %d\n", error_code); + printf ("NOTE: we expect validate_node_specs to report bad cpu, real_memory and tmp_disk on lx01\n"); + error_code = validate_node_specs ("lx01", 1, 2, 3); + if (error_code != EINVAL) + printf ("ERROR: validate_node_specs error2\n"); + + rehash (); + dump_hash (); + node_ptr = find_node_record ("lx02"); + if (node_ptr == 0) + printf ("ERROR: find_node_record failure 1\n"); + else if (strcmp (node_ptr->name, "lx02") != 0) + printf ("ERROR: find_node_record failure 2\n"); + else if (node_ptr->last_response != (time_t) 678) + printf ("ERROR: node default last_response not set\n"); + printf ("NOTE: we expect delete_node_record to report not finding a record for lx10\n"); + error_code = delete_node_record ("lx10"); + if (error_code != ENOENT) + printf ("ERROR: delete_node_record failure 1\n"); + error_code = delete_node_record ("lx02"); + if (error_code != 0) + printf ("ERROR: delete_node_record failure 2\n"); + printf ("NOTE: we expect find_node_record to report not finding a record for lx02\n"); + node_ptr = find_node_record ("lx02"); + if (node_ptr != 0) + printf ("ERROR: find_node_record failure 3\n"); + + exit (0); +} #endif /* - * BitMap2NodeName - Given a bitmap, build a node list representation - * Input: BitMap - Bitmap pointer - * Node_List - Place to put node list - * Output: Node_List - Set to node list or NULL on error - * Returns 0 if no error, errno otherwise - * NOTE: Consider returning the node list as a regular expression if helpful - * NOTE: The caller must free memory at Node_List when no longer required + * bitmap2node_name - given a bitmap, build a node list representation + * input: bitmap - bitmap pointer + * node_list - place to put node list + * output: node_list - set to node list or NULL on error + * returns 0 if no error, errno otherwise + * NOTE: consider returning the node list as a regular expression if helpful + * NOTE: the caller must free memory at node_list when no longer required */ -int BitMap2NodeName(unsigned *BitMap, char **Node_List) { - int Error_Code, Node_List_Size, i; - struct Node_Record *Node_Ptr; - char Prefix[MAX_NAME_LEN], Suffix[MAX_NAME_LEN]; - char Format[MAX_NAME_LEN], Temp[MAX_NAME_LEN]; - char Last_Prefix[MAX_NAME_LEN], Last_Suffix[MAX_NAME_LEN]; - int First_Index, Last_Index, Index, Digits; - unsigned mask; - - Node_List[0] = NULL; - Node_List_Size = 0; - if (BitMap == NULL) { +int bitmap2node_name (unsigned *bitmap, char **node_list) { + int error_code, node_list_size, i; + struct node_record *node_ptr; + char prefix[MAX_NAME_LEN], suffix[MAX_NAME_LEN]; + char format[MAX_NAME_LEN], temp[MAX_NAME_LEN]; + char last_prefix[MAX_NAME_LEN], last_suffix[MAX_NAME_LEN]; + int first_index, last_index, index, digits; + unsigned mask; + + node_list[0] = NULL; + node_list_size = 0; + if (bitmap == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "NodeName2BitMap: BitMap is NULL\n"); + fprintf (stderr, "node_name2bitmap: bitmap is NULL\n"); #else - syslog(LOG_ERR, "NodeName2BitMap: BitMap is NULL\n"); + syslog (LOG_ERR, "node_name2bitmap: bitmap is NULL\n"); #endif - abort(); - } /* if */ + abort (); + } - Node_List[0] = malloc(BUF_SIZE); - if (Node_List[0] == NULL) { + node_list[0] = malloc (BUF_SIZE); + if (node_list[0] == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "BitMap2NodeName: Can not allocate memory\n"); + fprintf (stderr, + "bitmap2node_name: can not allocate memory\n"); #else - syslog(LOG_ALERT, "BitMap2NodeName: Can not allocate memory\n"); + syslog (LOG_ALERT, + "bitmap2node_name: can not allocate memory\n"); #endif - abort(); - } /* if */ - strcpy(Node_List[0], ""); - - strcpy(Last_Prefix, ""); - strcpy(Last_Suffix, ""); - for (i=0; i<Node_Record_Count; i++) { - if (Node_List_Size < (strlen(Node_List[0])+MAX_NAME_LEN*3)) { - Node_List_Size += BUF_SIZE; - Node_List[0] = realloc(Node_List[0], Node_List_Size); - if (Node_List[0] == NULL) { + abort (); + } + strcpy (node_list[0], ""); + + strcpy (last_prefix, ""); + strcpy (last_suffix, ""); + for (i = 0; i < node_record_count; i++) { + if (node_list_size < + (strlen (node_list[0]) + MAX_NAME_LEN * 3)) { + node_list_size += BUF_SIZE; + node_list[0] = realloc (node_list[0], node_list_size); + if (node_list[0] == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "BitMap2NodeName: Can not allocate memory\n"); + fprintf (stderr, + "bitmap2node_name: can not allocate memory\n"); #else - syslog(LOG_ALERT, "BitMap2NodeName: Can not allocate memory\n"); + syslog (LOG_ALERT, + "bitmap2node_name: can not allocate memory\n"); #endif - abort(); - } /* if */ - } /* if need more memory */ - if (BitMapValue(BitMap, i) == 0) continue; - Split_Node_Name(Node_Record_Table_Ptr[i].Name, Prefix, Suffix, &Index, &Digits); - if ((Index == (Last_Index+1)) && /* Next in sequence */ - (strcmp(Last_Prefix, Prefix) == 0) && - (strcmp(Last_Suffix, Suffix) == 0)) { - Last_Index = Index; - continue; - } /* if */ - if ((strlen(Last_Prefix) != 0) || /* End of a sequence */ - (strlen(Last_Suffix) != 0)) { - if (strlen(Node_List[0]) > 0) strcat(Node_List[0],","); - strcat(Node_List[0], Last_Prefix); - if (First_Index != Last_Index) strcat(Node_List[0], "["); - strcpy(Format, "%0"); - sprintf(&Format[2], "%dd", Digits); - sprintf(Temp, Format, First_Index); - strcat(Node_List[0], Temp); - if (First_Index != Last_Index) { - strcat(Node_List[0], "-"); - strcpy(Format, "%0"); - sprintf(&Format[2], "%dd]", Digits); - sprintf(Temp, Format, Last_Index); - strcat(Node_List[0], Temp); - } /* if */ - strcat(Node_List[0], Last_Suffix); - strcpy(Last_Prefix, ""); - strcpy(Last_Suffix, ""); - } /* if */ - if (Index == NO_VAL) { - if (strlen(Node_List[0]) > 0) strcat(Node_List[0],","); - strcat(Node_List[0], Node_Record_Table_Ptr[i].Name); - } else { - strcpy(Last_Prefix, Prefix); - strcpy(Last_Suffix, Suffix); - First_Index = Last_Index = Index; - } /* else */ - } /* for */ - - if ((strlen(Last_Prefix) != 0) || /* End of a sequence */ - (strlen(Last_Suffix) != 0)) { - if (strlen(Node_List[0]) > 0) strcat(Node_List[0],","); - strcat(Node_List[0], Last_Prefix); - if (First_Index != Last_Index) strcat(Node_List[0], "["); - strcpy(Format, "%0"); - sprintf(&Format[2], "%dd", Digits); - sprintf(Temp, Format, First_Index); - strcat(Node_List[0], Temp); - if (First_Index != Last_Index) { - strcat(Node_List[0], "-"); - strcpy(Format, "%0"); - sprintf(&Format[2], "%dd]", Digits); - sprintf(Temp, Format, Last_Index); - strcat(Node_List[0], Temp); - } /* if */ - strcat(Node_List[0], Last_Suffix); - } /* if */ - Node_List[0] = realloc(Node_List[0], strlen(Node_List[0])+1); - return 0; -} /* BitMap2NodeName */ + abort (); + } + } + if (bitmap_value (bitmap, i) == 0) + continue; + split_node_name (node_record_table_ptr[i].name, prefix, + suffix, &index, &digits); + if ((index == (last_index + 1)) && /* next in sequence */ + (strcmp (last_prefix, prefix) == 0) && + (strcmp (last_suffix, suffix) == 0)) { + last_index = index; + continue; + } + if ((strlen (last_prefix) != 0) || /* end of a sequence */ + (strlen (last_suffix) != 0)) { + if (strlen (node_list[0]) > 0) + strcat (node_list[0], ","); + strcat (node_list[0], last_prefix); + if (first_index != last_index) + strcat (node_list[0], "["); + strcpy (format, "%0"); + sprintf (&format[2], "%dd", digits); + sprintf (temp, format, first_index); + strcat (node_list[0], temp); + if (first_index != last_index) { + strcat (node_list[0], "-"); + strcpy (format, "%0"); + sprintf (&format[2], "%dd]", digits); + sprintf (temp, format, last_index); + strcat (node_list[0], temp); + } + strcat (node_list[0], last_suffix); + strcpy (last_prefix, ""); + strcpy (last_suffix, ""); + } + if (index == NO_VAL) { + if (strlen (node_list[0]) > 0) + strcat (node_list[0], ","); + strcat (node_list[0], node_record_table_ptr[i].name); + } + else { + strcpy (last_prefix, prefix); + strcpy (last_suffix, suffix); + first_index = last_index = index; + } + } + + if ((strlen (last_prefix) != 0) || /* end of a sequence */ + (strlen (last_suffix) != 0)) { + if (strlen (node_list[0]) > 0) + strcat (node_list[0], ","); + strcat (node_list[0], last_prefix); + if (first_index != last_index) + strcat (node_list[0], "["); + strcpy (format, "%0"); + sprintf (&format[2], "%dd", digits); + sprintf (temp, format, first_index); + strcat (node_list[0], temp); + if (first_index != last_index) { + strcat (node_list[0], "-"); + strcpy (format, "%0"); + sprintf (&format[2], "%dd]", digits); + sprintf (temp, format, last_index); + strcat (node_list[0], temp); + } + strcat (node_list[0], last_suffix); + } + node_list[0] = realloc (node_list[0], strlen (node_list[0]) + 1); + return 0; +} /* - * Create_Config_Record - Create a Config_Record entry, append it to the Config_List, + * create_config_record - create a config_record entry, append it to the config_list, * and set is values to the defaults. - * Input: Error_Code - Pointer to an error code - * Output: Returns pointer to the Config_Record - * Error_Code - set to zero if no error, errno otherwise - * NOTE: The pointer returned is allocated memory that must be freed when no longer needed. + * input: error_code - pointer to an error code + * output: returns pointer to the config_record + * error_code - set to zero if no error, errno otherwise + * NOTE: the pointer returned is allocated memory that must be freed when no longer needed. */ -struct Config_Record *Create_Config_Record(int *Error_Code) { - struct Config_Record *Config_Point; - - Last_Node_Update = time(NULL); - Config_Point = (struct Config_Record *)malloc(sizeof(struct Config_Record)); - if (Config_Point == (struct Config_Record *)NULL) { +struct config_record * create_config_record (int *error_code) { + struct config_record *config_point; + + last_node_update = time (NULL); + config_point = + (struct config_record *) + malloc (sizeof (struct config_record)); + if (config_point == (struct config_record *) NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "Create_Config_Record: unable to allocate memory\n"); + fprintf (stderr, + "create_config_record: unable to allocate memory\n"); #else - syslog(LOG_ALERT, "Create_Config_Record: unable to allocate memory\n"); + syslog (LOG_ALERT, + "create_config_record: unable to allocate memory\n"); #endif - abort(); - } /* if */ - - /* Set default values */ - Config_Point->CPUs = Default_Config_Record.CPUs; - Config_Point->RealMemory = Default_Config_Record.RealMemory; - Config_Point->TmpDisk = Default_Config_Record.TmpDisk; - Config_Point->Weight = Default_Config_Record.Weight; - Config_Point->Nodes = NULL; - Config_Point->NodeBitMap = NULL; + abort (); + } + + /* set default values */ + config_point->cpus = default_config_record.cpus; + config_point->real_memory = default_config_record.real_memory; + config_point->tmp_disk = default_config_record.tmp_disk; + config_point->weight = default_config_record.weight; + config_point->nodes = NULL; + config_point->node_bitmap = NULL; #if DEBUG_SYSTEM - Config_Point->Magic = CONFIG_MAGIC; + config_point->magic = CONFIG_MAGIC; #endif - if (Default_Config_Record.Feature) { - Config_Point->Feature = (char *)malloc(strlen(Default_Config_Record.Feature)+1); - if (Config_Point->Feature == (char *)NULL) { + if (default_config_record.feature) { + config_point->feature = + (char *) + malloc (strlen (default_config_record.feature) + 1); + if (config_point->feature == (char *) NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "Create_Config_Record: unable to allocate memory\n"); + fprintf (stderr, + "create_config_record: unable to allocate memory\n"); #else - syslog(LOG_ALERT, "Create_Config_Record: unable to allocate memory\n"); + syslog (LOG_ALERT, + "create_config_record: unable to allocate memory\n"); #endif - abort(); - } /* if */ - strcpy(Config_Point->Feature, Default_Config_Record.Feature); - } else - Config_Point->Feature = (char *)NULL; + abort (); + } + strcpy (config_point->feature, default_config_record.feature); + } + else + config_point->feature = (char *) NULL; - if (list_append(Config_List, Config_Point) == NULL) { + if (list_append (config_list, config_point) == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "Create_Config_Record: unable to allocate memory\n"); + fprintf (stderr, + "create_config_record: unable to allocate memory\n"); #else - syslog(LOG_ALERT, "Create_Config_Record: unable to allocate memory\n"); + syslog (LOG_ALERT, + "create_config_record: unable to allocate memory\n"); #endif - abort(); - } /* if */ + abort (); + } - return Config_Point; -} /* Create_Config_Record */ + return config_point; +} /* - * Create_Node_Record - Create a node record - * Input: Error_Code - Location to store error value in - * Config_Point - Pointer to node's configuration information - * Node_Name - Name of the node - * Output: Error_Code - Set to zero if no error, errno otherwise - * Returns a pointer to the record or NULL if error - * NOTE The record's values are initialized to those of Default_Node_Record, Node_Name and - * Config_Point's CPUs, RealMemory, and TmpDisk values - * NOTE: Allocates memory that should be freed with Delete_Part_Record + * create_node_record - create a node record + * input: error_code - location to store error value in + * config_point - pointer to node's configuration information + * node_name - name of the node + * output: error_code - set to zero if no error, errno otherwise + * returns a pointer to the record or NULL if error + * note the record's values are initialized to those of default_node_record, node_name and + * config_point's cpus, real_memory, and tmp_disk values + * NOTE: allocates memory that should be freed with delete_part_record */ -struct Node_Record *Create_Node_Record(int *Error_Code, struct Config_Record *Config_Point, - char *Node_Name) { - struct Node_Record *Node_Record_Point; - int Old_Buffer_Size, New_Buffer_Size; +struct node_record * create_node_record (int *error_code, struct config_record *config_point, + char *node_name) { + struct node_record *node_record_point; + int old_buffer_size, new_buffer_size; - *Error_Code = 0; - Last_Node_Update = time(NULL); + *error_code = 0; + last_node_update = time (NULL); - if (Config_Point == NULL) { + if (config_point == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "Create_Node_Record: Invalid Config_Point\n"); + fprintf (stderr, + "create_node_record: invalid config_point\n"); #else - syslog(LOG_ALERT, "Create_Node_Record: Invalid Config_Point\n"); + syslog (LOG_ALERT, + "create_node_record: invalid config_point\n"); #endif - abort(); - } /* if */ - if ((Node_Name == NULL) || (strlen(Node_Name) >= MAX_NAME_LEN)) { + abort (); + } + if ((node_name == NULL) || (strlen (node_name) >= MAX_NAME_LEN)) { #if DEBUG_SYSTEM - fprintf(stderr, "Create_Node_Record: Invalid Node_Name %s\n", Node_Name); + fprintf (stderr, "create_node_record: invalid node_name %s\n", + node_name); #else - syslog(LOG_ALERT, "Create_Node_Record: Invalid Node_Name %s\n", Node_Name); + syslog (LOG_ALERT, + "create_node_record: invalid node_name %s\n", + node_name); #endif - abort(); - } /* if */ - /* Round up the buffer size to reduce overhead of realloc */ - Old_Buffer_Size = (Node_Record_Count) * sizeof(struct Node_Record); - Old_Buffer_Size = ((int)((Old_Buffer_Size / BUF_SIZE) + 1)) * BUF_SIZE; - New_Buffer_Size = (Node_Record_Count+1) * sizeof(struct Node_Record); - New_Buffer_Size = ((int)((New_Buffer_Size / BUF_SIZE) + 1)) * BUF_SIZE; - if (Node_Record_Count == 0) - Node_Record_Table_Ptr = (struct Node_Record *)malloc(New_Buffer_Size); - else if (Old_Buffer_Size != New_Buffer_Size) - Node_Record_Table_Ptr = (struct Node_Record *)realloc(Node_Record_Table_Ptr, New_Buffer_Size); - - if (Node_Record_Table_Ptr == NULL) { + abort (); + } + /* round up the buffer size to reduce overhead of realloc */ + old_buffer_size = (node_record_count) * sizeof (struct node_record); + old_buffer_size = + ((int) ((old_buffer_size / BUF_SIZE) + 1)) * BUF_SIZE; + new_buffer_size = + (node_record_count + 1) * sizeof (struct node_record); + new_buffer_size = + ((int) ((new_buffer_size / BUF_SIZE) + 1)) * BUF_SIZE; + if (node_record_count == 0) + node_record_table_ptr = + (struct node_record *) malloc (new_buffer_size); + else if (old_buffer_size != new_buffer_size) + node_record_table_ptr = + (struct node_record *) realloc (node_record_table_ptr, + new_buffer_size); + + if (node_record_table_ptr == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "Create_Node_Record: unable to allocate memory\n"); + fprintf (stderr, + "create_node_record: unable to allocate memory\n"); #else - syslog(LOG_ALERT, "Create_Node_Record: unable to allocate memory\n"); + syslog (LOG_ALERT, + "create_node_record: unable to allocate memory\n"); #endif - abort(); - } /* if */ - - Node_Record_Point = Node_Record_Table_Ptr + (Node_Record_Count++); - strcpy(Node_Record_Point->Name, Node_Name); - Node_Record_Point->NodeState = Default_Node_Record.NodeState; - Node_Record_Point->LastResponse = Default_Node_Record.LastResponse; - Node_Record_Point->Config_Ptr = Config_Point; - Node_Record_Point->Partition_Ptr = NULL; - /* These values will be overwritten when the node actually registers */ - Node_Record_Point->CPUs = Config_Point->CPUs; - Node_Record_Point->RealMemory = Config_Point->RealMemory; - Node_Record_Point->TmpDisk = Config_Point->TmpDisk; + abort (); + } + + node_record_point = node_record_table_ptr + (node_record_count++); + strcpy (node_record_point->name, node_name); + node_record_point->node_state = default_node_record.node_state; + node_record_point->last_response = default_node_record.last_response; + node_record_point->config_ptr = config_point; + node_record_point->partition_ptr = NULL; + /* these values will be overwritten when the node actually registers */ + node_record_point->cpus = config_point->cpus; + node_record_point->real_memory = config_point->real_memory; + node_record_point->tmp_disk = config_point->tmp_disk; #if DEBUG_SYSTEM - Node_Record_Point->Magic = NODE_MAGIC; + node_record_point->magic = NODE_MAGIC; #endif - Last_BitMap_Update = time(NULL); - return Node_Record_Point; -} /* Create_Node_Record */ + last_bitmap_update = time (NULL); + return node_record_point; +} /* - * Delete_Config_Record - Delete all configuration records - * Output: Returns 0 if no error, errno otherwise + * delete_config_record - delete all configuration records + * output: returns 0 if no error, errno otherwise */ -int Delete_Config_Record() { - Last_Node_Update = time(NULL); - (void)list_delete_all(Config_List, &List_Find_Config, "UNIVERSAL_KEY"); - return 0; -} /* Delete_Config_Record */ +int delete_config_record () { + last_node_update = time (NULL); + (void) list_delete_all (config_list, &list_find_config, + "universal_key"); + return 0; +} /* - * Delete_Node_Record - Delete record for node with specified name - * To avoid invalidating the bitmaps and hash table, we just clear the name + * delete_node_record - delete record for node with specified name + * to avoid invalidating the bitmaps and hash table, we just clear the name * set its state to STATE_DOWN - * Input: name - Name of the desired node, Delete all nodes if pointer is NULL - * Output: return 0 on success, errno otherwise + * input: name - name of the desired node, delete all nodes if pointer is NULL + * output: return 0 on success, errno otherwise */ -int Delete_Node_Record(char *name) { - struct Node_Record *Node_Record_Point; /* Pointer to Node_Record */ +int delete_node_record (char *name) { + struct node_record *node_record_point; /* pointer to node_record */ - Last_Node_Update = time(NULL); - Node_Lock(); - Node_Record_Point = Find_Node_Record(name); - if (Node_Record_Point == (struct Node_Record *)NULL) { + last_node_update = time (NULL); + node_record_point = find_node_record (name); + if (node_record_point == (struct node_record *) NULL) { #if DEBUG_MODULE - fprintf(stderr, "Delete_Node_Record: Attempt to delete non-existent node %s\n", name); + fprintf (stderr, + "delete_node_record: attempt to delete non-existent node %s\n", + name); #else - syslog(LOG_ALERT, "Delete_Node_Record: Attempt to delete non-existent node %s\n", name); + syslog (LOG_ALERT, + "delete_node_record: attempt to delete non-existent node %s\n", + name); #endif - Node_Unlock(); - return ENOENT; - } /* if */ - - if (Node_Record_Point->Partition_Ptr) { - (Node_Record_Point->Partition_Ptr->TotalNodes)--; - (Node_Record_Point->Partition_Ptr->TotalCPUs) -= Node_Record_Point->CPUs; - } /* if */ - strcpy(Node_Record_Point->Name, ""); - Node_Record_Point->NodeState = STATE_DOWN; - Last_BitMap_Update = time(NULL); - Node_Unlock(); - return 0; -} /* Delete_Node_Record */ - - -/* Print the Hash_Table contents, used for debugging or analysis of hash technique */ -void Dump_Hash() { - int i; - - if (Hash_Table == NULL) return; - for (i=0; i<Node_Record_Count; i++) { - if (strlen(Node_Record_Table_Ptr[Hash_Table[i]].Name) == 0) continue; - printf("Hash:%d:%s\n", i, Node_Record_Table_Ptr[Hash_Table[i]].Name); - } /* for */ -} /* Dump_Hash */ + return ENOENT; + } + + if (node_record_point->partition_ptr) { + (node_record_point->partition_ptr->total_nodes)--; + (node_record_point->partition_ptr->total_cpus) -= + node_record_point->cpus; + } + strcpy (node_record_point->name, ""); + node_record_point->node_state = STATE_DOWN; + last_bitmap_update = time (NULL); + return 0; +} + + +/* print the hash_table contents, used for debugging or analysis of hash technique */ +void dump_hash () { + int i; + + if (hash_table == NULL) + return; + for (i = 0; i < node_record_count; i++) { + if (strlen (node_record_table_ptr[hash_table[i]].name) == 0) + continue; + printf ("hash:%d:%s\n", i, + node_record_table_ptr[hash_table[i]].name); + } +} /* - * Dump_Node - Dump all configuration and node information to a buffer - * Input: Buffer_Ptr - Location into which a pointer to the data is to be stored. - * The data buffer is actually allocated by Dump_Node and the + * dump_node - dump all configuration and node information to a buffer + * input: buffer_ptr - location into which a pointer to the data is to be stored. + * the data buffer is actually allocated by dump_node and the * calling function must free the storage. - * Buffer_Size - Location into which the size of the created buffer is in bytes - * Update_Time - Dump new data only if partition records updated since time + * buffer_size - location into which the size of the created buffer is in bytes + * update_time - dump new data only if partition records updated since time * specified, otherwise return empty buffer - * Output: Buffer_Ptr - The pointer is set to the allocated buffer. - * Buffer_Size - Set to size of the buffer in bytes - * Update_Time - set to time partition records last updated - * Returns 0 if no error, errno otherwise - * NOTE: The buffer at *Buffer_Ptr must be freed by the caller - * NOTE: IF YOU MAKE ANY CHANGES HERE be sure to increment the value of NODE_STRUCT_VERSION - * and make the corresponding changes to Load_Node_Config in api/node_info.c + * output: buffer_ptr - the pointer is set to the allocated buffer. + * buffer_size - set to size of the buffer in bytes + * update_time - set to time partition records last updated + * returns 0 if no error, errno otherwise + * NOTE: the buffer at *buffer_ptr must be freed by the caller + * NOTE: if you make any changes here be sure to increment the value of NODE_STRUCT_VERSION + * and make the corresponding changes to load_node_config in api/node_info.c */ -int Dump_Node(char **Buffer_Ptr, int *Buffer_Size, time_t *Update_Time) { - char *Buffer; - int Buffer_Offset, Buffer_Allocated, My_BitMap_Size, i, inx, state; - char Out_Line[BUF_SIZE*2], *feature, *partition; - - Buffer_Ptr[0] = NULL; - *Buffer_Size = 0; - Buffer = NULL; - Buffer_Offset = 0; - Buffer_Allocated = 0; - if (*Update_Time == Last_Node_Update) return 0; - - Node_Lock(); - /* Write haeader: version and time */ - sprintf(Out_Line, HEAD_FORMAT, (unsigned long)Last_Node_Update, NODE_STRUCT_VERSION); - if (Write_Buffer(&Buffer, &Buffer_Offset, &Buffer_Allocated, Out_Line)) goto cleanup; - - /* Write node records */ - for (inx=0; inx<Node_Record_Count; inx++) { +int dump_node (char **buffer_ptr, int *buffer_size, time_t * update_time) { + char *buffer; + int buffer_offset, buffer_allocated, my_bitmap_size, i, inx, state; + char out_line[BUF_SIZE * 2], *feature, *partition; + + buffer_ptr[0] = NULL; + *buffer_size = 0; + buffer = NULL; + buffer_offset = 0; + buffer_allocated = 0; + if (*update_time == last_node_update) + return 0; + + /* write haeader: version and time */ + sprintf (out_line, HEAD_FORMAT, (unsigned long) last_node_update, + NODE_STRUCT_VERSION); + if (write_buffer + (&buffer, &buffer_offset, &buffer_allocated, out_line)) + goto cleanup; + + /* write node records */ + for (inx = 0; inx < node_record_count; inx++) { #if DEBUG_SYSTEM - if ((Node_Record_Table_Ptr[inx].Magic != NODE_MAGIC) || - (Node_Record_Table_Ptr[inx].Config_Ptr->Magic != CONFIG_MAGIC)) { - fprintf(stderr, "Dump_Node: Data integrity is bad\n"); - abort(); - } /* if */ + if ((node_record_table_ptr[inx].magic != NODE_MAGIC) || + (node_record_table_ptr[inx].config_ptr->magic != + CONFIG_MAGIC)) { + fprintf (stderr, + "dump_node: data integrity is bad\n"); + abort (); + } #endif - state = Node_Record_Table_Ptr[inx].NodeState; - if (state < 0) state=STATE_DOWN; - if (Node_Record_Table_Ptr[inx].Config_Ptr->Feature) - feature = Node_Record_Table_Ptr[inx].Config_Ptr->Feature; - else - feature = "NONE"; - if (Node_Record_Table_Ptr[inx].Partition_Ptr) - partition = Node_Record_Table_Ptr[inx].Partition_Ptr->Name; - else - partition = "NONE"; - sprintf(Out_Line, NODE_STRUCT_FORMAT, - Node_Record_Table_Ptr[inx].Name, - Node_State_String[state], - Node_Record_Table_Ptr[inx].CPUs, - Node_Record_Table_Ptr[inx].RealMemory, - Node_Record_Table_Ptr[inx].TmpDisk, - Node_Record_Table_Ptr[inx].Config_Ptr->Weight, - feature, partition); - - if (strlen(Out_Line) > BUF_SIZE) { + state = node_record_table_ptr[inx].node_state; + if (state < 0) + state = STATE_DOWN; + if (node_record_table_ptr[inx].config_ptr->feature) + feature = + node_record_table_ptr[inx].config_ptr-> + feature; + else + feature = "none"; + if (node_record_table_ptr[inx].partition_ptr) + partition = + node_record_table_ptr[inx].partition_ptr-> + name; + else + partition = "none"; + sprintf (out_line, NODE_STRUCT_FORMAT, + node_record_table_ptr[inx].name, + node_state_string[state], + node_record_table_ptr[inx].cpus, + node_record_table_ptr[inx].real_memory, + node_record_table_ptr[inx].tmp_disk, + node_record_table_ptr[inx].config_ptr->weight, + feature, partition); + + if (strlen (out_line) > BUF_SIZE) { #if DEBUG_SYSTEM - fprintf(stderr, "Dump_Node: buffer overflow for node %s\n", Node_Record_Table_Ptr[inx].Name); + fprintf (stderr, + "dump_node: buffer overflow for node %s\n", + node_record_table_ptr[inx].name); #else - syslog(LOG_ALERT, "Dump_Node: buffer overflow for node %s\n", Node_Record_Table_Ptr[inx].Name); + syslog (LOG_ALERT, + "dump_node: buffer overflow for node %s\n", + node_record_table_ptr[inx].name); #endif - if (strlen(Out_Line) > (2*BUF_SIZE)) abort(); - } /* if */ + if (strlen (out_line) > (2 * BUF_SIZE)) + abort (); + } - if (Write_Buffer(&Buffer, &Buffer_Offset, &Buffer_Allocated, Out_Line)) goto cleanup; - } /* for (inx */ + if (write_buffer + (&buffer, &buffer_offset, &buffer_allocated, out_line)) + goto cleanup; + } - Buffer = realloc(Buffer, Buffer_Offset); - if (Buffer == NULL) { + buffer = realloc (buffer, buffer_offset); + if (buffer == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "Dump_Node: unable to allocate memory\n"); + fprintf (stderr, "dump_node: unable to allocate memory\n"); #else - syslog(LOG_ALERT, "Dump_Node: unable to allocate memory\n"); + syslog (LOG_ALERT, "dump_node: unable to allocate memory\n"); #endif - abort(); - } /* if */ + abort (); + } - Buffer_Ptr[0] = Buffer; - *Buffer_Size = Buffer_Offset; - *Update_Time = Last_Node_Update; - Node_Unlock(); - return 0; + buffer_ptr[0] = buffer; + *buffer_size = buffer_offset; + *update_time = last_node_update; + return 0; -cleanup: - Node_Unlock(); - if (Buffer) free(Buffer); - return EINVAL; -} /* Dump_Node */ + cleanup: + if (buffer) + free (buffer); + return EINVAL; +} /* - * Find_Node_Record - Find a record for node with specified name, - * Input: name - name of the desired node - * Output: return pointer to node record or NULL if not found + * find_node_record - find a record for node with specified name, + * input: name - name of the desired node + * output: return pointer to node record or NULL if not found */ -struct Node_Record *Find_Node_Record(char *name) { - struct Node_Record *Node_Record_Point; /* Pointer to Node_Record */ - int i; - - /* Try to find in hash table first */ - if (Hash_Table) { - i = Hash_Index(name); - if (strcmp((Node_Record_Table_Ptr+Hash_Table[i])->Name, name) == 0) - return (Node_Record_Table_Ptr+Hash_Table[i]); +struct node_record * find_node_record (char *name) { + struct node_record *node_record_point; /* pointer to node_record */ + int i; + + /* try to find in hash table first */ + if (hash_table) { + i = hash_index (name); + if (strcmp + ((node_record_table_ptr + hash_table[i])->name, + name) == 0) + return (node_record_table_ptr + hash_table[i]); #if DEBUG_SYSTEM - fprintf(stderr, "Find_Node_Record: Hash table lookup failure for %s\n", name); - Dump_Hash(); + fprintf (stderr, + "find_node_record: hash table lookup failure for %s\n", + name); + dump_hash (); #else - syslog(LOG_DEBUG, "Find_Node_Record: Hash table lookup failure for %s\n", name); + syslog (LOG_DEBUG, + "find_node_record: hash table lookup failure for %s\n", + name); #endif - } /* if */ + } - /* Revert to sequential search */ - for (i=0; i<Node_Record_Count; i++) { - if (strcmp(name, Node_Record_Table_Ptr[i].Name) != 0) continue; - return (Node_Record_Table_Ptr+i); - } /* for */ + /* revert to sequential search */ + for (i = 0; i < node_record_count; i++) { + if (strcmp (name, node_record_table_ptr[i].name) != 0) + continue; + return (node_record_table_ptr + i); + } - if (Hash_Table) { + if (hash_table) { #if DEBUG_SYSTEM - fprintf(stderr, "Find_Node_Record: Lookup failure for %s\n", name); + fprintf (stderr, "find_node_record: lookup failure for %s\n", + name); #else - syslog(LOG_ERR, "Find_Node_Record: Lookup failure for %s\n", name); + syslog (LOG_ERR, "find_node_record: lookup failure for %s\n", + name); #endif - } /* if */ - return (struct Node_Record *)NULL; -} /* Find_Node_Record */ + } + return (struct node_record *) NULL; +} /* - * Hash_Index - Return a hash table index for the given node name - * This code is optimized for names containing a base-ten suffix (e.g. "lx04") - * Input: The node's name - * Output: Return code is the hash table index + * hash_index - return a hash table index for the given node name + * this code is optimized for names containing a base-ten suffix (e.g. "lx04") + * input: the node's name + * output: return code is the hash table index */ -int Hash_Index(char *name) { - int i, inx, tmp; +int hash_index (char *name) { + int i, inx, tmp; - if (Node_Record_Count == 0) return 0; /* Degenerate case */ - inx = 0; + if (node_record_count == 0) + return 0; /* degenerate case */ + inx = 0; #if ( HASH_BASE == 10 ) - for (i=0; ;i++) { - tmp = (int) name[i]; - if (tmp == 0) break; /* end if string */ - if ((tmp >= (int)'0') && (tmp <= (int)'9')) - inx = (inx * HASH_BASE) + (tmp - (int)'0'); - } /* for */ + for (i = 0;; i++) { + tmp = (int) name[i]; + if (tmp == 0) + break; /* end if string */ + if ((tmp >= (int) '0') && (tmp <= (int) '9')) + inx = (inx * HASH_BASE) + (tmp - (int) '0'); + } #elif ( HASH_BASE == 8 ) - for (i=0; ;i++) { - tmp = (int) name[i]; - if (tmp == 0) break; /* end if string */ - if ((tmp >= (int)'0') && (tmp <= (int)'7')) - inx = (inx * HASH_BASE) + (tmp - (int)'0'); - } /* for */ + for (i = 0;; i++) { + tmp = (int) name[i]; + if (tmp == 0) + break; /* end if string */ + if ((tmp >= (int) '0') && (tmp <= (int) '7')) + inx = (inx * HASH_BASE) + (tmp - (int) '0'); + } #else - for (i=0; i<5;i++) { - tmp = (int) name[i]; - if (tmp == 0) break; /* end if string */ - if ((tmp >= (int)'0') && (tmp <= (int)'9')) { /* value 0-9 */ - tmp -= (int)'0'; - } else if ((tmp >= (int)'a') && (tmp <= (int)'z')) { /* value 10-35 */ - tmp -= (int)'a'; - tmp += 10; - } else if ((tmp >= (int)'A') && (tmp <= (int)'Z')) { /* value 10-35 */ - tmp -= (int)'A'; - tmp += 10; - } else { - tmp = 36; + for (i = 0; i < 5; i++) { + tmp = (int) name[i]; + if (tmp == 0) + break; /* end if string */ + if ((tmp >= (int) '0') && (tmp <= (int) '9')) { /* value 0-9 */ + tmp -= (int) '0'; + } + else if ((tmp >= (int) 'a') && (tmp <= (int) 'z')) { /* value 10-35 */ + tmp -= (int) 'a'; + tmp += 10; + } + else if ((tmp >= (int) 'a') && (tmp <= (int) 'z')) { /* value 10-35 */ + tmp -= (int) 'a'; + tmp += 10; + } + else { + tmp = 36; + } + inx = (inx * 37) + tmp; } - inx = (inx * 37) + tmp; - } /* for */ - #endif +#endif - inx = inx % Node_Record_Count; - return inx; -} /* Hash_Index */ + inx = inx % node_record_count; + return inx; +} /* - * Init_Node_Conf - Initialize the node configuration values. - * This should be called before creating any node or configuration entries. - * Output: return value - 0 if no error, otherwise an error code + * init_node_conf - initialize the node configuration values. + * this should be called before creating any node or configuration entries. + * output: return value - 0 if no error, otherwise an error code */ -int Init_Node_Conf() { - Last_Node_Update = time(NULL); - - Node_Lock(); - Node_Record_Count = 0; - if (Node_Record_Table_Ptr) { - free(Node_Record_Table_Ptr); - Node_Record_Table_Ptr = NULL; - } - if (Hash_Table) { - free(Hash_Table); - Hash_Table = NULL; - } - - strcpy(Default_Node_Record.Name, "DEFAULT"); - Default_Node_Record.NodeState = STATE_UNKNOWN; - Default_Node_Record.LastResponse = (time_t)0; - Default_Node_Record.CPUs = 1; - Default_Node_Record.RealMemory = 1; - Default_Node_Record.TmpDisk = 1; - Default_Node_Record.Config_Ptr = NULL; - Default_Node_Record.Partition_Ptr = NULL; - Default_Config_Record.CPUs = 1; - Default_Config_Record.RealMemory = 1; - Default_Config_Record.TmpDisk = 1; - Default_Config_Record.Weight = 1; - if (Default_Config_Record.Feature) free(Default_Config_Record.Feature); - Default_Config_Record.Feature = (char *)NULL; - if (Default_Config_Record.Nodes) free(Default_Config_Record.Nodes); - Default_Config_Record.Nodes = (char *)NULL; - if (Default_Config_Record.NodeBitMap) free(Default_Config_Record.NodeBitMap); - Default_Config_Record.NodeBitMap = (unsigned *)NULL; - - if (Config_List) /* Delete defunct configuration entries */ - (void)Delete_Config_Record(); - else - Config_List = list_create(&List_Delete_Config); - - if (Config_List == NULL) { +int init_node_conf () { + last_node_update = time (NULL); + + node_record_count = 0; + if (node_record_table_ptr) { + free (node_record_table_ptr); + node_record_table_ptr = NULL; + } + if (hash_table) { + free (hash_table); + hash_table = NULL; + } + + strcpy (default_node_record.name, "DEFAULT"); + default_node_record.node_state = STATE_UNKNOWN; + default_node_record.last_response = (time_t) 0; + default_node_record.cpus = 1; + default_node_record.real_memory = 1; + default_node_record.tmp_disk = 1; + default_node_record.config_ptr = NULL; + default_node_record.partition_ptr = NULL; + default_config_record.cpus = 1; + default_config_record.real_memory = 1; + default_config_record.tmp_disk = 1; + default_config_record.weight = 1; + if (default_config_record.feature) + free (default_config_record.feature); + default_config_record.feature = (char *) NULL; + if (default_config_record.nodes) + free (default_config_record.nodes); + default_config_record.nodes = (char *) NULL; + if (default_config_record.node_bitmap) + free (default_config_record.node_bitmap); + default_config_record.node_bitmap = (unsigned *) NULL; + + if (config_list) /* delete defunct configuration entries */ + (void) delete_config_record (); + else + config_list = list_create (&list_delete_config); + + if (config_list == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "Init_Node_Conf: list_create can not allocate memory\n"); + fprintf (stderr, + "init_node_conf: list_create can not allocate memory\n"); #else - syslog(LOG_ALERT, "Init_Node_Conf: list_create can not allocate memory\n"); + syslog (LOG_ALERT, + "init_node_conf: list_create can not allocate memory\n"); #endif - abort(); - } /* if */ - Node_Unlock(); - return 0; -} /* Init_Node_Conf */ + abort (); + } + return 0; +} -/* List_Compare_Config - Compare two entry from the config list based upon weight, +/* list_compare_config - compare two entry from the config list based upon weight, * see list.h for documentation */ -int List_Compare_Config(void *Config_Entry1, void *Config_Entry2) { - int Weight1, Weight2; - Weight1 = ((struct Config_Record *)Config_Entry1)->Weight; - Weight2 = ((struct Config_Record *)Config_Entry2)->Weight; - return (Weight1 - Weight2); -} /* List_Compare_Config */ - - -/* List_Delete_Config - Delete an entry from the config list, see list.h for documentation */ -void List_Delete_Config(void *Config_Entry) { - struct Config_Record *Config_Record_Point; /* Pointer to Config_Record */ - Config_Record_Point = (struct Config_Record *)Config_Entry; - if (Config_Record_Point->Feature) free(Config_Record_Point->Feature); - if (Config_Record_Point->Nodes) free(Config_Record_Point->Nodes); - if (Config_Record_Point->NodeBitMap) free(Config_Record_Point->NodeBitMap); - free(Config_Record_Point); -} /* List_Delete_Config */ - - -/* List_Find_Config - Find an entry in the config list, see list.h for documentation - * Key is partition name or "UNIVERSAL_KEY" for all config */ -int List_Find_Config(void *Config_Entry, void *key) { - if (strcmp(key, "UNIVERSAL_KEY") == 0) return 1; - return 0; -} /* List_Find_Config */ +int list_compare_config (void *config_entry1, void *config_entry2) { + int weight1, weight2; + weight1 = ((struct config_record *) config_entry1)->weight; + weight2 = ((struct config_record *) config_entry2)->weight; + return (weight1 - weight2); +} + + +/* list_delete_config - delete an entry from the config list, see list.h for documentation */ +void list_delete_config (void *config_entry) { + struct config_record *config_record_point; /* pointer to config_record */ + config_record_point = (struct config_record *) config_entry; + if (config_record_point->feature) + free (config_record_point->feature); + if (config_record_point->nodes) + free (config_record_point->nodes); + if (config_record_point->node_bitmap) + free (config_record_point->node_bitmap); + free (config_record_point); +} + + +/* list_find_config - find an entry in the config list, see list.h for documentation + * key is partition name or "universal_key" for all config */ +int list_find_config (void *config_entry, void *key) { + if (strcmp (key, "universal_key") == 0) + return 1; + return 0; +} /* - * NodeName2BitMap - Given a node list, build a bitmap representation - * Input: Node_List - List of nodes - * BitMap - Place to put bitmap pointer - * Output: BitMap - Set to bitmap or NULL on error - * Returns 0 if no error, otherwise EINVAL or ENOMEM - * NOTE: The caller must free memory at BitMap when no longer required + * node_name2bitmap - given a node list, build a bitmap representation + * input: node_list - list of nodes + * bitmap - place to put bitmap pointer + * output: bitmap - set to bitmap or NULL on error + * returns 0 if no error, otherwise EINVAL or enomem + * NOTE: the caller must free memory at bitmap when no longer required */ -int NodeName2BitMap(char *Node_List, unsigned **BitMap) { - int Error_Code, i, size; - int Start_Inx, End_Inx, Count_Inx; - char *Format, This_Node_Name[BUF_SIZE], *My_Node_List, *str_ptr1, *str_ptr2; - struct Node_Record *Node_Record_Point; - unsigned *My_BitMap; - - BitMap[0] = NULL; - if (Node_List == NULL) { +int node_name2bitmap (char *node_list, unsigned **bitmap) { + int error_code, i, size; + int start_inx, end_inx, count_inx; + char *format, this_node_name[BUF_SIZE], *my_node_list, *str_ptr1, + *str_ptr2; + struct node_record *node_record_point; + unsigned *my_bitmap; + + bitmap[0] = NULL; + if (node_list == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "NodeName2BitMap: Node_List is NULL\n"); + fprintf (stderr, "node_name2bitmap: node_list is NULL\n"); #else - syslog(LOG_ERR, "NodeName2BitMap: Node_List is NULL\n"); + syslog (LOG_ERR, "node_name2bitmap: node_list is NULL\n"); #endif - return EINVAL; - } /* if */ - if (Node_Record_Count == 0) { + return EINVAL; + } + if (node_record_count == 0) { #if DEBUG_SYSTEM - fprintf(stderr, "NodeName2BitMap: System has no nodes\n"); + fprintf (stderr, "node_name2bitmap: system has no nodes\n"); #else - syslog(LOG_ERR, "NodeName2BitMap: System has no nodes\n"); + syslog (LOG_ERR, "node_name2bitmap: system has no nodes\n"); #endif - return EINVAL; - } /* if */ + return EINVAL; + } - My_Node_List = malloc(strlen(Node_List)+1); - if (My_Node_List == NULL) { + my_node_list = malloc (strlen (node_list) + 1); + if (my_node_list == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "NodeName2BitMap: unable to allocate memory\n"); + fprintf (stderr, + "node_name2bitmap: unable to allocate memory\n"); #else - syslog(LOG_ALERT, "NodeName2BitMap: unable to allocate memory\n"); + syslog (LOG_ALERT, + "node_name2bitmap: unable to allocate memory\n"); #endif - abort(); - } /* if */ - strcpy(My_Node_List, Node_List); - - size = (Node_Record_Count + (sizeof(unsigned)*8) - 1) / - (sizeof(unsigned)*8); /* Unsigned int records in bitmap */ - size *= 8; /* Bytes in bitmap */ - My_BitMap = (unsigned *)malloc(size); - if (My_BitMap == NULL) { + abort (); + } + strcpy (my_node_list, node_list); + + size = (node_record_count + (sizeof (unsigned) * 8) - 1) / (sizeof (unsigned) * 8); /* unsigned int records in bitmap */ + size *= 8; /* bytes in bitmap */ + my_bitmap = (unsigned *) malloc (size); + if (my_bitmap == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "NodeName2BitMap: unable to allocate memory\n"); + fprintf (stderr, + "node_name2bitmap: unable to allocate memory\n"); #else - syslog(LOG_ALERT, "NodeName2BitMap: unable to allocate memory\n"); + syslog (LOG_ALERT, + "node_name2bitmap: unable to allocate memory\n"); #endif - abort(); - } /* if */ - memset(My_BitMap, 0, size); - - str_ptr2 = (char *)strtok_r(My_Node_List, ",", &str_ptr1); - while (str_ptr2) { /* Break apart by comma separators */ - Error_Code = Parse_Node_Name(str_ptr2, &Format, &Start_Inx, &End_Inx, &Count_Inx); - if (Error_Code) { - free(My_Node_List); - free(My_BitMap); - return EINVAL; - } /* if */ - if (strlen(Format) >= sizeof(This_Node_Name)) { + abort (); + } + memset (my_bitmap, 0, size); + + str_ptr2 = (char *) strtok_r (my_node_list, ",", &str_ptr1); + while (str_ptr2) { /* break apart by comma separators */ + error_code = + parse_node_name (str_ptr2, &format, &start_inx, + &end_inx, &count_inx); + if (error_code) { + free (my_node_list); + free (my_bitmap); + return EINVAL; + } + if (strlen (format) >= sizeof (this_node_name)) { #if DEBUG_SYSTEM - fprintf(stderr, "NodeName2BitMap: Node name specification too long: %s\n", Format); + fprintf (stderr, + "node_name2bitmap: node name specification too long: %s\n", + format); #else - syslog(LOG_ERR, "NodeName2BitMap: Node name specification too long: %s\n", Format); + syslog (LOG_ERR, + "node_name2bitmap: node name specification too long: %s\n", + format); #endif - free(My_Node_List); - free(My_BitMap); - free(Format); - return EINVAL; - } /* if */ - for (i=Start_Inx; i<=End_Inx; i++) { - if (Count_Inx == 0) - strncpy(This_Node_Name, Format, sizeof(This_Node_Name)); - else - sprintf(This_Node_Name, Format, i); - Node_Record_Point = Find_Node_Record(This_Node_Name); - if (Node_Record_Point == NULL) { + free (my_node_list); + free (my_bitmap); + free (format); + return EINVAL; + } + for (i = start_inx; i <= end_inx; i++) { + if (count_inx == 0) + strncpy (this_node_name, format, + sizeof (this_node_name)); + else + sprintf (this_node_name, format, i); + node_record_point = find_node_record (this_node_name); + if (node_record_point == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "NodeName2BitMap: Invalid node specified %s\n", This_Node_Name); + fprintf (stderr, + "node_name2bitmap: invalid node specified %s\n", + this_node_name); #else - syslog(LOG_ERR, "NodeName2BitMap: Invalid node specified %s\n", This_Node_Name); + syslog (LOG_ERR, + "node_name2bitmap: invalid node specified %s\n", + this_node_name); #endif - free(My_Node_List); - free(My_BitMap); - free(Format); - return EINVAL; - } /* if */ - BitMapSet(My_BitMap, (int)(Node_Record_Point - Node_Record_Table_Ptr)); - } /* for */ - str_ptr2 = (char *)strtok_r(NULL, ",", &str_ptr1); - } /* while */ - - free(My_Node_List); - free(Format); - BitMap[0] =My_BitMap; - return 0; -} /* NodeName2BitMap */ - - -/* Node_Lock - Lock the node and configuration information */ -void Node_Lock() { - int Error_Code; - Error_Code = pthread_mutex_lock(&Node_Mutex); - if (Error_Code) { + free (my_node_list); + free (my_bitmap); + free (format); + return EINVAL; + } + bitmap_set (my_bitmap, + (int) (node_record_point - + node_record_table_ptr)); + } + str_ptr2 = (char *) strtok_r (NULL, ",", &str_ptr1); + } + + free (my_node_list); + free (format); + bitmap[0] = my_bitmap; + return 0; +} + + +/* node_lock - lock the node and configuration information */ +void node_lock () { + int error_code; + error_code = pthread_mutex_lock (&node_mutex); + if (error_code) { #if DEBUG_SYSTEM - fprintf(stderr, "Node_Lock: pthread_mutex_lock error %d\n", Error_Code); + fprintf (stderr, "node_lock: pthread_mutex_lock error %d\n", + error_code); #else - syslog(LOG_ALERT, "Node_Lock: pthread_mutex_lock error %d\n", Error_Code); + syslog (LOG_ALERT, "node_lock: pthread_mutex_lock error %d\n", + error_code); #endif - abort(); - } /* if */ -} /* Node_Lock */ + abort (); + } +} -/* Node_Unlock - Unlock the node and configuration information */ -void Node_Unlock() { - int Error_Code; - Error_Code = pthread_mutex_unlock(&Node_Mutex); - if (Error_Code) { +/* node_unlock - unlock the node and configuration information */ +void node_unlock () { + int error_code; + error_code = pthread_mutex_unlock (&node_mutex); + if (error_code) { #if DEBUG_SYSTEM - fprintf(stderr, "Node_Lock: pthread_mutex_unlock error %d\n", Error_Code); + fprintf (stderr, "node_lock: pthread_mutex_unlock error %d\n", + error_code); #else - syslog(LOG_ALERT, "Node_Lock: pthread_mutex_unlock error %d\n", Error_Code); + syslog (LOG_ALERT, + "node_lock: pthread_mutex_unlock error %d\n", + error_code); #endif - abort(); - } /* if */ -} /* Node_Unlock */ + abort (); + } +} /* - * Rehash - Build a hash table of the Node_Record entries. This is a large hash table + * rehash - build a hash table of the node_record entries. this is a large hash table * to permit the immediate finding of a record based only upon its name without regards - * to the number. There should be no need for a search. The algorithm is optimized for - * node names with a base-ten sequence number suffix. If you have a large cluster and - * use a different naming convention, this function and/or the Hash_Index function + * to the number. there should be no need for a search. the algorithm is optimized for + * node names with a base-ten sequence number suffix. if you have a large cluster and + * use a different naming convention, this function and/or the hash_index function * should be re-written. */ -void Rehash() { - struct Node_Record *Node_Record_Point; /* Pointer to Node_Record */ - int i, inx; +void rehash () { + struct node_record *node_record_point; /* pointer to node_record */ + int i, inx; - Node_Lock(); - Hash_Table = (int *)realloc(Hash_Table, (sizeof(int) * Node_Record_Count)); + hash_table = + (int *) realloc (hash_table, + (sizeof (int) * node_record_count)); - if (Hash_Table == NULL) { + if (hash_table == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "Rehash: list_append can not allocate memory\n"); + fprintf (stderr, + "rehash: list_append can not allocate memory\n"); #else - syslog(LOG_ALERT, "Rehash: list_append can not allocate memory\n"); + syslog (LOG_ALERT, + "rehash: list_append can not allocate memory\n"); #endif - abort(); - } /* if */ - memset(Hash_Table, 0, (sizeof(int) * Node_Record_Count)); + abort (); + } + memset (hash_table, 0, (sizeof (int) * node_record_count)); - for (i=0; i<Node_Record_Count; i++) { - if (strlen(Node_Record_Table_Ptr[i].Name) == 0) continue; - inx = Hash_Index(Node_Record_Table_Ptr[i].Name); - Hash_Table[inx] = i; - } /* for */ + for (i = 0; i < node_record_count; i++) { + if (strlen (node_record_table_ptr[i].name) == 0) + continue; + inx = hash_index (node_record_table_ptr[i].name); + hash_table[inx] = i; + } - Node_Unlock(); - return; -} /* Rehash */ + return; +} /* - * Split_Node_Name - Split a node name into prefix, suffix, and index value - * Input: Name - The node name to parse - * Prefix, Suffix, Index, Digits - Location into which to store node name's constituents - * Output: Prefix, Suffix, Index - The node name's constituents - * Index - Index, defaults to NO_VAL - * Digits - Number of digits in the index, defaults to NO_VAL + * split_node_name - split a node name into prefix, suffix, and index value + * input: name - the node name to parse + * prefix, suffix, index, digits - location into which to store node name's constituents + * output: prefix, suffix, index - the node name's constituents + * index - index, defaults to NO_VAL + * digits - number of digits in the index, defaults to NO_VAL */ -void Split_Node_Name(char *Name, char *Prefix, char *Suffix, int *Index, int *Digits) { - int i; - char Tmp[2]; - - strcpy(Prefix, ""); - strcpy(Suffix, ""); - *Index = NO_VAL; - *Digits = NO_VAL; - Tmp[1] = (char)NULL; - for (i=0; ; i++) { - if (Name[i] == (char)NULL) break; - if ((Name[i] >= '0') && (Name[i] <= '9')) { - if (*Index == NO_VAL) { - *Index = *Digits = 0; - } /* if */ - (*Digits)++; - *Index = (*Index * 10) + (Name[i] - '0'); - } else { - Tmp[0] = Name[i]; - if (*Index == NO_VAL) - strcat(Prefix, Tmp); - else - strcat(Suffix, Tmp); - } /* else */ - } /* for */ - return; -} /* Split_Node_Name */ +void split_node_name (char *name, char *prefix, char *suffix, int *index, + int *digits) { + int i; + char tmp[2]; + + strcpy (prefix, ""); + strcpy (suffix, ""); + *index = NO_VAL; + *digits = NO_VAL; + tmp[1] = (char) NULL; + for (i = 0;; i++) { + if (name[i] == (char) NULL) + break; + if ((name[i] >= '0') && (name[i] <= '9')) { + if (*index == NO_VAL) { + *index = *digits = 0; + } + (*digits)++; + *index = (*index * 10) + (name[i] - '0'); + } + else { + tmp[0] = name[i]; + if (*index == NO_VAL) + strcat (prefix, tmp); + else + strcat (suffix, tmp); + } + } + return; +} /* - * Update_Node - Update a node's configuration data - * Input: NodeName - Node's name - * Spec - The updates to the node's specification - * Output: Return - 0 if no error, otherwise an error code - * NOTE: The contents of Spec are overwritten by white space + * update_node - update a node's configuration data + * input: node_name - node's name + * spec - the updates to the node's specification + * output: return - 0 if no error, otherwise an error code + * NOTE: the contents of spec are overwritten by white space */ -int Update_Node(char *NodeName, char *Spec) { - int Bad_Index, Error_Code, i; - char *Format, *State, This_Node_Name[BUF_SIZE]; - int Start_Inx, End_Inx, Count_Inx, State_Val; - char *str_ptr1, *str_ptr2, *My_Node_List; - struct Node_Record *Node_Record_Point; - - if (strcmp(NodeName, "DEFAULT") == 0) { +int update_node (char *node_name, char *spec) { + int bad_index, error_code, i; + char *format, *state, this_node_name[BUF_SIZE]; + int start_inx, end_inx, count_inx, state_val; + char *str_ptr1, *str_ptr2, *my_node_list; + struct node_record *node_record_point; + + if (strcmp (node_name, "DEFAULT") == 0) { #if DEBUG_SYSTEM - fprintf(stderr, "Update_Node: Invalid node name %s\n", NodeName); + fprintf (stderr, "update_node: invalid node name %s\n", + node_name); #else - syslog(LOG_ERR, "Update_Node: Invalid node name %s\n", NodeName); + syslog (LOG_ERR, "update_node: invalid node name %s\n", + node_name); #endif - return EINVAL; - } /* if */ - - State_Val = NO_VAL; - State = NULL; - if (Error_Code=Load_String (&State, "State=", Spec)) return Error_Code; - if (State != NULL) { - for (i=0; i<=STATE_END; i++) { - if (strcmp(Node_State_String[i], "END") == 0) break; - if (strcmp(Node_State_String[i], State) == 0) { - State_Val = i; - break; - } /* if */ - } /* for */ - if (State_Val == NO_VAL) { + return EINVAL; + } + + state_val = NO_VAL; + state = NULL; + if (error_code = load_string (&state, "State=", spec)) + return error_code; + if (state != NULL) { + for (i = 0; i <= STATE_END; i++) { + if (strcmp (node_state_string[i], "END") == 0) + break; + if (strcmp (node_state_string[i], state) == 0) { + state_val = i; + break; + } + } + if (state_val == NO_VAL) { #if DEBUG_SYSTEM - fprintf(stderr, "Update_Node: Invalid State %s for NodeName %s\n", State, NodeName); + fprintf (stderr, + "update_node: invalid state %s for node_name %s\n", + state, node_name); #else - syslog(LOG_ERR, "Update_Node: Invalid State %s for NodeName %s\n", State, NodeName); + syslog (LOG_ERR, + "update_node: invalid state %s for node_name %s\n", + state, node_name); #endif - free(State); - return EINVAL; - } /* if */ - free(State); - } /* if */ - - /* Check for anything else (unparsed) in the specification */ - Bad_Index = -1; - for (i=0; i<strlen(Spec); i++) { - if (Spec[i] == '\n') Spec[i]=' '; - if (isspace((int)Spec[i])) continue; - Bad_Index=i; - break; - } /* if */ - - if (Bad_Index != -1) { + free (state); + return EINVAL; + } + free (state); + } + + /* check for anything else (unparsed) in the specification */ + bad_index = -1; + for (i = 0; i < strlen (spec); i++) { + if (spec[i] == '\n') + spec[i] = ' '; + if (isspace ((int) spec[i])) + continue; + bad_index = i; + break; + } + + if (bad_index != -1) { #if DEBUG_SYSTEM - fprintf(stderr, "Update_Node: Ignored node %s update specification: %s\n", - NodeName, &Spec[Bad_Index]); + fprintf (stderr, + "update_node: ignored node %s update specification: %s\n", + node_name, &spec[bad_index]); #else - syslog(LOG_ERR, "Update_Node: Ignored node %s update specification: %s\n", - NodeName, &Spec[Bad_Index]); + syslog (LOG_ERR, + "update_node: ignored node %s update specification: %s\n", + node_name, &spec[bad_index]); #endif - return EINVAL; - } /* if */ + return EINVAL; + } - My_Node_List = malloc(strlen(NodeName)+1); - if (My_Node_List == NULL) { + my_node_list = malloc (strlen (node_name) + 1); + if (my_node_list == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "Update_Node: Unable to allocate memory\n"); + fprintf (stderr, "update_node: unable to allocate memory\n"); #else - syslog(LOG_ALERT, "Update_Node: Unable to allocate memory\n"); + syslog (LOG_ALERT, + "update_node: unable to allocate memory\n"); #endif - abort(); - } /* if */ - strcpy(My_Node_List, NodeName); - str_ptr2 = (char *)strtok_r(My_Node_List, ",", &str_ptr1); - Last_Node_Update = time(NULL); - Node_Lock(); - while (str_ptr2) { /* Break apart by comma separators */ - Error_Code = Parse_Node_Name(str_ptr2, &Format, &Start_Inx, &End_Inx, &Count_Inx); - if (Error_Code) return Error_Code; - if (strlen(Format) >= sizeof(This_Node_Name)) { + abort (); + } + strcpy (my_node_list, node_name); + str_ptr2 = (char *) strtok_r (my_node_list, ",", &str_ptr1); + last_node_update = time (NULL); + while (str_ptr2) { /* break apart by comma separators */ + error_code = + parse_node_name (str_ptr2, &format, &start_inx, + &end_inx, &count_inx); + if (error_code) + return error_code; + if (strlen (format) >= sizeof (this_node_name)) { #if DEBUG_SYSTEM - fprintf(stderr, "Update_Node: Node name specification too long: %s\n", Format); + fprintf (stderr, + "update_node: node name specification too long: %s\n", + format); #else - syslog(LOG_ERR, "Update_Node: Node name specification too long: %s\n", Format); + syslog (LOG_ERR, + "update_node: node name specification too long: %s\n", + format); #endif - free(Format); - Error_Code = EINVAL; - break; - } /* if */ - for (i=Start_Inx; i<=End_Inx; i++) { - if (Count_Inx == 0) - strncpy(This_Node_Name, Format, sizeof(This_Node_Name)); - else - sprintf(This_Node_Name, Format, i); - Node_Record_Point = Find_Node_Record(This_Node_Name); - if (Node_Record_Point == NULL) { + free (format); + error_code = EINVAL; + break; + } + for (i = start_inx; i <= end_inx; i++) { + if (count_inx == 0) + strncpy (this_node_name, format, + sizeof (this_node_name)); + else + sprintf (this_node_name, format, i); + node_record_point = find_node_record (this_node_name); + if (node_record_point == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "Update_Node: Node name %s does not exist, can not be updated\n", This_Node_Name); + fprintf (stderr, + "update_node: node name %s does not exist, can not be updated\n", + this_node_name); #else - syslog(LOG_ERR, "Update_Node: Node name %s does not exist, can not be updated\n", This_Node_Name); + syslog (LOG_ERR, + "update_node: node name %s does not exist, can not be updated\n", + this_node_name); #endif - Error_Code = EINVAL; - break; - } /* if */ - if (State_Val != NO_VAL) { - if ((State_Val == STATE_DOWN) && - (Node_Record_Point->NodeState != STATE_UNKNOWN)) - Node_Record_Point->NodeState = -(Node_Record_Point->NodeState); - else - Node_Record_Point->NodeState = State_Val; - if (State_Val != STATE_IDLE) BitMapClear(Idle_NodeBitMap, - (int)(Node_Record_Point-Node_Record_Table_Ptr)); - if (State_Val == STATE_DOWN) BitMapClear(Up_NodeBitMap, - (int)(Node_Record_Point-Node_Record_Table_Ptr)); + error_code = EINVAL; + break; + } + if (state_val != NO_VAL) { + if ((state_val == STATE_DOWN) && + (node_record_point->node_state != + STATE_UNKNOWN)) + node_record_point->node_state = + -(node_record_point->node_state); + else + node_record_point->node_state = + state_val; + if (state_val != STATE_IDLE) + bitmap_clear (idle_node_bitmap, + (int) (node_record_point - + node_record_table_ptr)); + if (state_val == STATE_DOWN) + bitmap_clear (up_node_bitmap, + (int) (node_record_point - + node_record_table_ptr)); #if DEBUG_SYSTEM - fprintf(stderr, "Update_Node: Node %s state set to %s\n", - This_Node_Name, Node_State_String[State_Val]); + fprintf (stderr, + "update_node: node %s state set to %s\n", + this_node_name, + node_state_string[state_val]); #else - syslog(LOG_INFO, "Update_Node: Node %s state set to %s\n", - This_Node_Name, Node_State_String[State_Val]); + syslog (LOG_INFO, + "update_node: node %s state set to %s\n", + this_node_name, + node_state_string[state_val]); #endif - } /* if */ - } /* for */ - free(Format); - str_ptr2 = (char *)strtok_r(NULL, ",", &str_ptr1); - } /* while */ + } + } + free (format); + str_ptr2 = (char *) strtok_r (NULL, ",", &str_ptr1); + } - Node_Unlock(); - free(My_Node_List); - return Error_Code; -} /* Update_Node */ + free (my_node_list); + return error_code; +} /* - * Validate_Node_Specs - Validate the node's specifications as valid, - * if not set state to DOWN, in any case update LastResponse - * Input: NodeName - Name of the node - * CPUs - Number of CPUs measured - * RealMemory - MegaBytes of RealMemory measured - * TmpDisk - MegaBytes of TmpDisk measured - * Output: Returns 0 if no error, ENOENT if no such node, EINVAL if values too low - */ -int Validate_Node_Specs(char *NodeName, int CPUs, int RealMemory, int TmpDisk) { - int Error_Code; - struct Config_Record *Config_Ptr; - struct Node_Record *Node_Ptr; - - Node_Lock(); - Node_Ptr = Find_Node_Record(NodeName); - if (Node_Ptr == NULL) { - Node_Unlock(); - return ENOENT; - } /* if */ - Node_Ptr->LastResponse = time(NULL); - - Config_Ptr = Node_Ptr->Config_Ptr; - Error_Code = 0; - - if (CPUs < Config_Ptr->CPUs) { + * validate_node_specs - validate the node's specifications as valid, + * if not set state to down, in any case update last_response + * input: node_name - name of the node + * cpus - number of cpus measured + * real_memory - mega_bytes of real_memory measured + * tmp_disk - mega_bytes of tmp_disk measured + * output: returns 0 if no error, ENOENT if no such node, EINVAL if values too low + */ +int validate_node_specs (char *node_name, int cpus, int real_memory, int tmp_disk) { + int error_code; + struct config_record *config_ptr; + struct node_record *node_ptr; + + node_ptr = find_node_record (node_name); + if (node_ptr == NULL) { + return ENOENT; + } + node_ptr->last_response = time (NULL); + + config_ptr = node_ptr->config_ptr; + error_code = 0; + + if (cpus < config_ptr->cpus) { #if DEBUG_SYSTEM - fprintf(stderr, "Validate_Node_Specs: Node %s has low CPU count\n", NodeName); + fprintf (stderr, + "validate_node_specs: node %s has low cpu count\n", + node_name); #else - syslog(LOG_ERR, "Validate_Node_Specs: Node %s has low CPU count\n", NodeName); + syslog (LOG_ERR, + "validate_node_specs: node %s has low cpu count\n", + node_name); #endif - Error_Code = EINVAL; - } /* if */ - Node_Ptr->CPUs = CPUs; - if ((Config_Ptr->CPUs != CPUs) && - (Node_Ptr->Partition_Ptr)) /* Need to update Partition records TotalCPUs */ - Node_Ptr->Partition_Ptr->TotalCPUs += (CPUs - Config_Ptr->CPUs); - - if (RealMemory < Config_Ptr->RealMemory) { + error_code = EINVAL; + } + node_ptr->cpus = cpus; + if ((config_ptr->cpus != cpus) && (node_ptr->partition_ptr)) /* need to update partition records total_cpus */ + node_ptr->partition_ptr->total_cpus += (cpus - config_ptr->cpus); + + if (real_memory < config_ptr->real_memory) { #if DEBUG_SYSTEM - fprintf(stderr, "Validate_Node_Specs: Node %s has low RealMemory size\n", NodeName); + fprintf (stderr, + "validate_node_specs: node %s has low real_memory size\n", + node_name); #else - syslog(LOG_ERR, "Validate_Node_Specs: Node %s has low RealMemory size\n", NodeName); + syslog (LOG_ERR, + "validate_node_specs: node %s has low real_memory size\n", + node_name); #endif - Error_Code = EINVAL; - } /* if */ - Node_Ptr->RealMemory = RealMemory; + error_code = EINVAL; + } + node_ptr->real_memory = real_memory; - if (TmpDisk < Config_Ptr->TmpDisk) { + if (tmp_disk < config_ptr->tmp_disk) { #if DEBUG_SYSTEM - fprintf(stderr, "Validate_Node_Specs: Node %s has low TmpDisk size\n", NodeName); + fprintf (stderr, + "validate_node_specs: node %s has low tmp_disk size\n", + node_name); #else - syslog(LOG_ERR, "Validate_Node_Specs: Node %s has low TmpDisk size\n", NodeName); + syslog (LOG_ERR, + "validate_node_specs: node %s has low tmp_disk size\n", + node_name); #endif - Error_Code = EINVAL; - } /* if */ - Node_Ptr->TmpDisk = TmpDisk; + error_code = EINVAL; + } + node_ptr->tmp_disk = tmp_disk; - if (Error_Code) { + if (error_code) { #if DEBUG_SYSTEM - fprintf(stderr, "Validate_Node_Specs: Setting node %s state to DOWN\n", NodeName); + fprintf (stderr, + "validate_node_specs: setting node %s state to down\n", + node_name); #else - syslog(LOG_ERR, "Validate_Node_Specs: Setting node %s state to DOWN\n", NodeName); + syslog (LOG_ERR, + "validate_node_specs: setting node %s state to down\n", + node_name); #endif - Node_Ptr->NodeState = STATE_DOWN; - BitMapClear(Up_NodeBitMap, (Node_Ptr - Node_Record_Table_Ptr)); + node_ptr->node_state = STATE_DOWN; + bitmap_clear (up_node_bitmap, + (node_ptr - node_record_table_ptr)); - } else { + } + else { #if DEBUG_SYSTEM - fprintf(stderr, "Validate_Node_Specs: Node %s has registered\n", NodeName); + fprintf (stderr, + "validate_node_specs: node %s has registered\n", + node_name); #else - syslog(LOG_ERR, "Validate_Node_Specs: Node %s has registered\n", NodeName); + syslog (LOG_ERR, + "validate_node_specs: node %s has registered\n", + node_name); #endif - if ((Node_Ptr->NodeState == STATE_DOWN) || - (Node_Ptr->NodeState == STATE_UNKNOWN)) Node_Ptr->NodeState = STATE_IDLE; - if (Node_Ptr->NodeState < 0) Node_Ptr->NodeState = -(Node_Ptr->NodeState); - BitMapSet(Up_NodeBitMap, (Node_Ptr - Node_Record_Table_Ptr)); - } /* else */ - - Node_Unlock(); - return Error_Code; -} /* Validate_Node_Specs */ + if ((node_ptr->node_state == STATE_DOWN) || + (node_ptr->node_state == STATE_UNKNOWN)) + node_ptr->node_state = STATE_IDLE; + if (node_ptr->node_state < 0) + node_ptr->node_state = -(node_ptr->node_state); + bitmap_set (up_node_bitmap, + (node_ptr - node_record_table_ptr)); + } + + return error_code; +} diff --git a/src/slurmctld/node_scheduler.c b/src/slurmctld/node_scheduler.c index f01881d6ae2aa9a2a371e83e69226e78e802588c..f4ca1285cd68e28c0e7df5caf2945288de5058ed 100644 --- a/src/slurmctld/node_scheduler.c +++ b/src/slurmctld/node_scheduler.c @@ -1,11 +1,11 @@ /* - * node_scheduler.c - Select and allocated nodes to jobs - * See slurm.h for documentation on external functions and data structures + * node_scheduler.c - select and allocated nodes to jobs + * see slurm.h for documentation on external functions and data structures * * NOTE: DEBUG_MODULE mode test with execution line - * node_scheduler ../../etc/SLURM.conf2 ../../etc/SLURM.jobs + * node_scheduler ../../etc/slurm.conf2 ../../etc/slurm.jobs * - * Author: Moe Jette, jette@llnl.gov + * author: moe jette, jette@llnl.gov */ #ifdef HAVE_CONFIG_H @@ -22,1086 +22,1365 @@ #define BUF_SIZE 1024 #define NO_VAL (-99) -struct Node_Set { /* Set of nodes with same configuration that could be allocated */ - int CPUs_Per_Node; - int Nodes; - int Weight; - int Feature; - unsigned *My_BitMap; +struct node_set { /* set of nodes with same configuration that could be allocated */ + int cpus_per_node; + int nodes; + int weight; + int feature; + unsigned *my_bitmap; }; -int Is_Key_Valid(int Key); -int Match_Group(char *AllowGroups, char *UserGroups); -int Match_Feature(char *Seek, char *Available); -int Parse_Job_Specs(char *Job_Specs, char **Req_Features, char **Req_Node_List, char **Job_Name, - char **Req_Group, char **Req_Partition, int *Contiguous, int *Req_CPUs, - int *Req_Nodes, int *Min_CPUs, int *Min_Memory, int *Min_TmpDisk, int *Key, int *Shared); -int Pick_Best_CPUs(unsigned *BitMap, unsigned *Req_BitMap, int Req_Nodes, int Req_CPUs, - int Consecutive); -int Pick_Best_Nodes(struct Node_Set *Node_Set_Ptr, int Node_Set_Size, unsigned **Req_BitMap, - int Req_CPUs, int Req_Nodes, int Contiguous, int Shared, int Max_Nodes); -int ValidFeatures(char *Requested, char *Available); +int is_key_valid (int key); +int match_group (char *allow_groups, char *user_groups); +int match_feature (char *seek, char *available); +int parse_job_specs (char *job_specs, char **req_features, + char **req_node_list, char **job_name, char **req_group, + char **req_partition, int *contiguous, int *req_cpus, + int *req_nodes, int *min_cpus, int *min_memory, + int *min_tmp_disk, int *key, int *shared); +int pick_best_cpus (unsigned *bitmap, unsigned *req_bitmap, int req_nodes, + int req_cpus, int consecutive); +int pick_best_nodes (struct node_set *node_set_ptr, int node_set_size, + unsigned **req_bitmap, int req_cpus, int req_nodes, + int contiguous, int shared, int max_nodes); +int valid_features (char *requested, char *available); #if DEBUG_MODULE /* main is used here for testing purposes only */ -main(int argc, char * argv[]) { - int Error_Code, Line_Num, i; - FILE *Command_File; - char In_Line[BUF_SIZE], *Node_List; - - if (argc < 3) { - printf("Usage: %s <slurm_conf_file> <slurm_job_file>\n", argv[0]); - exit(1); - } /* if */ - - Error_Code = Init_SLURM_Conf(); - if (Error_Code) { - printf("controller: Error %d from Init_SLURM_Conf\n", Error_Code); - exit(Error_Code); - } /* if */ - - Error_Code = Read_SLURM_Conf(argv[1]); - if (Error_Code) { - printf("controller: Error %d from Read_SLURM_Conf\n", Error_Code); - exit(Error_Code); - } /* if */ - - /* Mark everything up and idle for testing */ - for (i=0; i<Node_Record_Count; i++) { - BitMapSet(Idle_NodeBitMap, i); - BitMapSet(Up_NodeBitMap, i); - } /* for */ - - - Command_File = fopen(argv[2], "r"); - if (Command_File == NULL) { - fprintf(stderr, "node_scheduler: error %d opening command file %s\n", - errno, argv[2]); - exit(1); - } /* if */ - - i = ValidFeatures("FS1&FS2","FS1"); - if (i != 0) printf("ValidFeatures error 1\n"); - i = ValidFeatures("FS1|FS2","FS1"); - if (i != 1) printf("ValidFeatures error 2\n"); - i = ValidFeatures("FS1|FS2&FS3","FS1,FS3"); - if (i != 1) printf("ValidFeatures error 3\n"); - i = ValidFeatures("[FS1|FS2]&FS3","FS2,FS3"); - if (i != 2) printf("ValidFeatures error 4\n"); - i = ValidFeatures("FS0&[FS1|FS2]&FS3","FS2,FS3"); - if (i != 0) printf("ValidFeatures error 5\n"); - i = ValidFeatures("FS3&[FS1|FS2]&FS3","FS2,FS3"); - if (i != 2) printf("ValidFeatures error 6\n"); - - Line_Num = 0; - printf("\n"); - while (fgets(In_Line, BUF_SIZE, Command_File)) { - if (In_Line[strlen(In_Line)-1] == '\n') In_Line[strlen(In_Line)-1]=(char)NULL; - Line_Num++; - Error_Code = Select_Nodes(In_Line, &Node_List); - if (Error_Code) { - if (strncmp(In_Line, "JobName=FAIL", 12) != 0) printf("ERROR:"); - printf("For job: %s\n", In_Line, Node_List); - printf("node_scheduler: Error %d from Select_Nodes on line %d\n\n", Error_Code, Line_Num); - } else { - if (strncmp(In_Line, "JobName=FAIL", 12) == 0) printf("ERROR: "); - printf("For job: %s\n Nodes selected %s\n\n", In_Line, Node_List); - free(Node_List); - } /* else */ - } /* while */ -} /* main */ +main (int argc, char *argv[]) { + int error_code, line_num, i; + FILE *command_file; + char in_line[BUF_SIZE], *node_list; + + if (argc < 3) { + printf ("usage: %s <SLURM_CONF_file> <slurm_job_file>\n", + argv[0]); + exit (1); + } + + error_code = init_slurm_conf (); + if (error_code) { + printf ("controller: error %d from init_slurm_conf\n", + error_code); + exit (error_code); + } + + error_code = read_slurm_conf (argv[1]); + if (error_code) { + printf ("controller: error %d from read_slurm_conf\n", + error_code); + exit (error_code); + } + + /* mark everything up and idle for testing */ + for (i = 0; i < node_record_count; i++) { + bitmap_set (idle_node_bitmap, i); + bitmap_set (up_node_bitmap, i); + } /* for */ + + + command_file = fopen (argv[2], "r"); + if (command_file == NULL) { + fprintf (stderr, + "node_scheduler: error %d opening command file %s\n", + errno, argv[2]); + exit (1); + } + + i = valid_features ("fs1&fs2", "fs1"); + if (i != 0) + printf ("valid_features error 1\n"); + i = valid_features ("fs1|fs2", "fs1"); + if (i != 1) + printf ("valid_features error 2\n"); + i = valid_features ("fs1|fs2&fs3", "fs1,fs3"); + if (i != 1) + printf ("valid_features error 3\n"); + i = valid_features ("[fs1|fs2]&fs3", "fs2,fs3"); + if (i != 2) + printf ("valid_features error 4\n"); + i = valid_features ("fs0&[fs1|fs2]&fs3", "fs2,fs3"); + if (i != 0) + printf ("valid_features error 5\n"); + i = valid_features ("fs3&[fs1|fs2]&fs3", "fs2,fs3"); + if (i != 2) + printf ("valid_features error 6\n"); + + line_num = 0; + printf ("\n"); + while (fgets (in_line, BUF_SIZE, command_file)) { + if (in_line[strlen (in_line) - 1] == '\n') + in_line[strlen (in_line) - 1] = (char) NULL; + line_num++; + error_code = select_nodes (in_line, &node_list); + if (error_code) { + if (strncmp (in_line, "JobName=FAIL", 12) != 0) + printf ("ERROR:"); + printf ("for job: %s\n", in_line, node_list); + printf ("node_scheduler: error %d from select_nodes on line %d\n\n", + error_code, line_num); + } + else { + if (strncmp (in_line, "job_name=fail", 12) == 0) + printf ("ERROR: "); + printf ("for job: %s\n nodes selected %s\n\n", + in_line, node_list); + free (node_list); + } + } +} #endif -/* For a given bitmap, change the state of specified nodes to STAGE_IN */ -/* This is a simple prototype for testing */ -void Allocate_Nodes(unsigned *BitMap) { - int i; +/* for a given bitmap, change the state of specified nodes to stage_in */ +/* this is a simple prototype for testing */ +void allocate_nodes (unsigned *bitmap) { + int i; - for (i=0; i<Node_Record_Count; i++) { - if (BitMapValue(BitMap, i) == 0) continue; - Node_Record_Table_Ptr[i].NodeState = STATE_STAGE_IN; - BitMapClear(Idle_NodeBitMap, i); - } /* for */ - return; -} /* Allocate_Nodes */ + for (i = 0; i < node_record_count; i++) { + if (bitmap_value (bitmap, i) == 0) + continue; + node_record_table_ptr[i].node_state = STATE_STAGE_IN; + bitmap_clear (idle_node_bitmap, i); + } /* for */ + return; +} /* - * Count_CPUs - Report how many CPUs are associated with the identified nodes - * Input: BitMap - A node bitmap - * Output: Returns a CPU count + * count_cpus - report how many cpus are associated with the identified nodes + * input: bitmap - a node bitmap + * output: returns a cpu count */ -int Count_CPUs(unsigned *BitMap) { - int i, sum; +int count_cpus (unsigned *bitmap) { + int i, sum; - sum = 0; - for (i=0; i<Node_Record_Count; i++) { - if (BitMapValue(BitMap, i) != 1) continue; - sum += Node_Record_Table_Ptr[i].CPUs; - } /* for */ - return sum; -} /* Count_CPUs */ + sum = 0; + for (i = 0; i < node_record_count; i++) { + if (bitmap_value (bitmap, i) != 1) + continue; + sum += node_record_table_ptr[i].cpus; + } /* for */ + return sum; +} /* - * Is_Key_Valid - Determine if supplied key is valid - * Input: Key - A SLURM key acquired by user root - * Output: Returns 1 if key is valid, 0 otherwise - * NOTE: This is only a placeholder for a future function + * is_key_valid - determine if supplied key is valid + * input: key - a slurm key acquired by user root + * output: returns 1 if key is valid, 0 otherwise + * NOTE: this is only a placeholder for a future function */ -int Is_Key_Valid(int Key) { - if (Key == NO_VAL) return 0; - return 1; -} /* Is_Key_Valid */ +int is_key_valid (int key) { + if (key == NO_VAL) + return 0; + return 1; +} /* - * Match_Feature - Determine if the desired feature (Seek) is one of those available - * Input: Seek - Desired feature - * Available - Comma separated list of features - * Output: Returns 1 if found, 0 otherwise + * match_feature - determine if the desired feature (seek) is one of those available + * input: seek - desired feature + * available - comma separated list of features + * output: returns 1 if found, 0 otherwise */ -int Match_Feature(char *Seek, char *Available) { - char *Tmp_Available, *str_ptr3, *str_ptr4; - int found; +int match_feature (char *seek, char *available) { + char *tmp_available, *str_ptr3, *str_ptr4; + int found; - if (Seek == NULL) return 1; /* Nothing to look for */ - if (Available == NULL) return 0; /* Nothing to find */ + if (seek == NULL) + return 1; /* nothing to look for */ + if (available == NULL) + return 0; /* nothing to find */ - Tmp_Available = malloc(strlen(Available)+1); - if (Tmp_Available == NULL) { + tmp_available = malloc (strlen (available) + 1); + if (tmp_available == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "Match_Feature: unable to allocate memory\n"); + fprintf (stderr, + "match_feature: unable to allocate memory\n"); #else - syslog(LOG_ALERT, "Match_Feature: unable to allocate memory\n"); + syslog (LOG_ALERT, + "match_feature: unable to allocate memory\n"); #endif - return 1; /* Assume good for now */ - } /* if */ - strcpy(Tmp_Available, Available); + return 1; /* assume good for now */ + } + strcpy (tmp_available, available); - found = 0; - str_ptr3 = (char *)strtok_r(Tmp_Available, ",", &str_ptr4); - while (str_ptr3) { - if (strcmp(Seek, str_ptr3) == 0) { /* We have a match */ - found = 1; - break; - } /* if */ - str_ptr3 = (char *)strtok_r(NULL, ",", &str_ptr4); - } /* while (str_ptr3) */ + found = 0; + str_ptr3 = (char *) strtok_r (tmp_available, ",", &str_ptr4); + while (str_ptr3) { + if (strcmp (seek, str_ptr3) == 0) { /* we have a match */ + found = 1; + break; + } + str_ptr3 = (char *) strtok_r (NULL, ",", &str_ptr4); + } /* while (str_ptr3) */ - free(Tmp_Available); - return found; -} /* Match_Feature */ + free (tmp_available); + return found; +} /* - * Match_Group - Determine if the user is a member of any groups permitted to use this partition - * Input: AllowGroups - Comma delimited list of groups permitted to use the partition, - * NULL is for ALL groups - * UserGroups - Comma delimited list of groups the user belongs to - * Output: Returns 1 if user is member, 0 otherwise + * match_group - determine if the user is a member of any groups permitted to use this partition + * input: allow_groups - comma delimited list of groups permitted to use the partition, + * NULL is for all groups + * user_groups - comma delimited list of groups the user belongs to + * output: returns 1 if user is member, 0 otherwise */ -int Match_Group(char *AllowGroups, char *UserGroups) { - char *Tmp_Allow_Group, *str_ptr1, *str_ptr2; - char *Tmp_User_Group, *str_ptr3, *str_ptr4; +int match_group (char *allow_groups, char *user_groups) { + char *tmp_allow_group, *str_ptr1, *str_ptr2; + char *tmp_user_group, *str_ptr3, *str_ptr4; - if ((AllowGroups == NULL) || /* Anybody can use it */ - (strcmp(AllowGroups, "ALL") == 0)) return 1; - if (UserGroups == NULL) return 0; /* Empty group list */ + if ((allow_groups == NULL) || /* anybody can use it */ + (strcmp (allow_groups, "all") == 0)) + return 1; + if (user_groups == NULL) + return 0; /* empty group list */ - Tmp_Allow_Group = malloc(strlen(AllowGroups)+1); - if (Tmp_Allow_Group == NULL) { + tmp_allow_group = malloc (strlen (allow_groups) + 1); + if (tmp_allow_group == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "Match_Group: unable to allocate memory\n"); + fprintf (stderr, "match_group: unable to allocate memory\n"); #else - syslog(LOG_ALERT, "Match_Group: unable to allocate memory\n"); + syslog (LOG_ALERT, + "match_group: unable to allocate memory\n"); #endif - return 1; /* Assume good for now */ - } /* if */ - strcpy(Tmp_Allow_Group, AllowGroups); + return 1; /* assume good for now */ + } + strcpy (tmp_allow_group, allow_groups); - Tmp_User_Group = malloc(strlen(UserGroups)+1); - if (Tmp_User_Group == NULL) { + tmp_user_group = malloc (strlen (user_groups) + 1); + if (tmp_user_group == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "Match_Group: unable to allocate memory\n"); + fprintf (stderr, "match_group: unable to allocate memory\n"); #else - syslog(LOG_ALERT, "Match_Group: unable to allocate memory\n"); + syslog (LOG_ALERT, + "match_group: unable to allocate memory\n"); #endif - free(Tmp_Allow_Group); - return 1; /* Assume good for now */ - } /* if */ - - str_ptr1 = (char *)strtok_r(Tmp_Allow_Group, ",", &str_ptr2); - while (str_ptr1) { - strcpy(Tmp_User_Group, UserGroups); - str_ptr3 = (char *)strtok_r(Tmp_User_Group, ",", &str_ptr4); - while (str_ptr3) { - if (strcmp(str_ptr1, str_ptr3) == 0) { /* We have a match */ - free(Tmp_Allow_Group); - free(Tmp_User_Group); - return 1; - } /* if */ - str_ptr3 = (char *)strtok_r(NULL, ",", &str_ptr4); - } /* while (str_ptr3) */ - str_ptr1 = (char *)strtok_r(NULL, ",", &str_ptr2); - } /* while (str_ptr1) */ - free(Tmp_Allow_Group); - free(Tmp_User_Group); - return 0; /* No match */ -} /* Match_Group */ + free (tmp_allow_group); + return 1; /* assume good for now */ + } + + str_ptr1 = (char *) strtok_r (tmp_allow_group, ",", &str_ptr2); + while (str_ptr1) { + strcpy (tmp_user_group, user_groups); + str_ptr3 = (char *) strtok_r (tmp_user_group, ",", &str_ptr4); + while (str_ptr3) { + if (strcmp (str_ptr1, str_ptr3) == 0) { /* we have a match */ + free (tmp_allow_group); + free (tmp_user_group); + return 1; + } + str_ptr3 = (char *) strtok_r (NULL, ",", &str_ptr4); + } + str_ptr1 = (char *) strtok_r (NULL, ",", &str_ptr2); + } + free (tmp_allow_group); + free (tmp_user_group); + return 0; /* no match */ +} /* - * Parse_Job_Specs - Pick the appropriate fields out of a job request specification - * Input: Job_Specs - String containing the specification - * Req_Features, etc. - Pointers to storage for the specifications - * Output: Req_Features, etc. - The job's specifications - * Returns 0 if no error, errno otherwise - * NOTE: The calling function must free memory at Req_Features[0], Req_Node_List[0], - * Job_Name[0], Req_Group[0], and Req_Partition[0] + * parse_job_specs - pick the appropriate fields out of a job request specification + * input: job_specs - string containing the specification + * req_features, etc. - pointers to storage for the specifications + * output: req_features, etc. - the job's specifications + * returns 0 if no error, errno otherwise + * NOTE: the calling function must free memory at req_features[0], req_node_list[0], + * job_name[0], req_group[0], and req_partition[0] */ -int Parse_Job_Specs(char *Job_Specs, char **Req_Features, char **Req_Node_List, char **Job_Name, - char **Req_Group, char **Req_Partition, int *Contiguous, int *Req_CPUs, - int *Req_Nodes, int *Min_CPUs, int *Min_Memory, int *Min_TmpDisk, int *Key, int *Shared) { - int Bad_Index, Error_Code, i; - char *Temp_Specs; - - Req_Features[0] = Req_Node_List[0] = Req_Group[0] = Req_Partition[0] = Job_Name[0] = NULL; - *Contiguous = *Req_CPUs = *Req_Nodes = *Min_CPUs = *Min_Memory = *Min_TmpDisk = NO_VAL; - *Key = *Shared = NO_VAL; - - Temp_Specs = malloc(strlen(Job_Specs)+1); - if (Temp_Specs == NULL) { +int parse_job_specs (char *job_specs, char **req_features, char **req_node_list, + char **job_name, char **req_group, char **req_partition, + int *contiguous, int *req_cpus, int *req_nodes, + int *min_cpus, int *min_memory, int *min_tmp_disk, int *key, + int *shared) { + int bad_index, error_code, i; + char *temp_specs; + + req_features[0] = req_node_list[0] = req_group[0] = req_partition[0] = + job_name[0] = NULL; + *contiguous = *req_cpus = *req_nodes = *min_cpus = *min_memory = + *min_tmp_disk = NO_VAL; + *key = *shared = NO_VAL; + + temp_specs = malloc (strlen (job_specs) + 1); + if (temp_specs == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "Parse_Job_Specs: unable to allocate memory\n"); + fprintf (stderr, + "parse_job_specs: unable to allocate memory\n"); #else - syslog(LOG_ALERT, "Parse_Job_Specs: unable to allocate memory\n"); + syslog (LOG_ALERT, + "parse_job_specs: unable to allocate memory\n"); #endif - abort(); - } /* if */ - strcpy(Temp_Specs, Job_Specs); - - Error_Code = Load_String (Job_Name, "JobName=", Temp_Specs); - if (Error_Code) goto cleanup; - - Error_Code = Load_String (Req_Features, "Features=", Temp_Specs); - if (Error_Code) goto cleanup; - - Error_Code = Load_String (Req_Node_List, "NodeList=", Temp_Specs); - if (Error_Code) goto cleanup; - - Error_Code = Load_String (Req_Group, "Groups=", Temp_Specs); - if (Error_Code) goto cleanup; - - Error_Code = Load_String (Req_Partition, "Partition=", Temp_Specs); - if (Error_Code) goto cleanup; - - Error_Code = Load_Integer (Contiguous, "Contiguous", Temp_Specs); - if (Error_Code) goto cleanup; - - Error_Code = Load_Integer (Req_CPUs, "TotalCPUs=", Temp_Specs); - if (Error_Code) goto cleanup; - - Error_Code = Load_Integer (Req_Nodes, "TotalNodes=", Temp_Specs); - if (Error_Code) goto cleanup; - - Error_Code = Load_Integer (Min_CPUs, "MinCPUs=", Temp_Specs); - if (Error_Code) goto cleanup; - - Error_Code = Load_Integer (Min_Memory, "MinMemory=", Temp_Specs); - if (Error_Code) goto cleanup; - - Error_Code = Load_Integer (Min_TmpDisk, "MinTmpDisk=", Temp_Specs); - if (Error_Code) goto cleanup; - - Error_Code = Load_Integer (Key, "Key=", Temp_Specs); - if (Error_Code) goto cleanup; - - Error_Code = Load_Integer (Shared, "Shared=", Temp_Specs); - if (Error_Code) goto cleanup; - - Bad_Index = -1; - for (i=0; i<strlen(Temp_Specs); i++) { - if (isspace((int)Temp_Specs[i]) || (Temp_Specs[i] == '\n')) continue; - Bad_Index=i; - break; - } /* if */ + abort (); + } + strcpy (temp_specs, job_specs); + + error_code = load_string (job_name, "JobName=", temp_specs); + if (error_code) + goto cleanup; + + error_code = load_string (req_features, "Features=", temp_specs); + if (error_code) + goto cleanup; + + error_code = load_string (req_node_list, "NodeList=", temp_specs); + if (error_code) + goto cleanup; + + error_code = load_string (req_group, "Groups=", temp_specs); + if (error_code) + goto cleanup; + + error_code = load_string (req_partition, "Partition=", temp_specs); + if (error_code) + goto cleanup; + + error_code = load_integer (contiguous, "Contiguous", temp_specs); + if (error_code) + goto cleanup; + + error_code = load_integer (req_cpus, "TotalCPUs=", temp_specs); + if (error_code) + goto cleanup; + + error_code = load_integer (req_nodes, "TotalNodes=", temp_specs); + if (error_code) + goto cleanup; + + error_code = load_integer (min_cpus, "MinCPUs=", temp_specs); + if (error_code) + goto cleanup; + + error_code = load_integer (min_memory, "MinMemory=", temp_specs); + if (error_code) + goto cleanup; + + error_code = load_integer (min_tmp_disk, "MinTmpDisk=", temp_specs); + if (error_code) + goto cleanup; + + error_code = load_integer (key, "Key=", temp_specs); + if (error_code) + goto cleanup; + + error_code = load_integer (shared, "Shared=", temp_specs); + if (error_code) + goto cleanup; + + bad_index = -1; + for (i = 0; i < strlen (temp_specs); i++) { + if (isspace ((int) temp_specs[i]) || (temp_specs[i] == '\n')) + continue; + bad_index = i; + break; + } - if (Bad_Index != -1) { + if (bad_index != -1) { #if DEBUG_SYSTEM - fprintf(stderr, "Parse_Job_Specs: Bad job specification input: %s\n", - &Temp_Specs[Bad_Index]); + fprintf (stderr, + "parse_job_specs: bad job specification input: %s\n", + &temp_specs[bad_index]); #else - syslog(LOG_ERR, "Parse_Job_Specs: Bad job specification input: %s\n", - &Temp_Specs[Bad_Index]); + syslog (LOG_ERR, + "parse_job_specs: bad job specification input: %s\n", + &temp_specs[bad_index]); #endif - Error_Code = EINVAL; - } /* if */ - - free(Temp_Specs); - return Error_Code; - -cleanup: - free(Temp_Specs); - if (Req_Features[0]) free(Req_Features[0]); - if (Req_Node_List[0]) free(Req_Node_List[0]); - if (Req_Group[0]) free(Req_Group[0]); - if (Req_Partition[0]) free(Req_Partition[0]); - if (Job_Name[0]) free(Job_Name[0]); - Req_Features[0] = Req_Node_List[0] = Req_Group[0] = Req_Partition[0] = Job_Name[0] = NULL; -} /* Parse_Job_Specs */ + error_code = EINVAL; + } + + free (temp_specs); + return error_code; + + cleanup: + free (temp_specs); + if (req_features[0]) + free (req_features[0]); + if (req_node_list[0]) + free (req_node_list[0]); + if (req_group[0]) + free (req_group[0]); + if (req_partition[0]) + free (req_partition[0]); + if (job_name[0]) + free (job_name[0]); + req_features[0] = req_node_list[0] = req_group[0] = req_partition[0] = + job_name[0] = NULL; +} /* - * Pick_Best_CPUs - Identify the nodes which best fit the Req_Nodes and Req_CPUs counts - * Input: BitMap - The bit map to search - * Req_BitMap - The bit map of nodes that MUST be selected, if not NULL these - * have already been confirmed to be in the input BitMap - * Req_Nodes - Number of nodes required - * Req_CPUs - Number of CPUs required - * Consecutive - Nodes must be consecutive is 1, otherwise 0 - * Output: BitMap - Nodes NOT required to satisfy the request are cleared, other left set - * Returns zero on success, EINVAL otherwise - * NOTE: BitMap must be a superset of Req_Nodes at function call time + * pick_best_cpus - identify the nodes which best fit the req_nodes and req_cpus counts + * input: bitmap - the bit map to search + * req_bitmap - the bit map of nodes that must be selected, if not NULL these + * have already been confirmed to be in the input bitmap + * req_nodes - number of nodes required + * req_cpus - number of cpus required + * consecutive - nodes must be consecutive is 1, otherwise 0 + * output: bitmap - nodes not required to satisfy the request are cleared, other left set + * returns zero on success, EINVAL otherwise + * NOTE: bitmap must be a superset of req_nodes at function call time */ -int Pick_Best_CPUs(unsigned *BitMap, unsigned *Req_BitMap, int Req_Nodes, int Req_CPUs, - int Consecutive) { - int i, index, Error_Code, Sufficient; - int *Consec_Nodes; /* How many nodes we can add from this consecutive set of nodes */ - int *Consec_CPUs; /* How many nodes we can add from this consecutive set of nodes */ - int *Consec_Start; /* Where this consecutive set starts (index) */ - int *Consec_End; /* Where this consecutive set ends (index) */ - int *Consec_Req; /* Are nodes from this set required (in Req_BitMap) */ - int Consec_Index, Consec_Size; - int Rem_CPUs, Rem_Nodes; /* Remaining resources required */ - int Best_Fit_Nodes, Best_Fit_CPUs, Best_Fit_Req, Best_Fit_Location, Best_Fit_Sufficient; - - if (BitMap == NULL) { +int pick_best_cpus (unsigned *bitmap, unsigned *req_bitmap, int req_nodes, + int req_cpus, int consecutive) { + int i, index, error_code, sufficient; + int *consec_nodes; /* how many nodes we can add from this consecutive set of nodes */ + int *consec_cpus; /* how many nodes we can add from this consecutive set of nodes */ + int *consec_start; /* where this consecutive set starts (index) */ + int *consec_end; /* where this consecutive set ends (index) */ + int *consec_req; /* are nodes from this set required (in req_bitmap) */ + int consec_index, consec_size; + int rem_cpus, rem_nodes; /* remaining resources required */ + int best_fit_nodes, best_fit_cpus, best_fit_req, best_fit_location, + best_fit_sufficient; + + if (bitmap == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "Pick_Best_CPUs: BitMap pointer is NULL\n"); + fprintf (stderr, "pick_best_cpus: bitmap pointer is NULL\n"); #else - syslog(LOG_ALERT, "Pick_Best_CPUs: BitMap pointer is NULL\n"); + syslog (LOG_ALERT, + "pick_best_cpus: bitmap pointer is NULL\n"); #endif - abort(); - } /* if */ - - Error_Code = EINVAL; /* Default is no fit */ - Consec_Index = 0; - Consec_Size = 50; /* Start allocation for 50 sets of consecutive nodes */ - Consec_CPUs = malloc(sizeof(int)*Consec_Size); - Consec_Nodes = malloc(sizeof(int)*Consec_Size); - Consec_Start = malloc(sizeof(int)*Consec_Size); - Consec_End = malloc(sizeof(int)*Consec_Size); - Consec_Req = malloc(sizeof(int)*Consec_Size); - if ((Consec_CPUs == NULL) || (Consec_Nodes == NULL) || - (Consec_Start == NULL) || (Consec_End == NULL) || (Consec_Req == NULL)) { + abort (); + } + + error_code = EINVAL; /* default is no fit */ + consec_index = 0; + consec_size = 50; /* start allocation for 50 sets of consecutive nodes */ + consec_cpus = malloc (sizeof (int) * consec_size); + consec_nodes = malloc (sizeof (int) * consec_size); + consec_start = malloc (sizeof (int) * consec_size); + consec_end = malloc (sizeof (int) * consec_size); + consec_req = malloc (sizeof (int) * consec_size); + if ((consec_cpus == NULL) || (consec_nodes == NULL) || + (consec_start == NULL) || (consec_end == NULL) + || (consec_req == NULL)) { #if DEBUG_SYSTEM - fprintf(stderr, "Pick_Best_CPUs: unable to allocate memory\n"); + fprintf (stderr, + "pick_best_cpus: unable to allocate memory\n"); #else - syslog(LOG_ALERT, "Pick_Best_CPUs: unable to allocate memory\n"); + syslog (LOG_ALERT, + "pick_best_cpus: unable to allocate memory\n"); #endif - goto cleanup; - } /* if */ - - Consec_CPUs[Consec_Index] = Consec_Nodes[Consec_Index] = 0; - Consec_Req[Consec_Index] = -1; /* No required nodes here by default */ - Rem_CPUs = Req_CPUs; - Rem_Nodes = Req_Nodes; - for (index=0; index<Node_Record_Count; index++) { - if (BitMapValue(BitMap,index)) { - if (Consec_Nodes[Consec_Index] == 0) Consec_Start[Consec_Index] = index; - i = Node_Record_Table_Ptr[index].CPUs; - if (Req_BitMap && BitMapValue(Req_BitMap,index)) { - if (Consec_Req[Consec_Index] == -1) - Consec_Req[Consec_Index] = index; /* First required node in set */ - Rem_CPUs -= i; /* Reduce count of additional resources required */ - Rem_Nodes--; /* Reduce count of additional resources required */ - } else { - BitMapClear(BitMap, index); - Consec_CPUs[Consec_Index] += i; - Consec_Nodes[Consec_Index]++; - } /* else */ - } else if (Consec_Nodes[Consec_Index] == 0) { - Consec_Req[Consec_Index] = -1; /* Already picked up any required nodes */ - /* Re-use this record */ - } else { - Consec_End[Consec_Index] = index - 1; - if (++Consec_Index >= Consec_Size) { - Consec_Size *= 2; - Consec_CPUs = realloc(Consec_CPUs , sizeof(int)*Consec_Size); - Consec_Nodes = realloc(Consec_Nodes, sizeof(int)*Consec_Size); - Consec_Start = realloc(Consec_Start, sizeof(int)*Consec_Size); - Consec_End = realloc(Consec_End, sizeof(int)*Consec_Size); - Consec_Req = realloc(Consec_Req, sizeof(int)*Consec_Size); - if ((Consec_CPUs == NULL) || (Consec_Nodes == NULL) || - (Consec_Start == NULL) || (Consec_End == NULL) || (Consec_Req == NULL)) { + goto cleanup; + } + + consec_cpus[consec_index] = consec_nodes[consec_index] = 0; + consec_req[consec_index] = -1; /* no required nodes here by default */ + rem_cpus = req_cpus; + rem_nodes = req_nodes; + for (index = 0; index < node_record_count; index++) { + if (bitmap_value (bitmap, index)) { + if (consec_nodes[consec_index] == 0) + consec_start[consec_index] = index; + i = node_record_table_ptr[index].cpus; + if (req_bitmap && bitmap_value (req_bitmap, index)) { + if (consec_req[consec_index] == -1) + consec_req[consec_index] = index; /* first required node in set */ + rem_cpus -= i; /* reduce count of additional resources required */ + rem_nodes--; /* reduce count of additional resources required */ + } + else { + bitmap_clear (bitmap, index); + consec_cpus[consec_index] += i; + consec_nodes[consec_index]++; + } + } + else if (consec_nodes[consec_index] == 0) { + consec_req[consec_index] = -1; /* already picked up any required nodes */ + /* re-use this record */ + } + else { + consec_end[consec_index] = index - 1; + if (++consec_index >= consec_size) { + consec_size *= 2; + consec_cpus = + realloc (consec_cpus, + sizeof (int) * consec_size); + consec_nodes = + realloc (consec_nodes, + sizeof (int) * consec_size); + consec_start = + realloc (consec_start, + sizeof (int) * consec_size); + consec_end = + realloc (consec_end, + sizeof (int) * consec_size); + consec_req = + realloc (consec_req, + sizeof (int) * consec_size); + if ((consec_cpus == NULL) + || (consec_nodes == NULL) + || (consec_start == NULL) + || (consec_end == NULL) + || (consec_req == NULL)) { #if DEBUG_SYSTEM - fprintf(stderr, "Pick_Best_CPUs: unable to allocate memory\n"); + fprintf (stderr, + "pick_best_cpus: unable to allocate memory\n"); #else - syslog(LOG_ALERT, "Pick_Best_CPUs: unable to allocate memory\n"); + syslog (LOG_ALERT, + "pick_best_cpus: unable to allocate memory\n"); #endif - goto cleanup; - } /* if */ - } /* if */ - Consec_CPUs[Consec_Index] = 0; - Consec_Nodes[Consec_Index] = 0; - Consec_Req[Consec_Index] = -1; - } /* else */ - } /* for (index */ - if (Consec_Nodes[Consec_Index] != 0) Consec_End[Consec_Index++] = index-1; + goto cleanup; + } + } + consec_cpus[consec_index] = 0; + consec_nodes[consec_index] = 0; + consec_req[consec_index] = -1; + } + } + if (consec_nodes[consec_index] != 0) + consec_end[consec_index++] = index - 1; #if DEBUG_SYSTEM > 1 - printf("Rem_CPUs=%d, Rem_Nodes=%d\n", Rem_CPUs, Rem_Nodes); - for (i=0; i<Consec_Index; i++) { - printf("Start=%s, End=%s, Nodes=%d, CPUs=%d", - Node_Record_Table_Ptr[Consec_Start[i]].Name, - Node_Record_Table_Ptr[Consec_End[i]].Name, - Consec_Nodes[i], Consec_CPUs[i]); - if (Consec_Req[i] != -1) - printf(", Req=%s\n", Node_Record_Table_Ptr[Consec_Req[i]].Name); - else - printf("\n"); - } /* if */ + printf ("rem_cpus=%d, rem_nodes=%d\n", rem_cpus, rem_nodes); + for (i = 0; i < consec_index; i++) { + printf ("start=%s, end=%s, nodes=%d, cpus=%d", + node_record_table_ptr[consec_start[i]].name, + node_record_table_ptr[consec_end[i]].name, + consec_nodes[i], consec_cpus[i]); + if (consec_req[i] != -1) + printf (", req=%s\n", + node_record_table_ptr[consec_req[i]].name); + else + printf ("\n"); + } #endif - while (Consec_Index) { - Best_Fit_CPUs = Best_Fit_Nodes = Best_Fit_Sufficient = 0; - Best_Fit_Req = -1; /* First required node, -1 if none */ - for (i=0; i<Consec_Index; i++) { - if (Consec_Nodes[i] == 0) continue; - Sufficient = ((Consec_Nodes[i] >= Rem_Nodes) && (Consec_CPUs[i] >= Rem_CPUs)); - if ((Best_Fit_Nodes == 0) || /* First possibility */ - ((Best_Fit_Req == -1) && (Consec_Req[i] != -1)) || /* Required nodes */ - (Sufficient && (Best_Fit_Sufficient == 0)) || /* First large enough */ - (Sufficient && (Consec_CPUs[i] < Best_Fit_CPUs)) || /* Less waste option */ - ((Sufficient == 0) && (Consec_CPUs[i] > Best_Fit_CPUs))) { /* Larger option */ - Best_Fit_CPUs = Consec_CPUs[i]; - Best_Fit_Nodes = Consec_Nodes[i]; - Best_Fit_Location = i; - Best_Fit_Req = Consec_Req[i]; - Best_Fit_Sufficient = Sufficient; - } /* if */ - } /* for */ - if (Best_Fit_Nodes == 0) break; - if (Consecutive && ((Best_Fit_Nodes < Rem_Nodes) || (Best_Fit_CPUs < Rem_CPUs))) - break; /* No hole large enough */ - if (Best_Fit_Req != -1) { /* Work out from required nodes */ - for (i=Best_Fit_Req; i<=Consec_End[Best_Fit_Location]; i++) { - if ((Rem_Nodes <= 0) && (Rem_CPUs <= 0)) break; - if (BitMapValue(BitMap, i)) continue; - BitMapSet(BitMap, i); - Rem_Nodes--; - Rem_CPUs -= Node_Record_Table_Ptr[i].CPUs; - } /* for */ - for (i=(Best_Fit_Req-1); i>=Consec_Start[Best_Fit_Location]; i--) { - if ((Rem_Nodes <= 0) && (Rem_CPUs <= 0)) break; - /* if (BitMapValue(BitMap, i)) continue; nothing set earlier */ - BitMapSet(BitMap, i); - Rem_Nodes--; - Rem_CPUs -= Node_Record_Table_Ptr[i].CPUs; - } /* for */ - } else { - for (i=Consec_Start[Best_Fit_Location]; i<=Consec_End[Best_Fit_Location]; i++) { - if ((Rem_Nodes <= 0) && (Rem_CPUs <= 0)) break; - if (BitMapValue(BitMap, i)) continue; - BitMapSet(BitMap, i); - Rem_Nodes--; - Rem_CPUs -= Node_Record_Table_Ptr[i].CPUs; - } /* for */ - } /* else */ - if ((Rem_Nodes <= 0) && (Rem_CPUs <= 0)) { - Error_Code = 0; - break; - } /* if */ - Consec_CPUs[Best_Fit_Location] = 0; - Consec_Nodes[Best_Fit_Location] = 0; - } /* while */ - -cleanup: - if (Consec_CPUs ) free(Consec_CPUs); - if (Consec_Nodes) free(Consec_Nodes); - if (Consec_Start) free(Consec_Start); - if (Consec_End ) free(Consec_End); - if (Consec_Req ) free(Consec_Req); - return Error_Code; -} /* Pick_Best_CPUs */ + while (consec_index) { + best_fit_cpus = best_fit_nodes = best_fit_sufficient = 0; + best_fit_req = -1; /* first required node, -1 if none */ + for (i = 0; i < consec_index; i++) { + if (consec_nodes[i] == 0) + continue; + sufficient = ((consec_nodes[i] >= rem_nodes) + && (consec_cpus[i] >= rem_cpus)); + if ((best_fit_nodes == 0) || /* first possibility */ + ((best_fit_req == -1) && (consec_req[i] != -1)) || /* required nodes */ + (sufficient && (best_fit_sufficient == 0)) || /* first large enough */ + (sufficient && (consec_cpus[i] < best_fit_cpus)) || /* less waste option */ + ((sufficient == 0) && (consec_cpus[i] > best_fit_cpus))) { /* larger option */ + best_fit_cpus = consec_cpus[i]; + best_fit_nodes = consec_nodes[i]; + best_fit_location = i; + best_fit_req = consec_req[i]; + best_fit_sufficient = sufficient; + } + } /* for */ + if (best_fit_nodes == 0) + break; + if (consecutive + && ((best_fit_nodes < rem_nodes) + || (best_fit_cpus < rem_cpus))) + break; /* no hole large enough */ + if (best_fit_req != -1) { /* work out from required nodes */ + for (i = best_fit_req; + i <= consec_end[best_fit_location]; i++) { + if ((rem_nodes <= 0) && (rem_cpus <= 0)) + break; + if (bitmap_value (bitmap, i)) + continue; + bitmap_set (bitmap, i); + rem_nodes--; + rem_cpus -= node_record_table_ptr[i].cpus; + } /* for */ + for (i = (best_fit_req - 1); + i >= consec_start[best_fit_location]; i--) { + if ((rem_nodes <= 0) && (rem_cpus <= 0)) + break; + /* if (bitmap_value(bitmap, i)) continue; nothing set earlier */ + bitmap_set (bitmap, i); + rem_nodes--; + rem_cpus -= node_record_table_ptr[i].cpus; + } /* for */ + } + else { + for (i = consec_start[best_fit_location]; + i <= consec_end[best_fit_location]; i++) { + if ((rem_nodes <= 0) && (rem_cpus <= 0)) + break; + if (bitmap_value (bitmap, i)) + continue; + bitmap_set (bitmap, i); + rem_nodes--; + rem_cpus -= node_record_table_ptr[i].cpus; + } /* for */ + } + if ((rem_nodes <= 0) && (rem_cpus <= 0)) { + error_code = 0; + break; + } + consec_cpus[best_fit_location] = 0; + consec_nodes[best_fit_location] = 0; + } + + cleanup: + if (consec_cpus) + free (consec_cpus); + if (consec_nodes) + free (consec_nodes); + if (consec_start) + free (consec_start); + if (consec_end) + free (consec_end); + if (consec_req) + free (consec_req); + return error_code; +} /* - * Pick_Best_Nodes - From nodes satisfying partition and configuration specifications, + * pick_best_nodes - from nodes satisfying partition and configuration specifications, * select the "best" for use - * Input: Node_Set_Ptr - Pointer to node specification information - * Node_Set_Size - Number of entries in records pointed to by Node_Set_Ptr - * Req_BitMap - Pointer to bitmap of specific nodes required by the job, could be NULL - * Req_CPUs - Count of CPUs required by the job - * Req_Nodes - Count of nodes required by the job - * Contiguous - Set to 1 if allocated nodes must be contiguous, 0 otherwise - * Shared - Set to 1 if nodes may be shared, 0 otherwise - * Max_Nodes - Maximum number of nodes permitted for job, -1 for none (partition limit) - * Output: Req_BitMap - Pointer to bitmap of selected nodes - * Returns 0 on success, EAGAIN if request can not be satisfied now, + * input: node_set_ptr - pointer to node specification information + * node_set_size - number of entries in records pointed to by node_set_ptr + * req_bitmap - pointer to bitmap of specific nodes required by the job, could be NULL + * req_cpus - count of cpus required by the job + * req_nodes - count of nodes required by the job + * contiguous - set to 1 if allocated nodes must be contiguous, 0 otherwise + * shared - set to 1 if nodes may be shared, 0 otherwise + * max_nodes - maximum number of nodes permitted for job, -1 for none (partition limit) + * output: req_bitmap - pointer to bitmap of selected nodes + * returns 0 on success, EAGAIN if request can not be satisfied now, * EINVAL if request can never be satisfied (insufficient contiguous nodes) - * NOTE: The caller must free memory pointed to by Req_BitMap + * NOTE: the caller must free memory pointed to by req_bitmap */ -int Pick_Best_Nodes(struct Node_Set *Node_Set_Ptr, int Node_Set_Size, unsigned **Req_BitMap, - int Req_CPUs, int Req_Nodes, int Contiguous, int Shared, int Max_Nodes) { - int Error_Code, i, j, size; - int Total_Nodes, Total_CPUs; /* Total resources configured in partition */ - int Avail_Nodes, Avail_CPUs; /* Resources available for use now */ - unsigned *Avail_BitMap, *Total_BitMap; - int Max_Feature, Min_Feature; - int *CPUs_Per_Node; - int Avail_Set, Total_Set, Runable; - - if (Node_Set_Size == 0) return EINVAL; - if ((Max_Nodes != -1) && (Req_Nodes > Max_Nodes)) return EINVAL; - Error_Code = 0; - Avail_BitMap = Total_BitMap = NULL; - Avail_Nodes = Avail_CPUs = 0; - Total_Nodes = Total_CPUs = 0; - if (Req_BitMap[0]) { /* Specific nodes required */ - /* NOTE: We have already confirmed that all of these nodes have a usable */ - /* configuration and are in the proper partition */ - if (Req_Nodes != 0) Total_Nodes=BitMapCount(Req_BitMap[0]); - if (Req_CPUs != 0) Total_CPUs=Count_CPUs(Req_BitMap[0]); - if (Total_Nodes > Max_Nodes) return EINVAL; - if ((Req_Nodes <= Total_Nodes) && (Req_CPUs <= Total_CPUs)) { - if (BitMapIsSuper(Req_BitMap[0], Up_NodeBitMap) != 1) return EAGAIN; - if ((Shared != 1) && (BitMapIsSuper(Req_BitMap[0], Idle_NodeBitMap) != 1)) return EAGAIN; - return 0; /* User can have selected nodes, we're done! */ - } /* if */ - Total_Nodes = Total_CPUs = 0; /* reinitialize */ - } /* if */ - - /* Identify how many feature sets we have (e.g. "[FS1|FS2|FS3|FS4]" */ - Max_Feature = Min_Feature = Node_Set_Ptr[0].Feature; - for (i=1; i<Node_Set_Size; i++) { - if (Node_Set_Ptr[i].Feature > Max_Feature) Max_Feature = Node_Set_Ptr[i].Feature; - if (Node_Set_Ptr[i].Feature < Min_Feature) Min_Feature = Node_Set_Ptr[i].Feature; - } /* for */ - - Runable = 0; /* Assume not runable until otherwise demonstrated */ - for (j=Min_Feature; j<=Max_Feature; j++) { - Avail_Set = Total_Set = 0; - for (i=0; i<Node_Set_Size; i++) { - if (Node_Set_Ptr[i].Feature != j) continue; - if (Runable == 0) { - if (Total_Set) - BitMapOR(Total_BitMap, Node_Set_Ptr[i].My_BitMap); - else { - Total_BitMap = BitMapCopy(Node_Set_Ptr[i].My_BitMap); - if (Total_BitMap == NULL) { /* No memory */ - if (Avail_BitMap) free(Avail_BitMap); - return EAGAIN; - } /* if */ - Total_Set = 1; - } /* else */ - Total_Nodes += Node_Set_Ptr[i].Nodes; - Total_CPUs += (Node_Set_Ptr[i].Nodes * Node_Set_Ptr[i].CPUs_Per_Node); - } /* if */ - BitMapAND(Node_Set_Ptr[i].My_BitMap, Up_NodeBitMap); - if (Shared != 1) BitMapAND(Node_Set_Ptr[i].My_BitMap, Idle_NodeBitMap); - Node_Set_Ptr[i].Nodes = BitMapCount(Node_Set_Ptr[i].My_BitMap); - if (Avail_Set) - BitMapOR(Avail_BitMap, Node_Set_Ptr[i].My_BitMap); - else { - Avail_BitMap = BitMapCopy(Node_Set_Ptr[i].My_BitMap); - if (Avail_BitMap == NULL) { /* No memory */ - if (Total_BitMap) free(Total_BitMap); - return EAGAIN; - } /* if */ - Avail_Set = 1; - } /* else */ - Avail_Nodes += Node_Set_Ptr[i].Nodes; - Avail_CPUs += (Node_Set_Ptr[i].Nodes * Node_Set_Ptr[i].CPUs_Per_Node); - if ((Req_BitMap[0]) && (BitMapIsSuper(Req_BitMap[0],Avail_BitMap) == 0)) continue; - if (Avail_Nodes < Req_Nodes) continue; - if (Avail_CPUs < Req_CPUs ) continue; - Error_Code = Pick_Best_CPUs(Avail_BitMap, Req_BitMap[0], Req_Nodes, Req_CPUs, Contiguous); - if ((Error_Code == 0) && (Max_Nodes != -1) && - (BitMapCount(Avail_BitMap) > Max_Nodes)) { - Error_Code = EINVAL; - break; - } /* if */ - if (Error_Code == 0) { - if (Total_BitMap) free(Total_BitMap); - if (Req_BitMap[0]) free(Req_BitMap[0]); - Req_BitMap[0] = Avail_BitMap; - return 0; - } /* if */ - } /* for (i */ - if ((Error_Code == 0) && (Runable == 0) && - (Total_Nodes > Req_Nodes) && (Total_CPUs > Req_CPUs) && - ((Req_BitMap[0] == NULL) || (BitMapIsSuper(Req_BitMap[0],Avail_BitMap) == 1)) && - ((Max_Nodes == -1) || (Req_Nodes <= Max_Nodes))) { - /* Determine if job could possibly run (if configured nodes all available) */ - Error_Code = Pick_Best_CPUs(Total_BitMap, Req_BitMap[0], Req_Nodes, Req_CPUs, Contiguous); - if ((Error_Code == 0) && (Max_Nodes != -1) && - (BitMapCount(Avail_BitMap) > Max_Nodes)) Error_Code = EINVAL; - if (Error_Code == 0) Runable=1; - } /* if */ - if (Avail_BitMap) free(Avail_BitMap); - if (Total_BitMap) free(Total_BitMap); - Avail_BitMap = Total_BitMap = NULL; - if (Error_Code != 0) break; - } /* for (j */ - - if (Runable == 0) Error_Code=EINVAL; - if (Error_Code == 0) Error_Code=EAGAIN; - return Error_Code; -} /* Pick_Best_Nodes */ +int +pick_best_nodes (struct node_set *node_set_ptr, int node_set_size, + unsigned **req_bitmap, int req_cpus, int req_nodes, + int contiguous, int shared, int max_nodes) { + int error_code, i, j, size; + int total_nodes, total_cpus; /* total resources configured in partition */ + int avail_nodes, avail_cpus; /* resources available for use now */ + unsigned *avail_bitmap, *total_bitmap; + int max_feature, min_feature; + int *cpus_per_node; + int avail_set, total_set, runable; + + if (node_set_size == 0) + return EINVAL; + if ((max_nodes != -1) && (req_nodes > max_nodes)) + return EINVAL; + error_code = 0; + avail_bitmap = total_bitmap = NULL; + avail_nodes = avail_cpus = 0; + total_nodes = total_cpus = 0; + if (req_bitmap[0]) { /* specific nodes required */ + /* NOTE: we have already confirmed that all of these nodes have a usable */ + /* configuration and are in the proper partition */ + if (req_nodes != 0) + total_nodes = bitmap_count (req_bitmap[0]); + if (req_cpus != 0) + total_cpus = count_cpus (req_bitmap[0]); + if (total_nodes > max_nodes) + return EINVAL; + if ((req_nodes <= total_nodes) && (req_cpus <= total_cpus)) { + if (bitmap_is_super (req_bitmap[0], up_node_bitmap) != + 1) + return EAGAIN; + if ((shared != 1) + && + (bitmap_is_super (req_bitmap[0], idle_node_bitmap) + != 1)) + return EAGAIN; + return 0; /* user can have selected nodes, we're done! */ + } + total_nodes = total_cpus = 0; /* reinitialize */ + } + + /* identify how many feature sets we have (e.g. "[fs1|fs2|fs3|fs4]" */ + max_feature = min_feature = node_set_ptr[0].feature; + for (i = 1; i < node_set_size; i++) { + if (node_set_ptr[i].feature > max_feature) + max_feature = node_set_ptr[i].feature; + if (node_set_ptr[i].feature < min_feature) + min_feature = node_set_ptr[i].feature; + } /* for */ + + runable = 0; /* assume not runable until otherwise demonstrated */ + for (j = min_feature; j <= max_feature; j++) { + avail_set = total_set = 0; + for (i = 0; i < node_set_size; i++) { + if (node_set_ptr[i].feature != j) + continue; + if (runable == 0) { + if (total_set) + bitmap_or (total_bitmap, + node_set_ptr[i].my_bitmap); + else { + total_bitmap = + bitmap_copy (node_set_ptr[i]. + my_bitmap); + if (total_bitmap == NULL) { /* no memory */ + if (avail_bitmap) + free (avail_bitmap); + return EAGAIN; + } + total_set = 1; + } + total_nodes += node_set_ptr[i].nodes; + total_cpus += + (node_set_ptr[i].nodes * + node_set_ptr[i].cpus_per_node); + } + bitmap_and (node_set_ptr[i].my_bitmap, + up_node_bitmap); + if (shared != 1) + bitmap_and (node_set_ptr[i].my_bitmap, + idle_node_bitmap); + node_set_ptr[i].nodes = + bitmap_count (node_set_ptr[i].my_bitmap); + if (avail_set) + bitmap_or (avail_bitmap, + node_set_ptr[i].my_bitmap); + else { + avail_bitmap = + bitmap_copy (node_set_ptr[i]. + my_bitmap); + if (avail_bitmap == NULL) { /* no memory */ + if (total_bitmap) + free (total_bitmap); + return EAGAIN; + } + avail_set = 1; + } + avail_nodes += node_set_ptr[i].nodes; + avail_cpus += + (node_set_ptr[i].nodes * + node_set_ptr[i].cpus_per_node); + if ((req_bitmap[0]) + && (bitmap_is_super (req_bitmap[0], avail_bitmap) + == 0)) + continue; + if (avail_nodes < req_nodes) + continue; + if (avail_cpus < req_cpus) + continue; + error_code = + pick_best_cpus (avail_bitmap, req_bitmap[0], + req_nodes, req_cpus, + contiguous); + if ((error_code == 0) && (max_nodes != -1) + && (bitmap_count (avail_bitmap) > max_nodes)) { + error_code = EINVAL; + break; + } + if (error_code == 0) { + if (total_bitmap) + free (total_bitmap); + if (req_bitmap[0]) + free (req_bitmap[0]); + req_bitmap[0] = avail_bitmap; + return 0; + } + } /* for (i */ + if ((error_code == 0) && (runable == 0) && + (total_nodes > req_nodes) && (total_cpus > req_cpus) && + ((req_bitmap[0] == NULL) + || (bitmap_is_super (req_bitmap[0], avail_bitmap) == 1)) + && ((max_nodes == -1) || (req_nodes <= max_nodes))) { + /* determine if job could possibly run (if configured nodes all available) */ + error_code = + pick_best_cpus (total_bitmap, req_bitmap[0], + req_nodes, req_cpus, + contiguous); + if ((error_code == 0) && (max_nodes != -1) + && (bitmap_count (avail_bitmap) > max_nodes)) + error_code = EINVAL; + if (error_code == 0) + runable = 1; + } + if (avail_bitmap) + free (avail_bitmap); + if (total_bitmap) + free (total_bitmap); + avail_bitmap = total_bitmap = NULL; + if (error_code != 0) + break; + } /* for (j */ + + if (runable == 0) + error_code = EINVAL; + if (error_code == 0) + error_code = EAGAIN; + return error_code; +} /* - * Select_Nodes - Select and allocate nodes to a job with the given specifications - * Input: Job_Specs - Job specifications - * Node_List - Pointer to node list returned - * Output: Node_List - List of allocated nodes - * Returns 0 on success, EINVAL if not possible to satisfy request, + * select_nodes - select and allocate nodes to a job with the given specifications + * input: job_specs - job specifications + * node_list - pointer to node list returned + * output: node_list - list of allocated nodes + * returns 0 on success, EINVAL if not possible to satisfy request, * or EAGAIN if resources are presently busy - * NOTE: The calling program must free the memory pointed to by Node_List + * NOTE: the calling program must free the memory pointed to by node_list */ -int Select_Nodes(char *Job_Specs, char **Node_List) { - char *Req_Features, *Req_Node_List, *Job_Name, *Req_Group, *Req_Partition, *Out_Line; - int Contiguous, Req_CPUs, Req_Nodes, Min_CPUs, Min_Memory, Min_TmpDisk; - int Error_Code, CPU_Tally, Node_Tally, Key, Shared; - struct Part_Record *Part_Ptr; - unsigned *Req_BitMap, *Scratch_BitMap; - ListIterator Config_Record_Iterator; /* For iterating through Config_List */ - struct Config_Record *Config_Record_Point; /* Pointer to Config_Record */ - int i; - struct Node_Set *Node_Set_Ptr; - int Node_Set_Index, Node_Set_Size; - - Req_Features = Req_Node_List = Job_Name = Req_Group = Req_Partition = NULL; - Req_BitMap = Scratch_BitMap = NULL; - Contiguous = Req_CPUs = Req_Nodes = Min_CPUs = Min_Memory = Min_TmpDisk = NO_VAL; - Key = Shared = NO_VAL; - Node_Set_Ptr = NULL; - Config_Record_Iterator = NULL; - Node_List[0] = NULL; - Config_Record_Iterator = (ListIterator)NULL; - Node_Lock(); - Part_Lock(); - - /* Setup and basic parsing */ - Error_Code = Parse_Job_Specs(Job_Specs, &Req_Features, &Req_Node_List, &Job_Name, &Req_Group, - &Req_Partition, &Contiguous, &Req_CPUs, &Req_Nodes, &Min_CPUs, - &Min_Memory, &Min_TmpDisk, &Key, &Shared); - if (Error_Code != 0) { - Error_Code = EINVAL; /* Permanent error, invalid parsing */ +int +select_nodes (char *job_specs, char **node_list) { + char *req_features, *req_node_list, *job_name, *req_group, + *req_partition, *out_line; + int contiguous, req_cpus, req_nodes, min_cpus, min_memory, + min_tmp_disk; + int error_code, cpu_tally, node_tally, key, shared; + struct part_record *part_ptr; + unsigned *req_bitmap, *scratch_bitmap; + ListIterator config_record_iterator; /* for iterating through config_list */ + struct config_record *config_record_point; /* pointer to config_record */ + int i; + struct node_set *node_set_ptr; + int node_set_index, node_set_size; + + req_features = req_node_list = job_name = req_group = req_partition = + NULL; + req_bitmap = scratch_bitmap = NULL; + contiguous = req_cpus = req_nodes = min_cpus = min_memory = + min_tmp_disk = NO_VAL; + key = shared = NO_VAL; + node_set_ptr = NULL; + config_record_iterator = NULL; + node_list[0] = NULL; + config_record_iterator = (ListIterator) NULL; + node_lock (); + part_lock (); + + /* setup and basic parsing */ + error_code = + parse_job_specs (job_specs, &req_features, &req_node_list, + &job_name, &req_group, &req_partition, + &contiguous, &req_cpus, &req_nodes, + &min_cpus, &min_memory, &min_tmp_disk, &key, + &shared); + if (error_code != 0) { + error_code = EINVAL; /* permanent error, invalid parsing */ #if DEBUG_SYSTEM - fprintf(stderr, "Select_Nodes: Parsing failure on %s\n", Job_Specs); + fprintf (stderr, "select_nodes: parsing failure on %s\n", + job_specs); #else - syslog(LOG_NOTICE, "Select_Nodes: Parsing failure on %s\n", Job_Specs); + syslog (LOG_NOTICE, "select_nodes: parsing failure on %s\n", + job_specs); #endif - goto cleanup; - } /* if */ - if ((Req_CPUs == NO_VAL) && (Req_Nodes == NO_VAL) && (Req_Node_List == NULL)) { + goto cleanup; + } + if ((req_cpus == NO_VAL) && (req_nodes == NO_VAL) + && (req_node_list == NULL)) { #if DEBUG_SYSTEM - fprintf(stderr, "Select_Nodes: Job failed to specify NodeList, CPU or Node count\n"); + fprintf (stderr, + "select_nodes: job failed to specify node_list, cpu or node count\n"); #else - syslog(LOG_NOTICE, "Select_Nodes: Job failed to specify NodeList, CPU or Node count\n"); + syslog (LOG_NOTICE, + "select_nodes: job failed to specify node_list, cpu or node count\n"); #endif - Error_Code = EINVAL; - goto cleanup; - } /* if */ - if (Contiguous == NO_VAL) Contiguous=0; /* Default not contiguous */ - if (Req_CPUs == NO_VAL) Req_CPUs=0; /* Default no CPU count requirements */ - if (Req_Nodes == NO_VAL) Req_Nodes=0; /* Default no node count requirements */ - - - /* Find selected partition */ - if (Req_Partition) { - Part_Ptr = list_find_first(Part_List, &List_Find_Part, Req_Partition); - if (Part_Ptr == NULL) { + error_code = EINVAL; + goto cleanup; + } + if (contiguous == NO_VAL) + contiguous = 0; /* default not contiguous */ + if (req_cpus == NO_VAL) + req_cpus = 0; /* default no cpu count requirements */ + if (req_nodes == NO_VAL) + req_nodes = 0; /* default no node count requirements */ + + + /* find selected partition */ + if (req_partition) { + part_ptr = + list_find_first (part_list, &list_find_part, + req_partition); + if (part_ptr == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "Select_Nodes: Invalid partition specified: %s\n", Req_Partition); + fprintf (stderr, + "select_nodes: invalid partition specified: %s\n", + req_partition); #else - syslog(LOG_NOTICE, "Select_Nodes: Invalid partition specified: %s\n", Req_Partition); + syslog (LOG_NOTICE, + "select_nodes: invalid partition specified: %s\n", + req_partition); #endif - Error_Code = EINVAL; - goto cleanup; - } /* if */ - } else { - if (Default_Part_Loc == NULL) { + error_code = EINVAL; + goto cleanup; + } + } + else { + if (default_part_loc == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "Select_Nodes: Default partition not set.\n"); + fprintf (stderr, + "select_nodes: default partition not set.\n"); #else - syslog(LOG_ERR, "Select_Nodes: Default partition not set.\n"); + syslog (LOG_ERR, + "select_nodes: default partition not set.\n"); #endif - Error_Code = EINVAL; - goto cleanup; - } /* if */ - Part_Ptr = Default_Part_Loc; - } /* if */ + error_code = EINVAL; + goto cleanup; + } + part_ptr = default_part_loc; + } - /* Can this user access this partition */ - if (Part_Ptr->Key && (Is_Key_Valid(Key) == 0)) { + /* can this user access this partition */ + if (part_ptr->key && (is_key_valid (key) == 0)) { #if DEBUG_SYSTEM - fprintf(stderr, "Select_Nodes: Job lacks key required of partition %s\n", - Part_Ptr->Name); + fprintf (stderr, + "select_nodes: job lacks key required of partition %s\n", + part_ptr->name); #else - syslog(LOG_NOTICE, "Select_Nodes: Job lacks key required of partition %s\n", - Part_Ptr->Name); + syslog (LOG_NOTICE, + "select_nodes: job lacks key required of partition %s\n", + part_ptr->name); #endif - Error_Code = EINVAL; - goto cleanup; - } /* if */ - if (Match_Group(Part_Ptr->AllowGroups, Req_Group) == 0) { + error_code = EINVAL; + goto cleanup; + } + if (match_group (part_ptr->allow_groups, req_group) == 0) { #if DEBUG_SYSTEM - fprintf(stderr, "Select_Nodes: Job lacks group required of partition %s\n", - Part_Ptr->Name); + fprintf (stderr, + "select_nodes: job lacks group required of partition %s\n", + part_ptr->name); #else - syslog(LOG_NOTICE, "Select_Nodes: Job lacks group required of partition %s\n", - Part_Ptr->Name); + syslog (LOG_NOTICE, + "select_nodes: job lacks group required of partition %s\n", + part_ptr->name); #endif - Error_Code = EINVAL; - goto cleanup; - } /* if */ - - - /* Check if select partition has sufficient resources to satisfy request */ - if (Req_Node_List) { /* Insure that selected nodes are in this partition */ - Error_Code = NodeName2BitMap(Req_Node_List, &Req_BitMap); - if (Error_Code == EINVAL) goto cleanup; - if (Error_Code != 0) { - Error_Code = EAGAIN; /* No memory */ - goto cleanup; - } /* if */ - if (Contiguous == 1) BitMapFill(Req_BitMap); - if (BitMapIsSuper(Req_BitMap, Part_Ptr->NodeBitMap) != 1) { + error_code = EINVAL; + goto cleanup; + } + + + /* check if select partition has sufficient resources to satisfy request */ + if (req_node_list) { /* insure that selected nodes are in this partition */ + error_code = node_name2bitmap (req_node_list, &req_bitmap); + if (error_code == EINVAL) + goto cleanup; + if (error_code != 0) { + error_code = EAGAIN; /* no memory */ + goto cleanup; + } + if (contiguous == 1) + bitmap_fill (req_bitmap); + if (bitmap_is_super (req_bitmap, part_ptr->node_bitmap) != 1) { #if DEBUG_SYSTEM - fprintf(stderr, "Select_Nodes: Requested nodes %s not in partition %s\n", - Req_Node_List, Part_Ptr->Name); + fprintf (stderr, + "select_nodes: requested nodes %s not in partition %s\n", + req_node_list, part_ptr->name); #else - syslog(LOG_NOTICE, "Select_Nodes: Requested nodes %s not in partition %s\n", - Req_Node_List, Part_Ptr->Name); + syslog (LOG_NOTICE, + "select_nodes: requested nodes %s not in partition %s\n", + req_node_list, part_ptr->name); #endif - Error_Code = EINVAL; - goto cleanup; - } /* if */ - i = Count_CPUs(Req_BitMap); - if (i > Req_CPUs) Req_CPUs=i; - i = BitMapCount(Req_BitMap); - if (i > Req_Nodes) Req_Nodes=i; - } /* if */ - if (Req_CPUs > Part_Ptr->TotalCPUs) { + error_code = EINVAL; + goto cleanup; + } + i = count_cpus (req_bitmap); + if (i > req_cpus) + req_cpus = i; + i = bitmap_count (req_bitmap); + if (i > req_nodes) + req_nodes = i; + } + if (req_cpus > part_ptr->total_cpus) { #if DEBUG_SYSTEM - fprintf(stderr, "Select_Nodes: Too many CPUs (%d) requested of partition %s(%d)\n", - Req_CPUs, Part_Ptr->Name, Part_Ptr->TotalCPUs); + fprintf (stderr, + "select_nodes: too many cpus (%d) requested of partition %s(%d)\n", + req_cpus, part_ptr->name, part_ptr->total_cpus); #else - syslog(LOG_NOTICE, "Select_Nodes: Too many CPUs (%d) requested of partition %s(%d)\n", - Req_CPUs, Part_Ptr->Name, Part_Ptr->TotalCPUs); + syslog (LOG_NOTICE, + "select_nodes: too many cpus (%d) requested of partition %s(%d)\n", + req_cpus, part_ptr->name, part_ptr->total_cpus); #endif - Error_Code = EINVAL; - goto cleanup; - } /* if */ - if ((Req_Nodes > Part_Ptr->TotalNodes) || (Req_Nodes > Part_Ptr->MaxNodes)) { - if (Part_Ptr->TotalNodes > Part_Ptr->MaxNodes) - i = Part_Ptr->MaxNodes; - else - i = Part_Ptr->TotalNodes; + error_code = EINVAL; + goto cleanup; + } + if ((req_nodes > part_ptr->total_nodes) + || (req_nodes > part_ptr->max_nodes)) { + if (part_ptr->total_nodes > part_ptr->max_nodes) + i = part_ptr->max_nodes; + else + i = part_ptr->total_nodes; #if DEBUG_SYSTEM - fprintf(stderr, "Select_Nodes: Too many nodes (%d) requested of partition %s(%d)\n", - Req_Nodes, Part_Ptr->Name, i); + fprintf (stderr, + "select_nodes: too many nodes (%d) requested of partition %s(%d)\n", + req_nodes, part_ptr->name, i); #else - syslog(LOG_NOTICE, "Select_Nodes: Too many nodes (%d) requested of partition %s(%d)\n", - Req_Nodes, Part_Ptr->Name, i); + syslog (LOG_NOTICE, + "select_nodes: too many nodes (%d) requested of partition %s(%d)\n", + req_nodes, part_ptr->name, i); #endif - Error_Code = EINVAL; - goto cleanup; - } /* if */ - if (Part_Ptr->Shared == 2) /* Shared=FORCE */ - Shared = 1; - else if ((Shared != 1) || (Part_Ptr->Shared == 0)) /* User or partition want no sharing */ - Shared = 0; - - - /* Pick up nodes from the Weight ordered configuration list */ - Node_Set_Index = 0; - Node_Set_Size = 0; - Node_Set_Ptr = (struct Node_Set *)malloc(sizeof(struct Node_Set)); - if (Node_Set_Ptr == NULL) { + error_code = EINVAL; + goto cleanup; + } + if (part_ptr->shared == 2) /* shared=force */ + shared = 1; + else if ((shared != 1) || (part_ptr->shared == 0)) /* user or partition want no sharing */ + shared = 0; + + + /* pick up nodes from the weight ordered configuration list */ + node_set_index = 0; + node_set_size = 0; + node_set_ptr = (struct node_set *) malloc (sizeof (struct node_set)); + if (node_set_ptr == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "Select_Nodes: Unable to allocate memory\n"); + fprintf (stderr, "select_nodes: unable to allocate memory\n"); #else - syslog(LOG_ALERT, "Select_Nodes: Unable to allocate memory\n"); + syslog (LOG_ALERT, + "select_nodes: unable to allocate memory\n"); #endif - Error_Code = EAGAIN; - goto cleanup; - } /* if */ - Node_Set_Ptr[Node_Set_Size++].My_BitMap = NULL; - - Config_Record_Iterator = list_iterator_create(Config_List); - if (Config_Record_Iterator == NULL) { + error_code = EAGAIN; + goto cleanup; + } + node_set_ptr[node_set_size++].my_bitmap = NULL; + + config_record_iterator = list_iterator_create (config_list); + if (config_record_iterator == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "Select_Nodes: list_iterator_create unable to allocate memory\n"); + fprintf (stderr, + "select_nodes: ListIterator_create unable to allocate memory\n"); #else - syslog(LOG_ALERT, "Select_Nodes: list_iterator_create unable to allocate memory\n"); + syslog (LOG_ALERT, + "select_nodes: ListIterator_create unable to allocate memory\n"); #endif - Error_Code = EAGAIN; - goto cleanup; - } /* if */ - - while (Config_Record_Point = (struct Config_Record *)list_next(Config_Record_Iterator)) { - int Tmp_Feature, Check_Node_Config; - - Tmp_Feature = ValidFeatures(Req_Features, Config_Record_Point->Feature); - if (Tmp_Feature == 0) continue; - - /* Since nodes can register with more resources than defined in the configuration, */ - /* we want to use those higher values for scheduling, but only as needed */ - if ((Min_CPUs > Config_Record_Point->CPUs) || - (Min_Memory > Config_Record_Point->RealMemory) || - (Min_TmpDisk > Config_Record_Point->TmpDisk) ) - Check_Node_Config = 1; - else - Check_Node_Config = 0; - Node_Set_Ptr[Node_Set_Index].My_BitMap = BitMapCopy(Config_Record_Point->NodeBitMap); - if (Node_Set_Ptr[Node_Set_Index].My_BitMap == NULL) { - Error_Code = EAGAIN; /* No memory */ - goto cleanup; - } /* if */ - BitMapAND(Node_Set_Ptr[Node_Set_Index].My_BitMap, Part_Ptr->NodeBitMap); - Node_Set_Ptr[Node_Set_Index].Nodes = BitMapCount(Node_Set_Ptr[Node_Set_Index].My_BitMap); - /* Check configuration of individual nodes ONLY if the check of baseline values in the */ - /* configuration file are too low. This will slow the scheduling for very large cluster. */ - if (Check_Node_Config && (Node_Set_Ptr[Node_Set_Index].Nodes != 0)) { - for (i=0; i<Node_Record_Count; i++) { - if (BitMapValue(Node_Set_Ptr[Node_Set_Index].My_BitMap, i) == 0) continue; - if ((Min_CPUs <= Node_Record_Table_Ptr[i].CPUs) && - (Min_Memory <= Node_Record_Table_Ptr[i].RealMemory) && - (Min_TmpDisk <= Node_Record_Table_Ptr[i].TmpDisk)) continue; - BitMapClear(Node_Set_Ptr[Node_Set_Index].My_BitMap, i); - if ((--Node_Set_Ptr[Node_Set_Index].Nodes) == 0) break; - } /* for */ - } /* if */ - if (Node_Set_Ptr[Node_Set_Index].Nodes == 0) { - free(Node_Set_Ptr[Node_Set_Index].My_BitMap); - Node_Set_Ptr[Node_Set_Index].My_BitMap = NULL; - continue; - } /* if */ - if (Req_BitMap) { - if (Scratch_BitMap) - BitMapOR(Scratch_BitMap, Node_Set_Ptr[Node_Set_Index].My_BitMap); - else { - Scratch_BitMap = BitMapCopy(Node_Set_Ptr[Node_Set_Index].My_BitMap); - if (Scratch_BitMap == NULL) { - Error_Code = EAGAIN; - goto cleanup; - } /* if */ - } /* else */ - } /* if */ - Node_Set_Ptr[Node_Set_Index].CPUs_Per_Node = Config_Record_Point->CPUs; - Node_Set_Ptr[Node_Set_Index].Weight = Config_Record_Point->Weight; - Node_Set_Ptr[Node_Set_Index].Feature = Tmp_Feature; + error_code = EAGAIN; + goto cleanup; + } + + while (config_record_point = + (struct config_record *) list_next (config_record_iterator)) { + int tmp_feature, check_node_config; + + tmp_feature = + valid_features (req_features, + config_record_point->feature); + if (tmp_feature == 0) + continue; + + /* since nodes can register with more resources than defined in the configuration, */ + /* we want to use those higher values for scheduling, but only as needed */ + if ((min_cpus > config_record_point->cpus) || + (min_memory > config_record_point->real_memory) || + (min_tmp_disk > config_record_point->tmp_disk)) + check_node_config = 1; + else + check_node_config = 0; + node_set_ptr[node_set_index].my_bitmap = + bitmap_copy (config_record_point->node_bitmap); + if (node_set_ptr[node_set_index].my_bitmap == NULL) { + error_code = EAGAIN; /* no memory */ + goto cleanup; + } + bitmap_and (node_set_ptr[node_set_index].my_bitmap, + part_ptr->node_bitmap); + node_set_ptr[node_set_index].nodes = + bitmap_count (node_set_ptr[node_set_index].my_bitmap); + /* check configuration of individual nodes only if the check of baseline values in the */ + /* configuration file are too low. this will slow the scheduling for very large cluster. */ + if (check_node_config + && (node_set_ptr[node_set_index].nodes != 0)) { + for (i = 0; i < node_record_count; i++) { + if (bitmap_value + (node_set_ptr[node_set_index].my_bitmap, + i) == 0) + continue; + if ((min_cpus <= + node_record_table_ptr[i].cpus) + && (min_memory <= + node_record_table_ptr[i].real_memory) + && (min_tmp_disk <= + node_record_table_ptr[i].tmp_disk)) + continue; + bitmap_clear (node_set_ptr[node_set_index]. + my_bitmap, i); + if ((--node_set_ptr[node_set_index].nodes) == + 0) + break; + } /* for */ + } + if (node_set_ptr[node_set_index].nodes == 0) { + free (node_set_ptr[node_set_index].my_bitmap); + node_set_ptr[node_set_index].my_bitmap = NULL; + continue; + } + if (req_bitmap) { + if (scratch_bitmap) + bitmap_or (scratch_bitmap, + node_set_ptr[node_set_index]. + my_bitmap); + else { + scratch_bitmap = + bitmap_copy (node_set_ptr + [node_set_index]. + my_bitmap); + if (scratch_bitmap == NULL) { + error_code = EAGAIN; + goto cleanup; + } + } + } + node_set_ptr[node_set_index].cpus_per_node = + config_record_point->cpus; + node_set_ptr[node_set_index].weight = + config_record_point->weight; + node_set_ptr[node_set_index].feature = tmp_feature; #if DEBUG_MODULE > 1 - printf("Found %d usable nodes from configuration with %s\n", - Node_Set_Ptr[Node_Set_Index].Nodes, Config_Record_Point->Nodes); + printf ("found %d usable nodes from configuration with %s\n", + node_set_ptr[node_set_index].nodes, + config_record_point->nodes); #endif - Node_Set_Index++; - Node_Set_Ptr = (struct Node_Set *)realloc(Node_Set_Ptr, - sizeof(struct Node_Set)*(Node_Set_Index+1)); - if (Node_Set_Ptr == 0) { + node_set_index++; + node_set_ptr = (struct node_set *) realloc (node_set_ptr, + sizeof (struct + node_set) + * + (node_set_index + + 1)); + if (node_set_ptr == 0) { #if DEBUG_SYSTEM - fprintf(stderr, "Select_Nodes: Unable to allocate memory\n"); + fprintf (stderr, + "select_nodes: unable to allocate memory\n"); #else - syslog(LOG_ALERT, "Select_Nodes: Unable to allocate memory\n"); + syslog (LOG_ALERT, + "select_nodes: unable to allocate memory\n"); #endif - Error_Code = EAGAIN; /* No memory */ - goto cleanup; - } /* if */ - Node_Set_Ptr[Node_Set_Size++].My_BitMap = NULL; - } /* while */ - if (Node_Set_Index == 0) { + error_code = EAGAIN; /* no memory */ + goto cleanup; + } + node_set_ptr[node_set_size++].my_bitmap = NULL; + } + if (node_set_index == 0) { #if DEBUG_SYSTEM - fprintf(stderr, "Select_Nodes: No node configurations satisfy requirements %d:%d:%d:%s\n", - Min_CPUs, Min_Memory, Min_TmpDisk, Req_Features); + fprintf (stderr, + "select_nodes: no node configurations satisfy requirements %d:%d:%d:%s\n", + min_cpus, min_memory, min_tmp_disk, req_features); #else - syslog(LOG_NOTICE, "Select_Nodes: No node configurations satisfy requirements %d:%d:%d:%s\n", - Min_CPUs, Min_Memory, Min_TmpDisk, Req_Features); + syslog (LOG_NOTICE, + "select_nodes: no node configurations satisfy requirements %d:%d:%d:%s\n", + min_cpus, min_memory, min_tmp_disk, req_features); #endif - Error_Code = EINVAL; - goto cleanup; - } /* if */ - if (Node_Set_Ptr[Node_Set_Index].My_BitMap) free(Node_Set_Ptr[Node_Set_Index].My_BitMap); - Node_Set_Ptr[Node_Set_Index].My_BitMap = NULL; - Node_Set_Size = Node_Set_Index; - - if (Req_BitMap) { - if ((Scratch_BitMap == NULL) || (BitMapIsSuper(Req_BitMap, Scratch_BitMap) != 1)) { + error_code = EINVAL; + goto cleanup; + } + if (node_set_ptr[node_set_index].my_bitmap) + free (node_set_ptr[node_set_index].my_bitmap); + node_set_ptr[node_set_index].my_bitmap = NULL; + node_set_size = node_set_index; + + if (req_bitmap) { + if ((scratch_bitmap == NULL) + || (bitmap_is_super (req_bitmap, scratch_bitmap) != 1)) { #if DEBUG_SYSTEM - fprintf(stderr, "Select_Nodes: Requested nodes do not satisfy configurations requirements %d:%d:%d:%s\n", - Min_CPUs, Min_Memory, Min_TmpDisk, Req_Features); + fprintf (stderr, + "select_nodes: requested nodes do not satisfy configurations requirements %d:%d:%d:%s\n", + min_cpus, min_memory, min_tmp_disk, + req_features); #else - syslog(LOG_NOTICE, "Select_Nodes: Requested nodes do not satisfy configurations requirements %d:%d:%d:%s\n", - Min_CPUs, Min_Memory, Min_TmpDisk, Req_Features); + syslog (LOG_NOTICE, + "select_nodes: requested nodes do not satisfy configurations requirements %d:%d:%d:%s\n", + min_cpus, min_memory, min_tmp_disk, + req_features); #endif - Error_Code = EINVAL; - goto cleanup; - } /* if */ - } /* if */ - - - /* Pick the nodes providing a best-fit */ - Error_Code = Pick_Best_Nodes(Node_Set_Ptr, Node_Set_Size, - &Req_BitMap, Req_CPUs, Req_Nodes, Contiguous, Shared, Part_Ptr->MaxNodes); - if (Error_Code == EAGAIN) goto cleanup; - if (Error_Code == EINVAL) { + error_code = EINVAL; + goto cleanup; + } + } + + + /* pick the nodes providing a best-fit */ + error_code = pick_best_nodes (node_set_ptr, node_set_size, + &req_bitmap, req_cpus, req_nodes, + contiguous, shared, + part_ptr->max_nodes); + if (error_code == EAGAIN) + goto cleanup; + if (error_code == EINVAL) { #if DEBUG_SYSTEM - fprintf(stderr, "Select_Nodes: No nodes can satisfy job request\n"); + fprintf (stderr, + "select_nodes: no nodes can satisfy job request\n"); #else - syslog(LOG_NOTICE, "Select_Nodes: No nodes can satisfy job request\n"); + syslog (LOG_NOTICE, + "select_nodes: no nodes can satisfy job request\n"); #endif - goto cleanup; - } /* if */ - - /* Mark the selected nodes as STATE_STAGE_IN */ - Allocate_Nodes(Req_BitMap); - Error_Code = BitMap2NodeName(Req_BitMap, Node_List); - if (Error_Code) printf("BitMap2NodeName error %d\n", Error_Code); - - -cleanup: - Part_Unlock(); - Node_Unlock(); - if (Req_Features) free(Req_Features); - if (Req_Node_List) free(Req_Node_List); - if (Job_Name) free(Job_Name); - if (Req_Group) free(Req_Group); - if (Req_Partition) free(Req_Partition); - if (Req_BitMap) free(Req_BitMap); - if (Scratch_BitMap) free(Scratch_BitMap); - if (Node_Set_Ptr) { - for (i=0; i<Node_Set_Size; i++) { - if (Node_Set_Ptr[i].My_BitMap) free(Node_Set_Ptr[i].My_BitMap); - } /* for */ - free(Node_Set_Ptr); - } /* if */ - if (Config_Record_Iterator) list_iterator_destroy(Config_Record_Iterator); - return Error_Code; -} /* Select_Nodes */ - - -/* ValidFeatures - Determine if the Requested features are satisfied by those Available - * Input: Requested - Requested features (by a job) - * Available - Available features (on a node) - * Output: Returns 0 if request is not satisfied, otherwise an integer indicating - * which mutually exclusive feature is satisfied. For example - * ValidFeatures("[FS1|FS2|FS3|FS4]", "FS3") returns 3. See the - * SLURM administrator and user guides for details. Returns 1 if + goto cleanup; + } + + /* mark the selected nodes as STATE_STAGE_IN */ + allocate_nodes (req_bitmap); + error_code = bitmap2node_name (req_bitmap, node_list); + if (error_code) + printf ("bitmap2node_name error %d\n", error_code); + + + cleanup: + part_unlock (); + node_unlock (); + if (req_features) + free (req_features); + if (req_node_list) + free (req_node_list); + if (job_name) + free (job_name); + if (req_group) + free (req_group); + if (req_partition) + free (req_partition); + if (req_bitmap) + free (req_bitmap); + if (scratch_bitmap) + free (scratch_bitmap); + if (node_set_ptr) { + for (i = 0; i < node_set_size; i++) { + if (node_set_ptr[i].my_bitmap) + free (node_set_ptr[i].my_bitmap); + } /* for */ + free (node_set_ptr); + } + if (config_record_iterator) + list_iterator_destroy (config_record_iterator); + return error_code; +} + + +/* valid_features - determine if the requested features are satisfied by those available + * input: requested - requested features (by a job) + * available - available features (on a node) + * output: returns 0 if request is not satisfied, otherwise an integer indicating + * which mutually exclusive feature is satisfied. for example + * valid_features("[fs1|fs2|fs3|fs4]", "fs3") returns 3. see the + * slurm administrator and user guides for details. returns 1 if * requirements are satisfied without mutually exclusive feature list. */ -int ValidFeatures(char *Requested, char *Available) { - char *Tmp_Requested, *str_ptr1; - int bracket, found, i, option, position, result; - int last_op; /* Last operation 0 for OR, 1 for AND */ - int save_op, save_result; /* For bracket support */ - - if (Requested == NULL) return 1; /* No constraints */ - if (Available == NULL) return 0; /* No features */ - - Tmp_Requested = malloc(strlen(Requested)+1); - if (Tmp_Requested == NULL) { +int +valid_features (char *requested, char *available) { + char *tmp_requested, *str_ptr1; + int bracket, found, i, option, position, result; + int last_op; /* last operation 0 for or, 1 for and */ + int save_op, save_result; /* for bracket support */ + + if (requested == NULL) + return 1; /* no constraints */ + if (available == NULL) + return 0; /* no features */ + + tmp_requested = malloc (strlen (requested) + 1); + if (tmp_requested == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "ValidFeatures: unable to allocate memory\n"); + fprintf (stderr, + "valid_features: unable to allocate memory\n"); #else - syslog(LOG_ALERT, "ValidFeatures: unable to allocate memory\n"); + syslog (LOG_ALERT, + "valid_features: unable to allocate memory\n"); #endif - return 1; /* Assume good for now */ - } /* if */ - strcpy(Tmp_Requested, Requested); - - bracket = option = position = 0; - str_ptr1 = Tmp_Requested; /* Start of feature name */ - result = last_op = 1; /* Assume good for now */ - for (i=0; ; i++) { - if (Tmp_Requested[i] == (char)NULL) { - if (strlen(str_ptr1) == 0) break; - found = Match_Feature(str_ptr1, Available); - if (last_op == 1) /* AND */ - result &= found; - else /* OR */ - result |= found; - break; - } /* if */ - - if (Tmp_Requested[i] == '&') { - if (bracket != 0) { + return 1; /* assume good for now */ + } + strcpy (tmp_requested, requested); + + bracket = option = position = 0; + str_ptr1 = tmp_requested; /* start of feature name */ + result = last_op = 1; /* assume good for now */ + for (i = 0;; i++) { + if (tmp_requested[i] == (char) NULL) { + if (strlen (str_ptr1) == 0) + break; + found = match_feature (str_ptr1, available); + if (last_op == 1) /* and */ + result &= found; + else /* or */ + result |= found; + break; + } + + if (tmp_requested[i] == '&') { + if (bracket != 0) { #if DEBUG_SYSTEM - fprintf(stderr, "ValidFeatures: Parsing failure 1 on %s\n", Requested); + fprintf (stderr, + "valid_features: parsing failure 1 on %s\n", + requested); #else - syslog(LOG_NOTICE, "ValidFeatures: Parsing failure 1 on %s\n", Requested); + syslog (LOG_NOTICE, + "valid_features: parsing failure 1 on %s\n", + requested); #endif - result = 0; - break; - } /* if */ - Tmp_Requested[i] = (char)NULL; - found = Match_Feature(str_ptr1, Available); - if (last_op == 1) /* AND */ - result &= found; - else /* OR */ - result |= found; - str_ptr1 = &Tmp_Requested[i+1]; - last_op = 1; /* AND */ - - } else if (Tmp_Requested[i] == '|') { - Tmp_Requested[i] = (char)NULL; - found = Match_Feature(str_ptr1, Available); - if (bracket != 0) { - if (found) option=position; - position++; - } - if (last_op == 1) /* AND */ - result &= found; - else /* OR */ - result |= found; - str_ptr1 = &Tmp_Requested[i+1]; - last_op = 0; /* OR */ - - } else if (Tmp_Requested[i] == '[') { - bracket++; - position = 1; - save_op = last_op; - save_result = result; - last_op = result =1; - str_ptr1 = &Tmp_Requested[i+1]; - - } else if (Tmp_Requested[i] == ']') { - Tmp_Requested[i] = (char)NULL; - found = Match_Feature(str_ptr1, Available); - if (found) option=position; - result |= found; - if (save_op == 1) /* AND */ - result &= save_result; - else /* OR */ - result |= save_result; - if ((Tmp_Requested[i+1] == '&') && (bracket == 1)) { - last_op = 1; - str_ptr1 = &Tmp_Requested[i+2]; - } else if ((Tmp_Requested[i+1] == '|') && (bracket == 1)) { - last_op = 0; - str_ptr1 = &Tmp_Requested[i+2]; - } else if ((Tmp_Requested[i+1] == (char)NULL) && (bracket == 1)) { - break; - } else { + result = 0; + break; + } + tmp_requested[i] = (char) NULL; + found = match_feature (str_ptr1, available); + if (last_op == 1) /* and */ + result &= found; + else /* or */ + result |= found; + str_ptr1 = &tmp_requested[i + 1]; + last_op = 1; /* and */ + + } + else if (tmp_requested[i] == '|') { + tmp_requested[i] = (char) NULL; + found = match_feature (str_ptr1, available); + if (bracket != 0) { + if (found) + option = position; + position++; + } + if (last_op == 1) /* and */ + result &= found; + else /* or */ + result |= found; + str_ptr1 = &tmp_requested[i + 1]; + last_op = 0; /* or */ + + } + else if (tmp_requested[i] == '[') { + bracket++; + position = 1; + save_op = last_op; + save_result = result; + last_op = result = 1; + str_ptr1 = &tmp_requested[i + 1]; + + } + else if (tmp_requested[i] == ']') { + tmp_requested[i] = (char) NULL; + found = match_feature (str_ptr1, available); + if (found) + option = position; + result |= found; + if (save_op == 1) /* and */ + result &= save_result; + else /* or */ + result |= save_result; + if ((tmp_requested[i + 1] == '&') && (bracket == 1)) { + last_op = 1; + str_ptr1 = &tmp_requested[i + 2]; + } + else if ((tmp_requested[i + 1] == '|') + && (bracket == 1)) { + last_op = 0; + str_ptr1 = &tmp_requested[i + 2]; + } + else if ((tmp_requested[i + 1] == (char) NULL) + && (bracket == 1)) { + break; + } + else { #if DEBUG_SYSTEM - fprintf(stderr, "ValidFeatures: Parsing failure 2 on %s\n", Requested); + fprintf (stderr, + "valid_features: parsing failure 2 on %s\n", + requested); #else - syslog(LOG_NOTICE, "ValidFeatures: Parsing failure 2 on %s\n", Requested); + syslog (LOG_NOTICE, + "valid_features: parsing failure 2 on %s\n", + requested); #endif - result = 0; - break; - } /* else */ - bracket = 0; - } /* else */ - } /* for */ - - if (position) result *= option; - free(Tmp_Requested); - return result; -} /* ValidFeatures */ + result = 0; + break; + } + bracket = 0; + } + } /* for */ + + if (position) + result *= option; + free (tmp_requested); + return result; +} diff --git a/src/slurmctld/partition_mgr.c b/src/slurmctld/partition_mgr.c index 9e928c3e3844a5e534edb171fd0ef029a08b3771..d56834ee87d824dd22684dc30ffb37ee6504de08 100644 --- a/src/slurmctld/partition_mgr.c +++ b/src/slurmctld/partition_mgr.c @@ -1,8 +1,8 @@ /* - * partition_mgr.c - Manage the partition information of SLURM - * See slurm.h for documentation on external functions and data structures + * partition_mgr.c - manage the partition information of slurm + * see slurm.h for documentation on external functions and data structures * - * Author: Moe Jette, jette@llnl.gov + * author: moe jette, jette@llnl.gov */ #ifdef HAVE_CONFIG_H @@ -22,756 +22,901 @@ #define NO_VAL -99 #define SEPCHARS " \n\t" -struct Part_Record Default_Part; /* Default configuration values */ -List Part_List = NULL; /* Partition List */ -char Default_Part_Name[MAX_NAME_LEN]; /* Name of default partition */ -struct Part_Record *Default_Part_Loc = NULL; /* Location of default partition */ -time_t Last_Part_Update; /* Time of last update to Part Records */ -static pthread_mutex_t Part_Mutex= PTHREAD_MUTEX_INITIALIZER; /* Lock for partition info */ +struct part_record default_part; /* default configuration values */ +List part_list = NULL; /* partition list */ +char default_part_name[MAX_NAME_LEN]; /* name of default partition */ +struct part_record *default_part_loc = NULL; /* location of default partition */ +time_t last_part_update; /* time of last update to part records */ +static pthread_mutex_t part_mutex = PTHREAD_MUTEX_INITIALIZER; /* lock for partition info */ -int Build_Part_BitMap(struct Part_Record *Part_Record_Point); -void List_Delete_Part(void *Part_Entry); -int List_Find_Part(void *Part_Entry, void *key); +int build_part_bitmap (struct part_record *part_record_point); +void list_delete_part (void *part_entry); +int list_find_part (void *part_entry, void *key); #if DEBUG_MODULE /* main is used here for module testing purposes only */ -main(int argc, char * argv[]) { - int Error_Code; - time_t Update_Time; - struct Part_Record *Part_Ptr; - char *Dump; - int Dump_Size; - char Req_Name[MAX_NAME_LEN]; /* Name of the partition */ - char Next_Name[MAX_NAME_LEN]; /* Name of the next partition */ - int MaxTime; /* -1 if unlimited */ - int MaxNodes; /* -1 if unlimited */ - int TotalNodes; /* Total number of nodes in the partition */ - int TotalCPUs; /* Total number of CPUs in the partition */ - char *Nodes; /* Names of nodes in partition */ - char *AllowGroups; /* NULL indicates ALL */ - int Key; /* 1 if SLURM distributed key is required for use of partition */ - int StateUp; /* 1 if state is UP */ - int Shared; /* 1 if partition can be shared */ - unsigned *NodeBitMap; /* Bitmap of nodes in partition */ - int BitMapSize; /* Bytes in NodeBitMap */ - char Update_Spec[] = "MaxTime=34 MaxNodes=56 Key=NO State=DOWN Shared=FORCE"; - - Error_Code = Init_Node_Conf(); - if (Error_Code) printf("Init_Node_Conf error %d\n", Error_Code); - Part_Lock(); - Error_Code = Init_Part_Conf(); - if (Error_Code) printf("Init_Part_Conf error %d\n", Error_Code); - Default_Part.MaxTime = 223344; - Default_Part.MaxNodes = 556677; - Default_Part.TotalNodes = 4; - Default_Part.TotalCPUs = 16; - Default_Part.Key = 1; - Node_Record_Count = 8; - - printf("Create some partitions and test defaults\n"); - Part_Ptr = Create_Part_Record(&Error_Code); - if (Error_Code) - printf("Create_Part_Record error %d\n", Error_Code); - else { - static int Tmp_BitMap; - if (Part_Ptr->MaxTime != 223344) printf("ERROR: Partition default MaxTime not set\n"); - if (Part_Ptr->MaxNodes != 556677) printf("ERROR: Partition default MaxNodes not set\n"); - if (Part_Ptr->TotalNodes != 4) printf("ERROR: Partition default TotalNodes not set\n"); - if (Part_Ptr->TotalCPUs != 16) printf("ERROR: Partition default MaxNodes not set\n"); - if (Part_Ptr->Key != 1) printf("ERROR: Partition default Key not set\n"); - if (Part_Ptr->StateUp != 1) printf("ERROR: Partition default StateUp not set\n"); - if (Part_Ptr->Shared != 0) printf("ERROR: Partition default Shared not set\n"); - strcpy(Part_Ptr->Name, "Interactive"); - Part_Ptr->Nodes = "lx[01-04]"; - Part_Ptr->AllowGroups = "students"; - Tmp_BitMap = 0x3c << (sizeof(unsigned)*8-8); - Part_Ptr->NodeBitMap = &Tmp_BitMap; - } /* else */ - Part_Ptr = Create_Part_Record(&Error_Code); - if (Error_Code) - printf("Create_Part_Record error %d\n", Error_Code); - else - strcpy(Part_Ptr->Name, "Batch"); - Part_Ptr = Create_Part_Record(&Error_Code); - if (Error_Code) - printf("ERROR: Create_Part_Record error %d\n", Error_Code); - else - strcpy(Part_Ptr->Name, "Class"); - - Update_Time = (time_t)0; - Error_Code = Dump_Part(&Dump, &Dump_Size, &Update_Time); - if (Error_Code) printf("ERROR: Dump_Part error %d\n", Error_Code); - - Error_Code = Update_Part("Batch", Update_Spec); - if (Error_Code) printf("ERROR: Update_Part error %d\n", Error_Code); - - Part_Ptr = list_find_first(Part_List, &List_Find_Part, "Batch"); - if (Part_Ptr == NULL) printf("ERROR: list_find failure\n"); - if (Part_Ptr->MaxTime != 34) printf("ERROR: Update_Part MaxTime not reset\n"); - if (Part_Ptr->MaxNodes != 56) printf("ERROR: Update_Part MaxNodes not reset\n"); - if (Part_Ptr->Key != 0) printf("ERROR: Update_Part Key not reset\n"); - if (Part_Ptr->StateUp != 0) printf("ERROR: Update_Part StateUp not set\n"); - if (Part_Ptr->Shared != 2) printf("ERROR: Update_Part Shared not set\n"); - - Node_Record_Count = 0; /* Delete_Part_Record dies if node count is bad */ - Error_Code = Delete_Part_Record("Batch"); - if (Error_Code != 0) printf("Delete_Part_Record error1 %d\n", Error_Code); - printf("NOTE: We expect Delete_Part_Record to report not finding a record for Batch\n"); - Error_Code = Delete_Part_Record("Batch"); - if (Error_Code != ENOENT) printf("ERROR: Delete_Part_Record error2 %d\n", Error_Code); - Part_Unlock(); - - exit(0); -} /* main */ +main (int argc, char *argv[]) { + int error_code; + time_t update_time; + struct part_record *part_ptr; + char *dump; + int dump_size; + char req_name[MAX_NAME_LEN]; /* name of the partition */ + char next_name[MAX_NAME_LEN]; /* name of the next partition */ + int max_time; /* -1 if unlimited */ + int max_nodes; /* -1 if unlimited */ + int total_nodes; /* total number of nodes in the partition */ + int total_cpus; /* total number of cpus in the partition */ + char *nodes; /* names of nodes in partition */ + char *allow_groups; /* NULL indicates all */ + int key; /* 1 if slurm distributed key is required for use of partition */ + int state_up; /* 1 if state is up */ + int shared; /* 1 if partition can be shared */ + unsigned *node_bitmap; /* bitmap of nodes in partition */ + int bitmap_size; /* bytes in node_bitmap */ + char update_spec[] = + "MaxTime=34 MaxNodes=56 Key=NO State=DOWN Shared=FORCE"; + + error_code = init_node_conf (); + if (error_code) + printf ("init_node_conf error %d\n", error_code); + error_code = init_part_conf (); + if (error_code) + printf ("init_part_conf error %d\n", error_code); + default_part.max_time = 223344; + default_part.max_nodes = 556677; + default_part.total_nodes = 4; + default_part.total_cpus = 16; + default_part.key = 1; + node_record_count = 8; + + printf ("create some partitions and test defaults\n"); + part_ptr = create_part_record (&error_code); + if (error_code) + printf ("create_part_record error %d\n", error_code); + else { + int tmp_bitmap; + if (part_ptr->max_time != 223344) + printf ("ERROR: partition default max_time not set\n"); + if (part_ptr->max_nodes != 556677) + printf ("ERROR: partition default max_nodes not set\n"); + if (part_ptr->total_nodes != 4) + printf ("ERROR: partition default total_nodes not set\n"); + if (part_ptr->total_cpus != 16) + printf ("ERROR: partition default max_nodes not set\n"); + if (part_ptr->key != 1) + printf ("ERROR: partition default key not set\n"); + if (part_ptr->state_up != 1) + printf ("ERROR: partition default state_up not set\n"); + if (part_ptr->shared != 0) + printf ("ERROR: partition default shared not set\n"); + strcpy (part_ptr->name, "interactive"); + part_ptr->nodes = "lx[01-04]"; + part_ptr->allow_groups = "students"; + tmp_bitmap = 0x3c << (sizeof (unsigned) * 8 - 8); + part_ptr->node_bitmap = &tmp_bitmap; + } + part_ptr = create_part_record (&error_code); + if (error_code) + printf ("create_part_record error %d\n", error_code); + else + strcpy (part_ptr->name, "batch"); + part_ptr = create_part_record (&error_code); + if (error_code) + printf ("ERROR: create_part_record error %d\n", error_code); + else + strcpy (part_ptr->name, "class"); + + update_time = (time_t) 0; + error_code = dump_part (&dump, &dump_size, &update_time); + if (error_code) + printf ("ERROR: dump_part error %d\n", error_code); + + error_code = update_part ("batch", update_spec); + if (error_code) + printf ("ERROR: update_part error %d\n", error_code); + + part_ptr = list_find_first (part_list, &list_find_part, "batch"); + if (part_ptr == NULL) + printf ("ERROR: list_find failure\n"); + if (part_ptr->max_time != 34) + printf ("ERROR: update_part max_time not reset\n"); + if (part_ptr->max_nodes != 56) + printf ("ERROR: update_part max_nodes not reset\n"); + if (part_ptr->key != 0) + printf ("ERROR: update_part key not reset\n"); + if (part_ptr->state_up != 0) + printf ("ERROR: update_part state_up not set\n"); + if (part_ptr->shared != 2) + printf ("ERROR: update_part shared not set\n"); + + node_record_count = 0; /* delete_part_record dies if node count is bad */ + error_code = delete_part_record ("batch"); + if (error_code != 0) + printf ("delete_part_record error1 %d\n", error_code); + printf ("NOTE: we expect delete_part_record to report not finding a record for batch\n"); + error_code = delete_part_record ("batch"); + if (error_code != ENOENT) + printf ("ERROR: delete_part_record error2 %d\n", error_code); + + exit (0); +} #endif /* - * Build_Part_BitMap - Update the TotalCPUs, TotalNodes, and NodeBitMap for the specified partition - * Also reset the partition pointers in the node back to this partition. - * Input: Part_Record_Point - Pointer to the partition - * Output: Returns 0 if no error, errno otherwise - * NOTE: This does not report nodes defined in more than one partition. This is checked only + * build_part_bitmap - update the total_cpus, total_nodes, and node_bitmap for the specified partition + * also reset the partition pointers in the node back to this partition. + * input: part_record_point - pointer to the partition + * output: returns 0 if no error, errno otherwise + * NOTE: this does not report nodes defined in more than one partition. this is checked only * upon reading the configuration file, not on an update */ -int Build_Part_BitMap(struct Part_Record *Part_Record_Point) { - int Start_Inx, End_Inx, Count_Inx; - int i, j, Error_Code, size; - char *str_ptr1, *str_ptr2, *Format, *My_Node_List, This_Node_Name[BUF_SIZE]; - unsigned *Old_BitMap; - struct Node_Record *Node_Record_Point; /* Pointer to Node_Record */ - - Format = My_Node_List = NULL; - Part_Record_Point->TotalCPUs = 0; - Part_Record_Point->TotalNodes = 0; - - size = (Node_Record_Count + (sizeof(unsigned)*8) - 1) / - (sizeof(unsigned)*8); /* Unsigned int records in bitmap */ - size *= 8; /* Bytes in bitmap */ - if (Part_Record_Point->NodeBitMap == NULL) { - Part_Record_Point->NodeBitMap = malloc(size); - if (Part_Record_Point->NodeBitMap == NULL) { +int build_part_bitmap (struct part_record *part_record_point) { + int start_inx, end_inx, count_inx; + int i, j, error_code, size; + char *str_ptr1, *str_ptr2, *format, *my_node_list, + this_node_name[BUF_SIZE]; + unsigned *old_bitmap; + struct node_record *node_record_point; /* pointer to node_record */ + + format = my_node_list = NULL; + part_record_point->total_cpus = 0; + part_record_point->total_nodes = 0; + + size = (node_record_count + (sizeof (unsigned) * 8) - 1) / (sizeof (unsigned) * 8); /* unsigned int records in bitmap */ + size *= 8; /* bytes in bitmap */ + if (part_record_point->node_bitmap == NULL) { + part_record_point->node_bitmap = malloc (size); + if (part_record_point->node_bitmap == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "Build_Part_BitMap: unable to allocate memory\n"); + fprintf (stderr, + "build_part_bitmap: unable to allocate memory\n"); #else - syslog(LOG_ALERT, "Build_Part_BitMap: unable to allocate memory\n"); + syslog (LOG_ALERT, + "build_part_bitmap: unable to allocate memory\n"); #endif - abort(); - } /* if */ - Old_BitMap = NULL; - } else - Old_BitMap = BitMapCopy(Part_Record_Point->NodeBitMap); - memset(Part_Record_Point->NodeBitMap, 0, size); - - if (Part_Record_Point->Nodes == NULL) { - if (Old_BitMap) free(Old_BitMap); - return 0; - } /* if */ - My_Node_List = malloc(strlen(Part_Record_Point->Nodes)+1); - if (My_Node_List == NULL) { + abort (); + } + old_bitmap = NULL; + } + else + old_bitmap = bitmap_copy (part_record_point->node_bitmap); + memset (part_record_point->node_bitmap, 0, size); + + if (part_record_point->nodes == NULL) { + if (old_bitmap) + free (old_bitmap); + return 0; + } + my_node_list = malloc (strlen (part_record_point->nodes) + 1); + if (my_node_list == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "Build_Part_BitMap: unable to allocate memory\n"); + fprintf (stderr, + "build_part_bitmap: unable to allocate memory\n"); #else - syslog(LOG_ALERT, "Build_Part_BitMap: unable to allocate memory\n"); + syslog (LOG_ALERT, + "build_part_bitmap: unable to allocate memory\n"); #endif - if (Old_BitMap) free(Old_BitMap); - abort(); - } /* if */ - strcpy(My_Node_List, Part_Record_Point->Nodes); - - str_ptr2 = (char *)strtok_r(My_Node_List, ",", &str_ptr1); - while (str_ptr2) { /* Break apart by comma separators */ - Error_Code = Parse_Node_Name(str_ptr2, &Format, &Start_Inx, &End_Inx, &Count_Inx); - if (Error_Code) { - free(My_Node_List); - if (Old_BitMap) free(Old_BitMap); - return EINVAL; - } /* if */ - if (strlen(Format) >= sizeof(This_Node_Name)) { + if (old_bitmap) + free (old_bitmap); + abort (); + } + strcpy (my_node_list, part_record_point->nodes); + + str_ptr2 = (char *) strtok_r (my_node_list, ",", &str_ptr1); + while (str_ptr2) { /* break apart by comma separators */ + error_code = + parse_node_name (str_ptr2, &format, &start_inx, + &end_inx, &count_inx); + if (error_code) { + free (my_node_list); + if (old_bitmap) + free (old_bitmap); + return EINVAL; + } + if (strlen (format) >= sizeof (this_node_name)) { #if DEBUG_SYSTEM - fprintf(stderr, "Build_Part_BitMap: Node name specification too long: %s\n", Format); + fprintf (stderr, + "build_part_bitmap: node name specification too long: %s\n", + format); #else - syslog(LOG_ERR, "Build_Part_BitMap: Node name specification too long: %s\n", Format); + syslog (LOG_ERR, + "build_part_bitmap: node name specification too long: %s\n", + format); #endif - free(My_Node_List); - free(Format); - if (Old_BitMap) free(Old_BitMap); - return EINVAL; - } /* if */ - for (i=Start_Inx; i<=End_Inx; i++) { - if (Count_Inx == 0) - strncpy(This_Node_Name, Format, sizeof(This_Node_Name)); - else - sprintf(This_Node_Name, Format, i); - Node_Record_Point = Find_Node_Record(This_Node_Name); - if (Node_Record_Point == NULL) { + free (my_node_list); + free (format); + if (old_bitmap) + free (old_bitmap); + return EINVAL; + } + for (i = start_inx; i <= end_inx; i++) { + if (count_inx == 0) + strncpy (this_node_name, format, + sizeof (this_node_name)); + else + sprintf (this_node_name, format, i); + node_record_point = find_node_record (this_node_name); + if (node_record_point == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "Build_Part_BitMap: Invalid node specified %s\n", This_Node_Name); + fprintf (stderr, + "build_part_bitmap: invalid node specified %s\n", + this_node_name); #else - syslog(LOG_ERR, "Build_Part_BitMap: Invalid node specified %s\n", This_Node_Name); + syslog (LOG_ERR, + "build_part_bitmap: invalid node specified %s\n", + this_node_name); #endif - free(My_Node_List); - free(Format); - if (Old_BitMap) free(Old_BitMap); - return EINVAL; - } /* if */ - BitMapSet(Part_Record_Point->NodeBitMap, - (int)(Node_Record_Point - Node_Record_Table_Ptr)); - Part_Record_Point->TotalNodes++; - Part_Record_Point->TotalCPUs += Node_Record_Point->CPUs; - Node_Record_Point->Partition_Ptr = Part_Record_Point; - BitMapClear(Old_BitMap, (int)(Node_Record_Point - Node_Record_Table_Ptr)); - } /* for */ - str_ptr2 = (char *)strtok_r(NULL, ",", &str_ptr1); - } /* while */ - - /* Unlink nodes removed from the partition */ - for (i=0; i<Node_Record_Count; i++) { - if (BitMapValue(Old_BitMap, i) == 0) continue; - Node_Record_Table_Ptr[i].Partition_Ptr = NULL; - } /* for */ - - if(My_Node_List) free(My_Node_List); - if(Format) free(Format); - if (Old_BitMap) free(Old_BitMap); - return 0; -} /* Build_Part_BitMap */ + free (my_node_list); + free (format); + if (old_bitmap) + free (old_bitmap); + return EINVAL; + } + bitmap_set (part_record_point->node_bitmap, + (int) (node_record_point - + node_record_table_ptr)); + part_record_point->total_nodes++; + part_record_point->total_cpus += + node_record_point->cpus; + node_record_point->partition_ptr = part_record_point; + bitmap_clear (old_bitmap, + (int) (node_record_point - + node_record_table_ptr)); + } + str_ptr2 = (char *) strtok_r (NULL, ",", &str_ptr1); + } + + /* unlink nodes removed from the partition */ + for (i = 0; i < node_record_count; i++) { + if (bitmap_value (old_bitmap, i) == 0) + continue; + node_record_table_ptr[i].partition_ptr = NULL; + } + + if (my_node_list) + free (my_node_list); + if (format) + free (format); + if (old_bitmap) + free (old_bitmap); + return 0; +} /* - * Create_Part_Record - Create a partition record - * Input: Error_Code - Location to store error value in - * Output: Error_Code - Set to zero if no error, errno otherwise - * Returns a pointer to the record or NULL if error - * NOTE: The record's values are initialized to those of Default_Part - * NOTE: Allocates memory that should be freed with Delete_Part_Record + * create_part_record - create a partition record + * input: error_code - location to store error value in + * output: error_code - set to zero if no error, errno otherwise + * returns a pointer to the record or NULL if error + * NOTE: the record's values are initialized to those of default_part + * NOTE: allocates memory that should be freed with delete_part_record */ -struct Part_Record *Create_Part_Record(int *Error_Code) { - struct Part_Record *Part_Record_Point; +struct part_record * create_part_record (int *error_code) { + struct part_record *part_record_point; - *Error_Code = 0; - Last_Part_Update = time(NULL); + *error_code = 0; + last_part_update = time (NULL); - Part_Record_Point = (struct Part_Record *)malloc(sizeof(struct Part_Record)); - if (Part_Record_Point == NULL) { + part_record_point = + (struct part_record *) malloc (sizeof (struct part_record)); + if (part_record_point == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "Create_Part_Record: unable to allocate memory\n"); + fprintf (stderr, + "create_part_record: unable to allocate memory\n"); #else - syslog(LOG_ALERT, "Create_Part_Record: unable to allocate memory\n"); + syslog (LOG_ALERT, + "create_part_record: unable to allocate memory\n"); #endif - abort(); - } /* if */ - - strcpy(Part_Record_Point->Name, "DEFAULT"); - Part_Record_Point->MaxTime = Default_Part.MaxTime; - Part_Record_Point->MaxNodes = Default_Part.MaxNodes; - Part_Record_Point->Key = Default_Part.Key; - Part_Record_Point->StateUp = Default_Part.StateUp; - Part_Record_Point->Shared = Default_Part.Shared; - Part_Record_Point->TotalNodes = Default_Part.TotalNodes; - Part_Record_Point->TotalCPUs = Default_Part.TotalCPUs; - Part_Record_Point->NodeBitMap = NULL; + abort (); + } + + strcpy (part_record_point->name, "default"); + part_record_point->max_time = default_part.max_time; + part_record_point->max_nodes = default_part.max_nodes; + part_record_point->key = default_part.key; + part_record_point->state_up = default_part.state_up; + part_record_point->shared = default_part.shared; + part_record_point->total_nodes = default_part.total_nodes; + part_record_point->total_cpus = default_part.total_cpus; + part_record_point->node_bitmap = NULL; #if DEBUG_SYSTEM - Part_Record_Point->Magic = PART_MAGIC; + part_record_point->magic = PART_MAGIC; #endif - if (Default_Part.AllowGroups) { - Part_Record_Point->AllowGroups = (char *)malloc(strlen(Default_Part.AllowGroups)+1); - if (Part_Record_Point->AllowGroups == NULL) { + if (default_part.allow_groups) { + part_record_point->allow_groups = + (char *) malloc (strlen (default_part.allow_groups) + + 1); + if (part_record_point->allow_groups == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "Create_Part_Record: unable to allocate memory\n"); + fprintf (stderr, + "create_part_record: unable to allocate memory\n"); #else - syslog(LOG_ALERT, "Create_Part_Record: unable to allocate memory\n"); + syslog (LOG_ALERT, + "create_part_record: unable to allocate memory\n"); #endif - abort(); - } /* if */ - strcpy(Part_Record_Point->AllowGroups, Default_Part.AllowGroups); - } else - Part_Record_Point->AllowGroups = NULL; - - if (Default_Part.Nodes) { - Part_Record_Point->Nodes = (char *)malloc(strlen(Default_Part.Nodes)+1); - if (Part_Record_Point->Nodes == NULL) { + abort (); + } + strcpy (part_record_point->allow_groups, + default_part.allow_groups); + } + else + part_record_point->allow_groups = NULL; + + if (default_part.nodes) { + part_record_point->nodes = + (char *) malloc (strlen (default_part.nodes) + 1); + if (part_record_point->nodes == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "Create_Part_Record: unable to allocate memory\n"); + fprintf (stderr, + "create_part_record: unable to allocate memory\n"); #else - syslog(LOG_ALERT, "Create_Part_Record: unable to allocate memory\n"); + syslog (LOG_ALERT, + "create_part_record: unable to allocate memory\n"); #endif - abort(); - } /* if */ - strcpy(Part_Record_Point->Nodes, Default_Part.Nodes); - } else - Part_Record_Point->Nodes = NULL; + abort (); + } + strcpy (part_record_point->nodes, default_part.nodes); + } + else + part_record_point->nodes = NULL; - if (list_append(Part_List, Part_Record_Point) == NULL) { + if (list_append (part_list, part_record_point) == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "Create_Part_Record: unable to allocate memory\n"); + fprintf (stderr, + "create_part_record: unable to allocate memory\n"); #else - syslog(LOG_ALERT, "Create_Part_Record: unable to allocate memory\n"); + syslog (LOG_ALERT, + "create_part_record: unable to allocate memory\n"); #endif - abort(); - } /* if */ + abort (); + } - return Part_Record_Point; -} /* Create_Part_Record */ + return part_record_point; +} /* - * Delete_Part_Record - Delete record for partition with specified name - * Input: name - Name of the desired node, Delete all partitions if pointer is NULL - * Output: return 0 on success, errno otherwise + * delete_part_record - delete record for partition with specified name + * input: name - name of the desired node, delete all partitions if pointer is NULL + * output: return 0 on success, errno otherwise */ -int Delete_Part_Record(char *name) { - int i; +int delete_part_record (char *name) { + int i; - Last_Part_Update = time(NULL); - if (name == NULL) - i = list_delete_all(Part_List, &List_Find_Part, "UNIVERSAL_KEY"); - else - i = list_delete_all(Part_List, &List_Find_Part, name); - if ((name == NULL) || (i != 0)) return 0; + last_part_update = time (NULL); + if (name == NULL) + i = list_delete_all (part_list, &list_find_part, + "universal_key"); + else + i = list_delete_all (part_list, &list_find_part, name); + if ((name == NULL) || (i != 0)) + return 0; #if DEBUG_SYSTEM - fprintf(stderr, "Delete_Part_Record: Attempt to delete non-existent partition %s\n", name); + fprintf (stderr, + "delete_part_record: attempt to delete non-existent partition %s\n", + name); #else - syslog(LOG_ERR, "Delete_Part_Record: Attempt to delete non-existent partition %s\n", name); + syslog (LOG_ERR, + "delete_part_record: attempt to delete non-existent partition %s\n", + name); #endif - return ENOENT; -} /* Delete_Part_Record */ + return ENOENT; +} /* - * Dump_Part - Dump all partition information to a buffer - * Input: Buffer_Ptr - Location into which a pointer to the data is to be stored. - * The data buffer is actually allocated by Dump_Part and the + * dump_part - dump all partition information to a buffer + * input: buffer_ptr - location into which a pointer to the data is to be stored. + * the data buffer is actually allocated by dump_part and the * calling function must free the storage. - * Buffer_Size - Location into which the size of the created buffer is in bytes - * Update_Time - Dump new data only if partition records updated since time + * buffer_size - location into which the size of the created buffer is in bytes + * update_time - dump new data only if partition records updated since time * specified, otherwise return empty buffer - * Output: Buffer_Ptr - The pointer is set to the allocated buffer. - * Buffer_Size - Set to size of the buffer in bytes - * Update_Time - set to time partition records last updated - * Returns 0 if no error, errno otherwise - * NOTE: The buffer at *Buffer_Ptr must be freed by the caller - * NOTE: IF YOU MAKE ANY CHANGES HERE be sure to increment the value of PART_STRUCT_VERSION - * and make the corresponding changes to Load_Part_Name in api/partition_info.c + * output: buffer_ptr - the pointer is set to the allocated buffer. + * buffer_size - set to size of the buffer in bytes + * update_time - set to time partition records last updated + * returns 0 if no error, errno otherwise + * NOTE: the buffer at *buffer_ptr must be freed by the caller + * NOTE: if you make any changes here be sure to increment the value of PART_STRUCT_VERSION + * and make the corresponding changes to load_part_name in api/partition_info.c */ -int Dump_Part(char **Buffer_Ptr, int *Buffer_Size, time_t *Update_Time) { - ListIterator Part_Record_Iterator; /* For iterating through Part_Record_List */ - struct Part_Record *Part_Record_Point; /* Pointer to Part_Record */ - char *Buffer; - int Buffer_Offset, Buffer_Allocated, i, Record_Size; - char Out_Line[BUF_SIZE*2], *Nodes, *Key, *Default, *AllowGroups, *Shared, *State; - - Buffer_Ptr[0] = NULL; - *Buffer_Size = 0; - Buffer = NULL; - Buffer_Offset = 0; - Buffer_Allocated = 0; - if (*Update_Time == Last_Part_Update) return 0; - - Part_Lock(); - Part_Record_Iterator = list_iterator_create(Part_List); - if (Part_Record_Iterator == NULL) { +int dump_part (char **buffer_ptr, int *buffer_size, time_t * update_time) { + ListIterator part_record_iterator; /* for iterating through part_record_list */ + struct part_record *part_record_point; /* pointer to part_record */ + char *buffer; + int buffer_offset, buffer_allocated, i, record_size; + char out_line[BUF_SIZE * 2], *nodes, *key, *default_flag, *allow_groups, + *shared, *state; + + buffer_ptr[0] = NULL; + *buffer_size = 0; + buffer = NULL; + buffer_offset = 0; + buffer_allocated = 0; + if (*update_time == last_part_update) + return 0; + + part_record_iterator = list_iterator_create (part_list); + if (part_record_iterator == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "Dump_Part: list_iterator_create unable to allocate memory\n"); + fprintf (stderr, + "dump_part: list_iterator_create unable to allocate memory\n"); #else - syslog(LOG_ALERT, "Dump_Part: list_iterator_create unable to allocate memory\n"); + syslog (LOG_ALERT, + "dump_part: list_iterator_create unable to allocate memory\n"); #endif - abort(); - } /* if */ - - /* Write haeader, version and time */ - sprintf(Out_Line, HEAD_FORMAT, (unsigned long)Last_Part_Update, PART_STRUCT_VERSION); - if (Write_Buffer(&Buffer, &Buffer_Offset, &Buffer_Allocated, Out_Line)) goto cleanup; - - /* Write partition records */ - while (Part_Record_Point = (struct Part_Record *)list_next(Part_Record_Iterator)) { + abort (); + } + + /* write haeader, version and time */ + sprintf (out_line, HEAD_FORMAT, (unsigned long) last_part_update, + PART_STRUCT_VERSION); + if (write_buffer + (&buffer, &buffer_offset, &buffer_allocated, out_line)) + goto cleanup; + + /* write partition records */ + while (part_record_point = + (struct part_record *) list_next (part_record_iterator)) { #if DEBUG_SYSTEM - if (Part_Record_Point->Magic != PART_MAGIC) { + if (part_record_point->magic != PART_MAGIC) { #if DEBUG_SYSTEM - fprintf(stderr, "Dump_Part: Data integrity is bad\n"); + fprintf (stderr, + "dump_part: data integrity is bad\n"); #else - syslog(LOG_ALERT, "Dump_Part: Data integrity is bad\n"); + syslog (LOG_ALERT, + "dump_part: data integrity is bad\n"); #endif - abort(); - } /* if */ + abort (); + } #endif - if (Part_Record_Point->Nodes) - Nodes = Part_Record_Point->Nodes; - else - Nodes = "NONE"; - if (Part_Record_Point == Default_Part_Loc) - Default = "YES"; - else - Default = "NO"; - if (Part_Record_Point->Key) - Key = "YES"; - else - Key = "NO"; - if (Part_Record_Point->StateUp) - State = "UP"; - else - State = "DOWN"; - if (Part_Record_Point->Shared) - Shared = "YES"; - else - Shared = "NO"; - if (Part_Record_Point->AllowGroups) - AllowGroups = Part_Record_Point->AllowGroups; - else - AllowGroups = "ALL"; - sprintf(Out_Line, PART_STRUCT_FORMAT, - Part_Record_Point->Name, - Part_Record_Point->MaxNodes, - Part_Record_Point->MaxTime, - Nodes, - Key, - Default, - AllowGroups, - Shared, - State, - Part_Record_Point->TotalNodes, - Part_Record_Point->TotalCPUs); - - if (strlen(Out_Line) > BUF_SIZE) { + if (part_record_point->nodes) + nodes = part_record_point->nodes; + else + nodes = "NONE"; + if (part_record_point == default_part_loc) + default_flag = "YES"; + else + default_flag = "NO"; + if (part_record_point->key) + key = "YES"; + else + key = "NO"; + if (part_record_point->state_up) + state = "UP"; + else + state = "DONW"; + if (part_record_point->shared) + shared = "YES"; + else + shared = "NO"; + if (part_record_point->allow_groups) + allow_groups = part_record_point->allow_groups; + else + allow_groups = "ALL"; + sprintf (out_line, PART_STRUCT_FORMAT, + part_record_point->name, + part_record_point->max_nodes, + part_record_point->max_time, + nodes, + key, + default_flag, + allow_groups, + shared, + state, + part_record_point->total_nodes, + part_record_point->total_cpus); + + if (strlen (out_line) > BUF_SIZE) { #if DEBUG_SYSTEM - fprintf(stderr, "Dump_Part: buffer overflow for partition %s\n", Part_Record_Point->Name); + fprintf (stderr, + "dump_part: buffer overflow for partition %s\n", + part_record_point->name); #else - syslog(LOG_ALERT, "Dump_Part: buffer overflow for partition %s\n", Part_Record_Point->Name); + syslog (LOG_ALERT, + "dump_part: buffer overflow for partition %s\n", + part_record_point->name); #endif - if (strlen(Out_Line) > (2*BUF_SIZE)) abort(); - } /* if */ - - if (Write_Buffer(&Buffer, &Buffer_Offset, &Buffer_Allocated, Out_Line)) goto cleanup; - } /* while */ - - list_iterator_destroy(Part_Record_Iterator); - Buffer = realloc(Buffer, Buffer_Offset); - if (Buffer == NULL) { + if (strlen (out_line) > (2 * BUF_SIZE)) + abort (); + } + + if (write_buffer + (&buffer, &buffer_offset, &buffer_allocated, out_line)) + goto cleanup; + } + + list_iterator_destroy (part_record_iterator); + buffer = realloc (buffer, buffer_offset); + if (buffer == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "Dump_Part: unable to allocate memory\n"); + fprintf (stderr, "dump_part: unable to allocate memory\n"); #else - syslog(LOG_ALERT, "Dump_Part: unable to allocate memory\n"); + syslog (LOG_ALERT, "dump_part: unable to allocate memory\n"); #endif - abort(); - } /* if */ + abort (); + } - Buffer_Ptr[0] = Buffer; - *Buffer_Size = Buffer_Offset; - *Update_Time = Last_Part_Update; - Part_Unlock(); - return 0; + buffer_ptr[0] = buffer; + *buffer_size = buffer_offset; + *update_time = last_part_update; + return 0; -cleanup: - Part_Unlock(); - list_iterator_destroy(Part_Record_Iterator); - if (Buffer) free(Buffer); - return EINVAL; -} /* Dump_Part */ + cleanup: + list_iterator_destroy (part_record_iterator); + if (buffer) + free (buffer); + return EINVAL; +} /* - * Init_Part_Conf - Initialize the partition configuration values. - * This should be called before creating any partition entries. - * Output: return value - 0 if no error, otherwise an error code + * init_part_conf - initialize the partition configuration values. + * this should be called before creating any partition entries. + * output: return value - 0 if no error, otherwise an error code */ -int Init_Part_Conf() { - Last_Part_Update = time(NULL); - - strcpy(Default_Part.Name, "DEFAULT"); - Default_Part.AllowGroups = (char *)NULL; - Default_Part.MaxTime = -1; - Default_Part.MaxNodes = -1; - Default_Part.Key = 0; - Default_Part.StateUp = 1; - Default_Part.Shared = 0; - Default_Part.TotalNodes = 0; - Default_Part.TotalCPUs = 0; - if (Default_Part.Nodes) free(Default_Part.Nodes); - Default_Part.Nodes = (char *)NULL; - if (Default_Part.AllowGroups) free(Default_Part.AllowGroups); - Default_Part.AllowGroups = (char *)NULL; - if (Default_Part.NodeBitMap) free(Default_Part.NodeBitMap); - Default_Part.NodeBitMap = (unsigned *)NULL; - - if (Part_List) /* Delete defunct partitions */ - (void)Delete_Part_Record(NULL); - else - Part_List = list_create(&List_Delete_Part); - - if (Part_List == NULL) { +int init_part_conf () { + last_part_update = time (NULL); + + strcpy (default_part.name, "DEFAULT"); + default_part.allow_groups = (char *) NULL; + default_part.max_time = -1; + default_part.max_nodes = -1; + default_part.key = 0; + default_part.state_up = 1; + default_part.shared = 0; + default_part.total_nodes = 0; + default_part.total_cpus = 0; + if (default_part.nodes) + free (default_part.nodes); + default_part.nodes = (char *) NULL; + if (default_part.allow_groups) + free (default_part.allow_groups); + default_part.allow_groups = (char *) NULL; + if (default_part.node_bitmap) + free (default_part.node_bitmap); + default_part.node_bitmap = (unsigned *) NULL; + + if (part_list) /* delete defunct partitions */ + (void) delete_part_record (NULL); + else + part_list = list_create (&list_delete_part); + + if (part_list == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "Init_Part_Conf: list_create can not allocate memory\n"); + fprintf (stderr, + "init_part_conf: list_create can not allocate memory\n"); #else - syslog(LOG_ALERT, "Init_Part_Conf: list_create can not allocate memory\n"); + syslog (LOG_ALERT, + "init_part_conf: list_create can not allocate memory\n"); #endif - abort(); - } /* if */ - - strcpy(Default_Part_Name, ""); - Default_Part_Loc = (struct Part_Record *)NULL; - - return 0; -} /* Init_Part_Conf */ - - -/* List_Delete_Part - Delete an entry from the partition list, see list.h for documentation */ -void List_Delete_Part(void *Part_Entry) { - struct Part_Record *Part_Record_Point; /* Pointer to Part_Record */ - int i; - - Part_Record_Point = (struct Part_Record *)Part_Entry; - for (i=0; i<Node_Record_Count; i++) { - if (Node_Record_Table_Ptr[i].Partition_Ptr != Part_Record_Point) continue; - Node_Record_Table_Ptr[i].Partition_Ptr = NULL; - } /* if */ - if (Part_Record_Point->AllowGroups) free(Part_Record_Point->AllowGroups); - if (Part_Record_Point->Nodes) free(Part_Record_Point->Nodes); - if (Part_Record_Point->NodeBitMap) free(Part_Record_Point->NodeBitMap); - free(Part_Entry); -} /* List_Delete_Part */ - - -/* List_Find_Part - Find an entry in the partition list, see list.h for documentation - * Key is partition name or "UNIVERSAL_KEY" for all partitions */ -int List_Find_Part(void *Part_Entry, void *key) { - struct Part_Record *Part_Record_Point; /* Pointer to Part_Record */ - if (strcmp(key, "UNIVERSAL_KEY") == 0) return 1; - Part_Record_Point = (struct Part_Record *)Part_Entry; - if (strcmp(Part_Record_Point->Name, (char *)key) == 0) return 1; - return 0; -} /* List_Find_Part */ - - -/* Part_Lock - Lock the partition information */ -void Part_Lock() { - int Error_Code; - Error_Code = pthread_mutex_lock(&Part_Mutex); - if (Error_Code) { + abort (); + } + + strcpy (default_part_name, ""); + default_part_loc = (struct part_record *) NULL; + + return 0; +} + +/* list_delete_part - delete an entry from the partition list, see list.h for documentation */ +void list_delete_part (void *part_entry) { + struct part_record *part_record_point; /* pointer to part_record */ + int i; + + part_record_point = (struct part_record *) part_entry; + for (i = 0; i < node_record_count; i++) { + if (node_record_table_ptr[i].partition_ptr != + part_record_point) + continue; + node_record_table_ptr[i].partition_ptr = NULL; + } + if (part_record_point->allow_groups) + free (part_record_point->allow_groups); + if (part_record_point->nodes) + free (part_record_point->nodes); + if (part_record_point->node_bitmap) + free (part_record_point->node_bitmap); + free (part_entry); +} + + +/* list_find_part - find an entry in the partition list, see list.h for documentation + * key is partition name or "universal_key" for all partitions */ +int list_find_part (void *part_entry, void *key) { + struct part_record *part_record_point; /* pointer to part_record */ + if (strcmp (key, "universal_key") == 0) + return 1; + part_record_point = (struct part_record *) part_entry; + if (strcmp (part_record_point->name, (char *) key) == 0) + return 1; + return 0; +} + + +/* part_lock - lock the partition information */ +void part_lock () { + int error_code; + error_code = pthread_mutex_lock (&part_mutex); + if (error_code) { #if DEBUG_SYSTEM - fprintf(stderr, "Part_Lock: pthread_mutex_lock error %d\n", Error_Code); + fprintf (stderr, "part_lock: pthread_mutex_lock error %d\n", + error_code); #else - syslog(LOG_ALERT, "Part_Lock: pthread_mutex_lock error %d\n", Error_Code); + syslog (LOG_ALERT, "part_lock: pthread_mutex_lock error %d\n", + error_code); #endif - abort(); - } /* if */ -} /* Part_Lock */ + abort (); + } +} -/* Part_Unlock - Unlock the partition information */ -void Part_Unlock() { - int Error_Code; - Error_Code = pthread_mutex_unlock(&Part_Mutex); - if (Error_Code) { +/* part_unlock - unlock the partition information */ +void part_unlock () { + int error_code; + error_code = pthread_mutex_unlock (&part_mutex); + if (error_code) { #if DEBUG_SYSTEM - fprintf(stderr, "Part_Unlock: pthread_mutex_unlock error %d\n", Error_Code); + fprintf (stderr, + "part_unlock: pthread_mutex_unlock error %d\n", + error_code); #else - syslog(LOG_ALERT, "Part_Unlock: pthread_mutex_unlock error %d\n", Error_Code); + syslog (LOG_ALERT, + "part_unlock: pthread_mutex_unlock error %d\n", + error_code); #endif - abort(); - } /* if */ -} /* Part_Unlock */ + abort (); + } +} /* - * Update_Part - Update a partition's configuration data - * Input: PartitionName - Partition's name - * Spec - The updates to the partition's specification - * Output: Return - 0 if no error, otherwise an error code - * NOTE: The contents of Spec are overwritten by white space + * update_part - update a partition's configuration data + * input: partition_name - partition's name + * spec - the updates to the partition's specification + * output: return - 0 if no error, otherwise an error code + * NOTE: the contents of spec are overwritten by white space */ -int Update_Part(char *PartitionName, char *Spec) { - int Error_Code; - struct Part_Record *Part_Ptr; - int MaxTime_Val, MaxNodes_Val, Key_Val, State_Val, Shared_Val, Default_Val; - char *AllowGroups, *Nodes; - int Bad_Index, i; - - if (strcmp(PartitionName, "DEFAULT") == 0) { +int update_part (char *partition_name, char *spec) { + int error_code; + struct part_record *part_ptr; + int max_time_val, max_nodes_val, key_val, state_val, shared_val, + default_val; + char *allow_groups, *nodes; + int bad_index, i; + + if (strcmp (partition_name, "DEFAULT") == 0) { #if DEBUG_SYSTEM - fprintf(stderr, "Update_Part: Invalid partition name %s\n", PartitionName); + fprintf (stderr, "update_part: invalid partition name %s\n", + partition_name); #else - syslog(LOG_ALERT, "Update_Part: Invalid partition name %s\n", PartitionName); + syslog (LOG_ALERT, + "update_part: invalid partition name %s\n", + partition_name); #endif - return EINVAL; - } /* if */ + return EINVAL; + } - Node_Lock(); - Part_Lock(); - Part_Ptr = list_find_first(Part_List, &List_Find_Part, PartitionName); - if (Part_Ptr == 0) { + part_ptr = + list_find_first (part_list, &list_find_part, partition_name); + if (part_ptr == 0) { #if DEBUG_SYSTEM - fprintf(stderr, "Update_Part: Partition %s does not exist, being created.\n", PartitionName); + fprintf (stderr, + "update_part: partition %s does not exist, being created.\n", + partition_name); #else - syslog(LOG_ALERT, "Update_Part: Partition %s does not exist, being created.\n", PartitionName); + syslog (LOG_ALERT, + "update_part: partition %s does not exist, being created.\n", + partition_name); #endif - Part_Ptr = Create_Part_Record(&Error_Code); - if (Error_Code) goto cleanup; - } /* if */ - - MaxTime_Val = NO_VAL; - Error_Code = Load_Integer(&MaxTime_Val, "MaxTime=", Spec); - if (Error_Code) goto cleanup; - - MaxNodes_Val = NO_VAL; - Error_Code = Load_Integer(&MaxNodes_Val, "MaxNodes=", Spec); - if (Error_Code) goto cleanup; - - Key_Val = NO_VAL; - Error_Code = Load_Integer(&Key_Val, "Key=NO", Spec); - if (Error_Code) goto cleanup; - if (Key_Val == 1) Key_Val = 0; - Error_Code = Load_Integer(&Key_Val, "Key=YES", Spec); - if (Error_Code) goto cleanup; - - State_Val = NO_VAL; - Error_Code = Load_Integer(&State_Val, "State=DOWN", Spec); - if (Error_Code) goto cleanup; - if (State_Val == 1) State_Val = 0; - Error_Code = Load_Integer(&State_Val, "State=UP", Spec); - if (Error_Code) goto cleanup; - - Shared_Val = NO_VAL; - Error_Code = Load_Integer(&Shared_Val, "Shared=NO", Spec); - if (Error_Code) goto cleanup; - if (Shared_Val == 1) Shared_Val = 0; - Error_Code = Load_Integer(&Shared_Val, "Shared=FORCE", Spec); - if (Error_Code) goto cleanup; - if (Shared_Val == 1) Shared_Val = 2; - Error_Code = Load_Integer(&Shared_Val, "Shared=YES", Spec); - if (Error_Code) goto cleanup; - - Default_Val = NO_VAL; - Error_Code = Load_Integer(&Default_Val, "Default=YES", Spec); - if (Error_Code) goto cleanup; - - AllowGroups = NULL; - Error_Code = Load_String (&AllowGroups, "AllowGroups=", Spec); - if (Error_Code) goto cleanup; - - Nodes = NULL; - Error_Code = Load_String (&Nodes, "Nodes=", Spec); - if (Error_Code) goto cleanup; - - Bad_Index = -1; - for (i=0; i<strlen(Spec); i++) { - if (Spec[i] == '\n') Spec[i]=' '; - if (isspace((int)Spec[i])) continue; - Bad_Index=i; - break; - } /* if */ - - if (Bad_Index != -1) { + part_ptr = create_part_record (&error_code); + if (error_code) + goto cleanup; + } + + max_time_val = NO_VAL; + error_code = load_integer (&max_time_val, "MaxTime=", spec); + if (error_code) + goto cleanup; + + max_nodes_val = NO_VAL; + error_code = load_integer (&max_nodes_val, "MaxNodes=", spec); + if (error_code) + goto cleanup; + + key_val = NO_VAL; + error_code = load_integer (&key_val, "Key=NO", spec); + if (error_code) + goto cleanup; + if (key_val == 1) + key_val = 0; + error_code = load_integer (&key_val, "Key=YES", spec); + if (error_code) + goto cleanup; + + state_val = NO_VAL; + error_code = load_integer (&state_val, "State=DOWN", spec); + if (error_code) + goto cleanup; + if (state_val == 1) + state_val = 0; + error_code = load_integer (&state_val, "State=UP", spec); + if (error_code) + goto cleanup; + + shared_val = NO_VAL; + error_code = load_integer (&shared_val, "Shared=NO", spec); + if (error_code) + goto cleanup; + if (shared_val == 1) + shared_val = 0; + error_code = load_integer (&shared_val, "Shared=FORCE", spec); + if (error_code) + goto cleanup; + if (shared_val == 1) + shared_val = 2; + error_code = load_integer (&shared_val, "Shared=YES", spec); + if (error_code) + goto cleanup; + + default_val = NO_VAL; + error_code = load_integer (&default_val, "Default=YES", spec); + if (error_code) + goto cleanup; + + allow_groups = NULL; + error_code = load_string (&allow_groups, "AllowGroups=", spec); + if (error_code) + goto cleanup; + + nodes = NULL; + error_code = load_string (&nodes, "Nodes=", spec); + if (error_code) + goto cleanup; + + bad_index = -1; + for (i = 0; i < strlen (spec); i++) { + if (spec[i] == '\n') + spec[i] = ' '; + if (isspace ((int) spec[i])) + continue; + bad_index = i; + break; + } + + if (bad_index != -1) { #if DEBUG_SYSTEM - fprintf(stderr, "Update_Part: Ignored partition %s update specification: %s\n", - PartitionName, &Spec[Bad_Index]); + fprintf (stderr, + "update_part: ignored partition %s update specification: %s\n", + partition_name, &spec[bad_index]); #else - syslog(LOG_ERR, "Update_Part: Ignored partition %s update specification: %s\n", - PartitionName, &Spec[Bad_Index]); + syslog (LOG_ERR, + "update_part: ignored partition %s update specification: %s\n", + partition_name, &spec[bad_index]); #endif - Error_Code = EINVAL; - goto cleanup; - } /* if */ + error_code = EINVAL; + goto cleanup; + } - Last_Part_Update = time(NULL); - if (MaxTime_Val != NO_VAL) { + last_part_update = time (NULL); + if (max_time_val != NO_VAL) { #if DEBUG_SYSTEM - fprintf(stderr, "Update_Part: setting MaxTime to %d for partition %s\n", - MaxTime_Val, PartitionName); + fprintf (stderr, + "update_part: setting max_time to %d for partition %s\n", + max_time_val, partition_name); #else - syslog(LOG_NOTICE, "Update_Part: setting MaxTime to %d for partition %s\n", - MaxTime_Val, PartitionName); + syslog (LOG_NOTICE, + "update_part: setting max_time to %d for partition %s\n", + max_time_val, partition_name); #endif - Part_Ptr->MaxTime = MaxTime_Val; - }/* if */ + part_ptr->max_time = max_time_val; + } - if (MaxNodes_Val != NO_VAL) { + if (max_nodes_val != NO_VAL) { #if DEBUG_SYSTEM - fprintf(stderr, "Update_Part: setting MaxNodes to %d for partition %s\n", - MaxNodes_Val, PartitionName); + fprintf (stderr, + "update_part: setting max_nodes to %d for partition %s\n", + max_nodes_val, partition_name); #else - syslog(LOG_NOTICE, "Update_Part: setting MaxNodes to %d for partition %s\n", - MaxNodes_Val, PartitionName); + syslog (LOG_NOTICE, + "update_part: setting max_nodes to %d for partition %s\n", + max_nodes_val, partition_name); #endif - Part_Ptr->MaxNodes = MaxNodes_Val; - }/* if */ + part_ptr->max_nodes = max_nodes_val; + } - if (Key_Val != NO_VAL) { + if (key_val != NO_VAL) { #if DEBUG_SYSTEM - fprintf(stderr, "Update_Part: setting Key to %d for partition %s\n", - Key_Val, PartitionName); + fprintf (stderr, + "update_part: setting key to %d for partition %s\n", + key_val, partition_name); #else - syslog(LOG_NOTICE, "Update_Part: setting Key to %d for partition %s\n", - Key_Val, PartitionName); + syslog (LOG_NOTICE, + "update_part: setting key to %d for partition %s\n", + key_val, partition_name); #endif - Part_Ptr->Key = Key_Val; - }/* if */ + part_ptr->key = key_val; + } - if (State_Val != NO_VAL) { + if (state_val != NO_VAL) { #if DEBUG_SYSTEM - fprintf(stderr, "Update_Part: setting StateUp to %d for partition %s\n", - State_Val, PartitionName); + fprintf (stderr, + "update_part: setting state_up to %d for partition %s\n", + state_val, partition_name); #else - syslog(LOG_NOTICE, "Update_Part: setting StateUp to %d for partition %s\n", - State_Val, PartitionName); + syslog (LOG_NOTICE, + "update_part: setting state_up to %d for partition %s\n", + state_val, partition_name); #endif - Part_Ptr->StateUp = State_Val; - }/* if */ + part_ptr->state_up = state_val; + } - if (Shared_Val != NO_VAL) { + if (shared_val != NO_VAL) { #if DEBUG_SYSTEM - fprintf(stderr, "Update_Part: setting Shared to %d for partition %s\n", - Shared_Val, PartitionName); + fprintf (stderr, + "update_part: setting shared to %d for partition %s\n", + shared_val, partition_name); #else - syslog(LOG_NOTICE, "Update_Part: setting Shared to %d for partition %s\n", - Shared_Val, PartitionName); + syslog (LOG_NOTICE, + "update_part: setting shared to %d for partition %s\n", + shared_val, partition_name); #endif - Part_Ptr->Shared = Shared_Val; - }/* if */ + part_ptr->shared = shared_val; + } - if (Default_Val == 1) { + if (default_val == 1) { #if DEBUG_SYSTEM - fprintf(stderr, "Update_Part: changing default partition from %s to %s\n", - Default_Part_Name, PartitionName); + fprintf (stderr, + "update_part: changing default partition from %s to %s\n", + default_part_name, partition_name); #else - syslog(LOG_NOTICE, "Update_Part: changing default partition from %s to %s\n", - Default_Part_Name, PartitionName); + syslog (LOG_NOTICE, + "update_part: changing default partition from %s to %s\n", + default_part_name, partition_name); #endif - strcpy(Default_Part_Name, PartitionName); - Default_Part_Loc = Part_Ptr; - } /* if */ - - if (AllowGroups != NULL) { - if (Part_Ptr->AllowGroups) free(Part_Ptr->AllowGroups); - Part_Ptr->AllowGroups = AllowGroups; + strcpy (default_part_name, partition_name); + default_part_loc = part_ptr; + } + + if (allow_groups != NULL) { + if (part_ptr->allow_groups) + free (part_ptr->allow_groups); + part_ptr->allow_groups = allow_groups; #if DEBUG_SYSTEM - fprintf(stderr, "Update_Part: setting AllowGroups to %s for partition %s\n", - AllowGroups, PartitionName); + fprintf (stderr, + "update_part: setting allow_groups to %s for partition %s\n", + allow_groups, partition_name); #else - syslog(LOG_NOTICE, "Update_Part: setting AllowGroups to %s for partition %s\n", - AllowGroups, PartitionName); + syslog (LOG_NOTICE, + "update_part: setting allow_groups to %s for partition %s\n", + allow_groups, partition_name); #endif - } /* if */ + } - if (Nodes != NULL) { - if (Part_Ptr->Nodes) free(Part_Ptr->Nodes); - Part_Ptr->Nodes = Nodes; + if (nodes != NULL) { + if (part_ptr->nodes) + free (part_ptr->nodes); + part_ptr->nodes = nodes; #if DEBUG_SYSTEM - fprintf(stderr, "Update_Part: setting Nodes to %s for partition %s\n", - Nodes, PartitionName); + fprintf (stderr, + "update_part: setting nodes to %s for partition %s\n", + nodes, partition_name); #else - syslog(LOG_NOTICE, "Update_Part: setting Nodes to %s for partition %s\n", - Nodes, PartitionName); + syslog (LOG_NOTICE, + "update_part: setting nodes to %s for partition %s\n", + nodes, partition_name); #endif - /* Now we need to update TotalCPUs, TotalNodes, and NodeBitMap */ - Error_Code = Build_Part_BitMap(Part_Ptr); - if (Error_Code) goto cleanup; - } /* if */ - -cleanup: - Part_Unlock(); - Node_Unlock(); - return Error_Code; -} /* Update_Part */ + /* now we need to update total_cpus, total_nodes, and node_bitmap */ + error_code = build_part_bitmap (part_ptr); + if (error_code) + goto cleanup; + } + + cleanup: + return error_code; +} diff --git a/src/slurmctld/read_config.c b/src/slurmctld/read_config.c index 484fed37bd025e83d67e4ed34be023f97f72a17d..ed25e1d684bad44b2dd143aa1570d6dca27947bb 100644 --- a/src/slurmctld/read_config.c +++ b/src/slurmctld/read_config.c @@ -1,12 +1,12 @@ /* - * read_config.c - Read the overall SLURM configuration file - * See slurm.h for documentation on external functions and data structures + * read_config.c - read the overall slurm configuration file + * see slurm.h for documentation on external functions and data structures * * NOTE: DEBUG_MODULE mode test with execution line - * read_config ../../etc/SLURM.conf1 - * read_config ../../etc/SLURM.conf1 1000 + * read_config ../../etc/slurm.conf1 + * read_config ../../etc/slurm.conf1 1000 * - * Author: Moe Jette, jette@llnl.gov + * author: moe jette, jette@llnl.gov */ #ifdef HAVE_CONFIG_H @@ -25,715 +25,919 @@ #define BUF_SIZE 1024 #define NO_VAL (-99) -int Parse_Node_Spec(char *In_Line); -int Parse_Part_Spec(char *In_Line); +int parse_node_spec (char *in_line); +int parse_part_spec (char *in_line); -char *BackupController = NULL; -char *ControlMachine = NULL; +char *backup_controller = NULL; +char *control_machine = NULL; #if DEBUG_MODULE /* main is used here for module testing purposes only */ -main(int argc, char * argv[]) { - int Error_Code, Start_Inx, End_Inx, Count_Inx; - char Out_Line[BUF_SIZE]; - char *Format, *NodeName, *BitMap; - char *Partitions[] = {"login", "debug", "batch", "class", "END"}; - struct Part_Record *Part_Ptr; - int cycles, i, found; - - if (argc > 3) { - printf("Usage: %s <in_file> <cnt>\n", argv[0]); - exit(1); - } /* if */ - - Error_Code = Init_SLURM_Conf(); - if (Error_Code != 0) exit(Error_Code); - - if (argc >= 2) - Error_Code = Read_SLURM_Conf(argv[1]); - else - Error_Code = Read_SLURM_Conf(SLURM_CONF); - - if (Error_Code) { - printf("Error %d from Read_SLURM_Conf\n", Error_Code); - exit(1); - } /* if */ - - printf("ControlMachine=%s\n", ControlMachine); - printf("BackupController=%s\n", BackupController); - printf("\n"); - - for (i=0; i<Node_Record_Count; i++) { - if (strlen(Node_Record_Table_Ptr[i].Name) == 0) continue; - printf("NodeName=%s ", Node_Record_Table_Ptr[i].Name); - printf("NodeState=%s ", Node_State_String[Node_Record_Table_Ptr[i].NodeState]); - printf("LastResponse=%ld ", (long)Node_Record_Table_Ptr[i].LastResponse); - - printf("CPUs=%d ", Node_Record_Table_Ptr[i].CPUs); - printf("RealMemory=%d ", Node_Record_Table_Ptr[i].RealMemory); - printf("TmpDisk=%d ", Node_Record_Table_Ptr[i].TmpDisk); - printf("Weight=%d ", Node_Record_Table_Ptr[i].Config_Ptr->Weight); - printf("Feature=%s\n", Node_Record_Table_Ptr[i].Config_Ptr->Feature); - } /* for */ - BitMap = BitMapPrint(Up_NodeBitMap); - printf("\nUp_NodeBitMap =%s\n", BitMap); - free(BitMap); - BitMap = BitMapPrint(Idle_NodeBitMap); - printf("Idle_NodeBitMap=%s\n\n", BitMap); - free(BitMap); - - printf("Default_Part_Name=%s\n", Default_Part_Name); - found = 0; - for (i=0; ;i++) { - if (strcmp(Partitions[i], "END") == 0) { - if (found) break; - Part_Ptr = Default_Part_Loc; - } else { - Part_Ptr = list_find_first(Part_List, &List_Find_Part, Partitions[i]); - if (Part_Ptr == Default_Part_Loc) found = 1; - } /* else */ - if (Part_Ptr == NULL) continue; - printf("PartitionName=%s ", Part_Ptr->Name); - printf("MaxTime=%d ", Part_Ptr->MaxTime); - printf("MaxNodes=%d ", Part_Ptr->MaxNodes); - printf("Key=%d ", Part_Ptr->Key); - printf("StateUp=%d ", Part_Ptr->StateUp); - printf("Shared=%d ", Part_Ptr->Shared); - printf("Nodes=%s ", Part_Ptr->Nodes); - printf("TotalNodes=%d ", Part_Ptr->TotalNodes); - printf("TotalCPUs=%d ", Part_Ptr->TotalCPUs); - printf("AllowGroups=%s ", Part_Ptr->AllowGroups); - BitMap = BitMapPrint(Part_Ptr->NodeBitMap); - printf("NodeBitMap=%s\n", BitMap); - if (BitMap) free(BitMap); - } /* for */ - if (argc < 3) exit(0); - - cycles = atoi(argv[2]); - printf("Let's reinitialize the database %d times. Run /bin/ps to get memory size.\n", cycles); - sleep(5); - for (i=0; i<cycles; i++) { - Error_Code = Init_SLURM_Conf(); - if (Error_Code) { - printf("Error %d from Init_SLURM_Conf\n", Error_Code); - exit(Error_Code); - } /* if */ - - Error_Code = Read_SLURM_Conf(argv[1]); - if (Error_Code) { - printf("Error %d from Read_SLURM_Conf\n", Error_Code); - exit(Error_Code); - } /* if */ - } /* for */ - printf("All done. Run /bin/ps again look for increase in memory size (leakage).\n"); - sleep(10); - - exit(0); -} /* main */ +main (int argc, char *argv[]) { + int error_code, start_inx, end_inx, count_inx; + char out_line[BUF_SIZE]; + char *format, *node_name, *bitmap; + char *partitions[] = { "login", "debug", "batch", "class", "end" }; + struct part_record *part_ptr; + int cycles, i, found; + + if (argc > 3) { + printf ("usage: %s <in_file> <cnt>\n", argv[0]); + exit (1); + } + + error_code = init_slurm_conf (); + if (error_code != 0) + exit (error_code); + + if (argc >= 2) + error_code = read_slurm_conf (argv[1]); + else + error_code = read_slurm_conf (SLURM_CONF); + + if (error_code) { + printf ("error %d from read_slurm_conf\n", error_code); + exit (1); + } + + printf ("ControlMachine=%s\n", control_machine); + printf ("BackupController=%s\n", backup_controller); + printf ("\n"); + + for (i = 0; i < node_record_count; i++) { + if (strlen (node_record_table_ptr[i].name) == 0) + continue; + printf ("NodeName=%s ", node_record_table_ptr[i].name); + printf ("NodeState=%s ", + node_state_string[node_record_table_ptr[i]. + node_state]); + printf ("LastResponse=%ld ", + (long) node_record_table_ptr[i].last_response); + + printf ("CPUs=%d ", node_record_table_ptr[i].cpus); + printf ("RealMemory=%d ", + node_record_table_ptr[i].real_memory); + printf ("TmpDisk=%d ", node_record_table_ptr[i].tmp_disk); + printf ("Weight=%d ", + node_record_table_ptr[i].config_ptr->weight); + printf ("Feature=%s\n", + node_record_table_ptr[i].config_ptr->feature); + } + bitmap = bitmap_print (up_node_bitmap); + printf ("\nup_node_bitmap =%s\n", bitmap); + free (bitmap); + bitmap = bitmap_print (idle_node_bitmap); + printf ("idle_node_bitmap=%s\n\n", bitmap); + free (bitmap); + + printf ("default_part_name=%s\n", default_part_name); + found = 0; + for (i = 0;; i++) { + if (strcmp (partitions[i], "end") == 0) { + if (found) + break; + part_ptr = default_part_loc; + } + else { + part_ptr = + list_find_first (part_list, &list_find_part, + partitions[i]); + if (part_ptr == default_part_loc) + found = 1; + } /* else */ + if (part_ptr == NULL) + continue; + printf ("PartitionName=%s ", part_ptr->name); + printf ("MaxTime=%d ", part_ptr->max_time); + printf ("MaxNodes=%d ", part_ptr->max_nodes); + printf ("Key=%d ", part_ptr->key); + printf ("State=%d ", part_ptr->state_up); + printf ("Shared=%d ", part_ptr->shared); + printf ("Nodes=%s ", part_ptr->nodes); + printf ("AllowGroups=%s ", part_ptr->allow_groups); + printf ("total_nodes=%d ", part_ptr->total_nodes); + printf ("total_cpus=%d ", part_ptr->total_cpus); + bitmap = bitmap_print (part_ptr->node_bitmap); + printf ("node_bitmap=%s\n", bitmap); + if (bitmap) + free (bitmap); + } + if (argc < 3) + exit (0); + + cycles = atoi (argv[2]); + printf ("let's reinitialize the database %d times. run /bin/ps to get memory size.\n", cycles); + sleep (5); + for (i = 0; i < cycles; i++) { + error_code = init_slurm_conf (); + if (error_code) { + printf ("error %d from init_slurm_conf\n", + error_code); + exit (error_code); + } + + error_code = read_slurm_conf (argv[1]); + if (error_code) { + printf ("error %d from read_slurm_conf\n", + error_code); + exit (error_code); + } + } + printf ("all done. run /bin/ps again look for increase in memory size (leakage).\n"); + sleep (10); + + exit (0); +} #endif /* - * Build_BitMaps - Build node bitmaps to define which nodes are in which - * 1) Partition 2) Configuration record 3) UP state 4) IDLE state - * Also sets values of TotalNodes and TotalCPUs for every partition. - * Output: Returns 0 if no error, errno otherwise + * build_bitmaps - build node bitmaps to define which nodes are in which + * 1) partition 2) configuration record 3) up state 4) idle state + * also sets values of total_nodes and total_cpus for every partition. + * output: returns 0 if no error, errno otherwise */ -int Build_BitMaps() { - int i, j, size, Error_Code; - ListIterator Config_Record_Iterator; /* For iterating through Config_Record */ - ListIterator Part_Record_Iterator; /* For iterating through Part_Record_List */ - struct Config_Record *Config_Record_Point; /* Pointer to Config_Record */ - struct Part_Record *Part_Record_Point; /* Pointer to Part_Record */ - struct Node_Record *Node_Record_Point; /* Pointer to Node_Record */ - unsigned *AllPart_NodeBitMap; - char *Format, This_Node_Name[BUF_SIZE]; - int Start_Inx, End_Inx, Count_Inx; - char *My_Node_List, *str_ptr1, *str_ptr2; - - Error_Code = 0; - Last_Node_Update = time(NULL); - Last_Part_Update = time(NULL); - size = (Node_Record_Count + (sizeof(unsigned)*8) - 1) / - (sizeof(unsigned)*8); /* Unsigned int records in bitmap */ - size *= 8; /* Bytes in bitmap */ - - /* Initialize the Idle and Up bitmaps */ - if (Idle_NodeBitMap) free(Idle_NodeBitMap); - if (Up_NodeBitMap) free(Up_NodeBitMap); - Idle_NodeBitMap = (unsigned *)malloc(size); - Up_NodeBitMap = (unsigned *)malloc(size); - if ((Idle_NodeBitMap == NULL) || (Up_NodeBitMap == NULL)) { +int build_bitmaps () { + int i, j, size, error_code; + ListIterator config_record_iterator; /* for iterating through config_record */ + ListIterator part_record_iterator; /* for iterating through part_record_list */ + struct config_record *config_record_point; /* pointer to config_record */ + struct part_record *part_record_point; /* pointer to part_record */ + struct node_record *node_record_point; /* pointer to node_record */ + unsigned *all_part_node_bitmap; + char *format, this_node_name[BUF_SIZE]; + int start_inx, end_inx, count_inx; + char *my_node_list, *str_ptr1, *str_ptr2; + + error_code = 0; + last_node_update = time (NULL); + last_part_update = time (NULL); + size = (node_record_count + (sizeof (unsigned) * 8) - 1) / (sizeof (unsigned) * 8); + /* unsigned int records in bitmap */ + size *= 8; /* bytes in bitmap */ + + /* initialize the idle and up bitmaps */ + if (idle_node_bitmap) + free (idle_node_bitmap); + if (up_node_bitmap) + free (up_node_bitmap); + idle_node_bitmap = (unsigned *) malloc (size); + up_node_bitmap = (unsigned *) malloc (size); + if ((idle_node_bitmap == NULL) || (up_node_bitmap == NULL)) { #if DEBUG_SYSTEM - fprintf(stderr, "Build_BitMaps: unable to allocate memory\n"); + fprintf (stderr, + "build_bitmaps: unable to allocate memory\n"); #else - syslog(LOG_ALERT, "Build_BitMaps: unable to allocate memory\n"); + syslog (log_alert, + "build_bitmaps: unable to allocate memory\n"); #endif - abort(); - } /* if */ - memset(Idle_NodeBitMap, 0, size); - memset(Up_NodeBitMap, 0, size); - - /* Initialize the configuration bitmaps */ - Config_Record_Iterator = list_iterator_create(Config_List); - if (Config_Record_Iterator == NULL) { + abort (); + } + memset (idle_node_bitmap, 0, size); + memset (up_node_bitmap, 0, size); + + /* initialize the configuration bitmaps */ + config_record_iterator = list_iterator_create (config_list); + if (config_record_iterator == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "Build_BitMaps: list_iterator_create unable to allocate memory\n"); + fprintf (stderr, + "build_bitmaps: list_iterator_create unable to allocate memory\n"); #else - syslog(LOG_ALERT, "Build_BitMaps: list_iterator_create unable to allocate memory\n"); + syslog (log_alert, + "build_bitmaps: list_iterator_create unable to allocate memory\n"); #endif - abort(); - } /* if */ - while (Config_Record_Point = (struct Config_Record *)list_next(Config_Record_Iterator)) { - if (Config_Record_Point->NodeBitMap) free(Config_Record_Point->NodeBitMap); - Config_Record_Point->NodeBitMap = (unsigned *)malloc(size); - if (Config_Record_Point->NodeBitMap == NULL) { + abort (); + } + while (config_record_point = + (struct config_record *) list_next (config_record_iterator)) { + if (config_record_point->node_bitmap) + free (config_record_point->node_bitmap); + config_record_point->node_bitmap = (unsigned *) malloc (size); + if (config_record_point->node_bitmap == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "Build_BitMaps: unable to allocate memory\n"); + fprintf (stderr, + "build_bitmaps: unable to allocate memory\n"); #else - syslog(LOG_ALERT, "Build_BitMaps: unable to allocate memory\n"); + syslog (log_alert, + "build_bitmaps: unable to allocate memory\n"); #endif - abort(); - } /* if */ - memset(Config_Record_Point->NodeBitMap, 0, size); - } /* while */ - list_iterator_destroy(Config_Record_Iterator); - - /* Scan all nodes and identify which are UP and IDLE and their configuration */ - for (i=0; i<Node_Record_Count; i++) { - if (strlen(Node_Record_Table_Ptr[i].Name) == 0) continue; /* Defunct */ - if (Node_Record_Table_Ptr[i].NodeState == STATE_IDLE) BitMapSet(Idle_NodeBitMap, i); - if (Node_Record_Table_Ptr[i].NodeState != STATE_DOWN) BitMapSet(Up_NodeBitMap, i); - if (Node_Record_Table_Ptr[i].Config_Ptr) - BitMapSet(Node_Record_Table_Ptr[i].Config_Ptr->NodeBitMap, i); - } /* for */ - - /* Scan partition table and identify nodes in each */ - AllPart_NodeBitMap = (unsigned *)malloc(size); - if (AllPart_NodeBitMap == NULL) { + abort (); + } + memset (config_record_point->node_bitmap, 0, size); + } + list_iterator_destroy (config_record_iterator); + + /* scan all nodes and identify which are up and idle and their configuration */ + for (i = 0; i < node_record_count; i++) { + if (strlen (node_record_table_ptr[i].name) == 0) + continue; /* defunct */ + if (node_record_table_ptr[i].node_state == STATE_IDLE) + bitmap_set (idle_node_bitmap, i); + if (node_record_table_ptr[i].node_state > STATE_DOWN) + bitmap_set (up_node_bitmap, i); + if (node_record_table_ptr[i].config_ptr) + bitmap_set (node_record_table_ptr[i].config_ptr-> + node_bitmap, i); + } + + /* scan partition table and identify nodes in each */ + all_part_node_bitmap = (unsigned *) malloc (size); + if (all_part_node_bitmap == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "Build_BitMaps: unable to allocate memory\n"); + fprintf (stderr, + "build_bitmaps: unable to allocate memory\n"); #else - syslog(LOG_ALERT, "Build_BitMaps: unable to allocate memory\n"); + syslog (log_alert, + "build_bitmaps: unable to allocate memory\n"); #endif - abort(); - } /* if */ - memset(AllPart_NodeBitMap, 0, size); - Part_Record_Iterator = list_iterator_create(Part_List); - if (Part_Record_Iterator == NULL) { + abort (); + } + memset (all_part_node_bitmap, 0, size); + part_record_iterator = list_iterator_create (part_list); + if (part_record_iterator == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "Build_BitMaps: list_iterator_create unable to allocate memory\n"); + fprintf (stderr, + "build_bitmaps: list_iterator_create unable to allocate memory\n"); #else - syslog(LOG_ALERT, "Build_BitMaps: list_iterator_create unable to allocate memory\n"); + syslog (log_alert, + "build_bitmaps: list_iterator_create unable to allocate memory\n"); #endif - abort(); - } /* if */ - while (Part_Record_Point = (struct Part_Record *)list_next(Part_Record_Iterator)) { - if (Part_Record_Point->NodeBitMap) free(Part_Record_Point->NodeBitMap); - Part_Record_Point->NodeBitMap = (unsigned *)malloc(size); - if (Part_Record_Point->NodeBitMap == NULL) { + abort (); + } + while (part_record_point = + (struct part_record *) list_next (part_record_iterator)) { + if (part_record_point->node_bitmap) + free (part_record_point->node_bitmap); + part_record_point->node_bitmap = (unsigned *) malloc (size); + if (part_record_point->node_bitmap == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "Build_BitMaps: unable to allocate memory\n"); + fprintf (stderr, + "build_bitmaps: unable to allocate memory\n"); #else - syslog(LOG_ALERT, "Build_BitMaps: unable to allocate memory\n"); + syslog (log_alert, + "build_bitmaps: unable to allocate memory\n"); #endif - abort(); - } /* if */ - memset(Part_Record_Point->NodeBitMap, 0, size); - - /* Check for each node in the partition */ - if ((Part_Record_Point->Nodes == NULL) || - (strlen(Part_Record_Point->Nodes) == 0)) continue; - My_Node_List = (char *)malloc(strlen(Part_Record_Point->Nodes)+1); - if (My_Node_List == NULL) { + abort (); + } + memset (part_record_point->node_bitmap, 0, size); + + /* check for each node in the partition */ + if ((part_record_point->nodes == NULL) || + (strlen (part_record_point->nodes) == 0)) + continue; + my_node_list = + (char *) malloc (strlen (part_record_point->nodes) + + 1); + if (my_node_list == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "Build_BitMaps: unable to allocate memory\n"); + fprintf (stderr, + "build_bitmaps: unable to allocate memory\n"); #else - syslog(LOG_ALERT, "Build_BitMaps: unable to allocate memory\n"); + syslog (log_alert, + "build_bitmaps: unable to allocate memory\n"); #endif - abort(); - } /* if */ - strcpy(My_Node_List, Part_Record_Point->Nodes); - str_ptr2 = (char *)strtok_r(My_Node_List, ",", &str_ptr1); - while (str_ptr2) { /* Break apart by comma separators */ - Error_Code = Parse_Node_Name(str_ptr2, &Format, &Start_Inx, &End_Inx, &Count_Inx); - if (Error_Code) continue; - if (strlen(Format) >= sizeof(This_Node_Name)) { + abort (); + } + strcpy (my_node_list, part_record_point->nodes); + str_ptr2 = (char *) strtok_r (my_node_list, ",", &str_ptr1); + while (str_ptr2) { /* break apart by comma separators */ + error_code = + parse_node_name (str_ptr2, &format, + &start_inx, &end_inx, + &count_inx); + if (error_code) + continue; + if (strlen (format) >= sizeof (this_node_name)) { #if DEBUG_SYSTEM - fprintf(stderr, "Build_BitMaps: Node name specification too long: %s\n", Format); + fprintf (stderr, + "build_bitmaps: node name specification too long: %s\n", + format); #else - syslog(LOG_ERR, "Build_BitMaps: Node name specification too long: %s\n", Format); + syslog (log_err, + "build_bitmaps: node name specification too long: %s\n", + format); #endif - free(Format); - continue; - } /* if */ - for (i=Start_Inx; i<=End_Inx; i++) { - if (Count_Inx == 0) - strncpy(This_Node_Name, Format, sizeof(This_Node_Name)); - else - sprintf(This_Node_Name, Format, i); - Node_Record_Point = Find_Node_Record(This_Node_Name); - if (Node_Record_Point == NULL) { + free (format); + continue; + } + for (i = start_inx; i <= end_inx; i++) { + if (count_inx == 0) + strncpy (this_node_name, format, + sizeof (this_node_name)); + else + sprintf (this_node_name, format, i); + node_record_point = + find_node_record (this_node_name); + if (node_record_point == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "Build_BitMaps: Invalid node specified %s\n", This_Node_Name); + fprintf (stderr, + "build_bitmaps: invalid node specified %s\n", + this_node_name); #else - syslog(LOG_ERR, "Build_BitMaps: Invalid node specified %s\n", This_Node_Name); + syslog (log_err, + "build_bitmaps: invalid node specified %s\n", + this_node_name); #endif - continue; - } /* if */ - j = Node_Record_Point - Node_Record_Table_Ptr; - if (BitMapValue(AllPart_NodeBitMap, j) == 1) { + continue; + } + j = node_record_point - node_record_table_ptr; + if (bitmap_value (all_part_node_bitmap, j) == + 1) { #if DEBUG_SYSTEM - fprintf(stderr, "Build_BitMaps: Node %s defined in more than one partition\n", - This_Node_Name); - fprintf(stderr, "Build_BitMaps: Only the first partition's specification is honored\n"); + fprintf (stderr, + "build_bitmaps: node %s defined in more than one partition\n", + this_node_name); + fprintf (stderr, + "build_bitmaps: only the first partition's specification is honored\n"); #else - syslog(LOG_ERR, "Build_BitMaps: Node %s defined in more than one partition\n", - This_Node_Name); - syslog(LOG_ERR, "Build_BitMaps: Only the first partition's specification is honored\n"); + syslog (log_err, + "build_bitmaps: node %s defined in more than one partition\n", + this_node_name); + syslog (log_err, + "build_bitmaps: only the first partition's specification is honored\n"); #endif - } else { - BitMapSet(Part_Record_Point->NodeBitMap, j); - BitMapSet(AllPart_NodeBitMap, j); - Part_Record_Point->TotalNodes++; - Part_Record_Point->TotalCPUs += Node_Record_Point->CPUs; - Node_Record_Point->Partition_Ptr = Part_Record_Point; - } /* else */ - } /* for */ - free(Format); - str_ptr2 = (char *)strtok_r(NULL, ",", &str_ptr1); - } /* while (str_ptr2 */ - free(My_Node_List); - } /* while (Part_Record_Point */ - list_iterator_destroy(Part_Record_Iterator); - free(AllPart_NodeBitMap); - return Error_Code; -} /* Build_BitMaps */ + } + else { + bitmap_set (part_record_point-> + node_bitmap, j); + bitmap_set (all_part_node_bitmap, j); + part_record_point->total_nodes++; + part_record_point->total_cpus += + node_record_point->cpus; + node_record_point->partition_ptr = + part_record_point; + } /* else */ + } + free (format); + str_ptr2 = (char *) strtok_r (NULL, ",", &str_ptr1); + } /* while (str_ptr2 */ + free (my_node_list); + } /* while (part_record_point */ + list_iterator_destroy (part_record_iterator); + free (all_part_node_bitmap); + return error_code; +} /* - * Init_SLURM_Conf - Initialize or re-initialize the SLURM configuration - * values. This should be called before calling Read_SLURM_Conf. - * Output: return value - 0 if no error, otherwise an error code + * init_slurm_conf - initialize or re-initialize the slurm configuration + * values. this should be called before calling read_slurm_conf. + * output: return value - 0 if no error, otherwise an error code */ -int Init_SLURM_Conf() { - int Error_Code; - - if (ControlMachine) { - free(ControlMachine); - ControlMachine = NULL; - } - if (BackupController) { - free(BackupController); - BackupController = NULL; - } - - Error_Code = Init_Node_Conf(); - if (Error_Code) return Error_Code; +int init_slurm_conf () { + int error_code; + + if (control_machine) { + free (control_machine); + control_machine = NULL; + } + if (backup_controller) { + free (backup_controller); + backup_controller = NULL; + } + + error_code = init_node_conf (); + if (error_code) + return error_code; + + error_code = init_part_conf (); + if (error_code) + return error_code; - Error_Code = Init_Part_Conf(); - if (Error_Code) return Error_Code; - - return 0; -} /* Init_SLURM_Conf */ + return 0; +} /* - * Parse_Node_Spec - Parse the node specification, build table and set values - * Input: In_Line line from the configuration file - * Output: In_Line parsed keywords and values replaced by blanks + * parse_node_spec - parse the node specification, build table and set values + * input: in_line line from the configuration file + * output: in_line parsed keywords and values replaced by blanks * return value 0 if no error, error code otherwise */ -int Parse_Node_Spec (char *In_Line) { - char *NodeName, *State, *Feature, *Format, This_Node_Name[BUF_SIZE]; - int Start_Inx, End_Inx, Count_Inx; - int Error_Code, i; - int State_Val, CPUs_Val, RealMemory_Val, TmpDisk_Val, Weight_Val; - struct Node_Record *Node_Record_Point; - struct Config_Record *Config_Point; - char *str_ptr1, *str_ptr2; - - NodeName = State = Feature = (char *)NULL; - CPUs_Val = RealMemory_Val = State_Val = NO_VAL; - TmpDisk_Val = Weight_Val = NO_VAL; - if (Error_Code=Load_String(&NodeName, "NodeName=", In_Line)) return Error_Code; - if (NodeName == NULL) return 0; /* No Node info */ - - if (Error_Code == 0) Error_Code = Load_Integer(&CPUs_Val, "CPUs=", In_Line); - if (Error_Code == 0) Error_Code = Load_Integer(&RealMemory_Val, "RealMemory=", In_Line); - if (Error_Code == 0) Error_Code = Load_Integer(&TmpDisk_Val, "TmpDisk=", In_Line); - if (Error_Code == 0) Error_Code = Load_Integer(&Weight_Val, "Weight=", In_Line); - if (Error_Code != 0) { - free(NodeName); - return Error_Code; - } /* if */ - - if (Error_Code=Load_String (&State, "State=", In_Line)) return Error_Code; - if (State != NULL) { - for (i=0; i<=STATE_END; i++) { - if (strcmp(Node_State_String[i], "END") == 0) break; - if (strcmp(Node_State_String[i], State) == 0) { - State_Val = i; - break; - } /* if */ - } /* for */ - if (State_Val == NO_VAL) { +int parse_node_spec (char *in_line) { + char *node_name, *state, *feature, *format, this_node_name[BUF_SIZE]; + int start_inx, end_inx, count_inx; + int error_code, i; + int state_val, cpus_val, real_memory_val, tmp_disk_val, weight_val; + struct node_record *node_record_point; + struct config_record *config_point; + char *str_ptr1, *str_ptr2; + + node_name = state = feature = (char *) NULL; + cpus_val = real_memory_val = state_val = NO_VAL; + tmp_disk_val = weight_val = NO_VAL; + if (error_code = load_string (&node_name, "NodeName=", in_line)) + return error_code; + if (node_name == NULL) + return 0; /* no node info */ + + if (error_code == 0) + error_code = load_integer (&cpus_val, "CPUs=", in_line); + if (error_code == 0) + error_code = + load_integer (&real_memory_val, "RealMemory=", + in_line); + if (error_code == 0) + error_code = + load_integer (&tmp_disk_val, "TmpDisk=", in_line); + if (error_code == 0) + error_code = load_integer (&weight_val, "Weight=", in_line); + if (error_code != 0) { + free (node_name); + return error_code; + } + + if (error_code = load_string (&state, "State=", in_line)) + return error_code; + if (state != NULL) { + for (i = 0; i <= STATE_END; i++) { + if (strcmp (node_state_string[i], "END") == 0) + break; + if (strcmp (node_state_string[i], state) == 0) { + state_val = i; + break; + } + } + if (state_val == NO_VAL) { #if DEBUG_SYSTEM - fprintf(stderr, "Parse_Node_Spec: Invalid State %s for NodeName %s\n", State, NodeName); + fprintf (stderr, + "parse_node_spec: invalid state %s for node_name %s\n", + state, node_name); #else - syslog(LOG_ERR, "Parse_Node_Spec: Invalid State %s for NodeName %s\n", State, NodeName); + syslog (log_err, + "parse_node_spec: invalid state %s for node_name %s\n", + state, node_name); #endif - free(NodeName); - free(State); - return EINVAL; - } /* if */ - free(State); - } /* if */ - - Error_Code = Load_String (&Feature, "Feature=", In_Line); - if (Error_Code != 0) { - free(NodeName); - return Error_Code; - } /* if */ - - Error_Code = Parse_Node_Name(NodeName, &Format, &Start_Inx, &End_Inx, &Count_Inx); - if (Error_Code != 0) { - free(NodeName); - if (Feature) free(Feature); - return Error_Code; - } /* if */ - if (Count_Inx == 0) { /* Execute below loop once */ - Start_Inx = 0; - End_Inx = 0; - } /* if */ - - for (i=Start_Inx; i<=End_Inx; i++) { - if (Count_Inx == 0) { /* Deal with comma separated node names here */ - if (i == Start_Inx) - str_ptr2 = strtok_r(Format, ",", &str_ptr1); - else - str_ptr2 = strtok_r(NULL, ",", &str_ptr1); - if (str_ptr2 == NULL) break; - End_Inx++; - strncpy(This_Node_Name, str_ptr2, sizeof(This_Node_Name)); - } else - sprintf(This_Node_Name, Format, i); - if (strlen(This_Node_Name) >= MAX_NAME_LEN) { + free (node_name); + free (state); + return EINVAL; + } + free (state); + } + + error_code = load_string (&feature, "Feature=", in_line); + if (error_code != 0) { + free (node_name); + return error_code; + } + + error_code = + parse_node_name (node_name, &format, &start_inx, &end_inx, + &count_inx); + if (error_code != 0) { + free (node_name); + if (feature) + free (feature); + return error_code; + } + if (count_inx == 0) { /* execute below loop once */ + start_inx = 0; + end_inx = 0; + } + + for (i = start_inx; i <= end_inx; i++) { + if (count_inx == 0) { /* deal with comma separated node names here */ + if (i == start_inx) + str_ptr2 = strtok_r (format, ",", &str_ptr1); + else + str_ptr2 = strtok_r (NULL, ",", &str_ptr1); + if (str_ptr2 == NULL) + break; + end_inx++; + strncpy (this_node_name, str_ptr2, + sizeof (this_node_name)); + } + else + sprintf (this_node_name, format, i); + if (strlen (this_node_name) >= MAX_NAME_LEN) { #if DEBUG_SYSTEM - fprintf(stderr, "Parse_Node_Spec: Node name %s too long\n", This_Node_Name); + fprintf (stderr, + "parse_node_spec: node name %s too long\n", + this_node_name); #else - syslog(LOG_ERR, "Parse_Node_Spec: Node name %s too long\n", This_Node_Name); + syslog (log_err, + "parse_node_spec: node name %s too long\n", + this_node_name); #endif - if (i == Start_Inx) free(NodeName); - if (Feature) free(Feature); /* Can't use feature */ - Error_Code = EINVAL; - break; - } /* if */ - if (strcmp(NodeName, "DEFAULT") == 0) { - if (i == Start_Inx) free(NodeName); - if (CPUs_Val != NO_VAL) Default_Config_Record.CPUs = CPUs_Val; - if (RealMemory_Val != NO_VAL) Default_Config_Record.RealMemory = RealMemory_Val; - if (TmpDisk_Val != NO_VAL) Default_Config_Record.TmpDisk = TmpDisk_Val; - if (Weight_Val != NO_VAL) Default_Config_Record.Weight = Weight_Val; - if (State_Val != NO_VAL) Default_Node_Record.NodeState = State_Val; - if (Feature) { - if (Default_Config_Record.Feature) free(Default_Config_Record.Feature); - Default_Config_Record.Feature = Feature; - } /* if */ - } else { - if (i == Start_Inx) { - Config_Point = Create_Config_Record(&Error_Code); - if (Error_Code != 0) { - if (Feature) free(Feature); /* Can't use feature */ - break; - } /* if */ - Config_Point->Nodes = NodeName; - if (CPUs_Val != NO_VAL) Config_Point->CPUs = CPUs_Val; - if (RealMemory_Val != NO_VAL) Config_Point->RealMemory = RealMemory_Val; - if (TmpDisk_Val != NO_VAL) Config_Point->TmpDisk = TmpDisk_Val; - if (Weight_Val != NO_VAL) Config_Point->Weight = Weight_Val; - if (Feature) { - if (Config_Point->Feature) free(Config_Point->Feature); - Config_Point->Feature = Feature; - } /* if */ - } /* if */ - - Node_Record_Point = Find_Node_Record(This_Node_Name); - if (Node_Record_Point == NULL) { - Node_Record_Point = Create_Node_Record(&Error_Code, Config_Point, This_Node_Name); - if (Error_Code != 0) break; - if (State_Val != NO_VAL) Node_Record_Point->NodeState=State_Val; - } else { + if (i == start_inx) + free (node_name); + if (feature) + free (feature); /* can't use feature */ + error_code = EINVAL; + break; + } + if (strcmp (node_name, "DEFAULT") == 0) { + if (i == start_inx) + free (node_name); + if (cpus_val != NO_VAL) + default_config_record.cpus = cpus_val; + if (real_memory_val != NO_VAL) + default_config_record.real_memory = + real_memory_val; + if (tmp_disk_val != NO_VAL) + default_config_record.tmp_disk = tmp_disk_val; + if (weight_val != NO_VAL) + default_config_record.weight = weight_val; + if (state_val != NO_VAL) + default_node_record.node_state = state_val; + if (feature) { + if (default_config_record.feature) + free (default_config_record.feature); + default_config_record.feature = feature; + } + } + else { + if (i == start_inx) { + config_point = + create_config_record (&error_code); + if (error_code != 0) { + if (feature) + free (feature); /* can't use feature */ + break; + } + config_point->nodes = node_name; + if (cpus_val != NO_VAL) + config_point->cpus = cpus_val; + if (real_memory_val != NO_VAL) + config_point->real_memory = + real_memory_val; + if (tmp_disk_val != NO_VAL) + config_point->tmp_disk = tmp_disk_val; + if (weight_val != NO_VAL) + config_point->weight = weight_val; + if (feature) { + if (config_point->feature) + free (config_point->feature); + config_point->feature = feature; + } + } + + node_record_point = find_node_record (this_node_name); + if (node_record_point == NULL) { + node_record_point = + create_node_record (&error_code, + config_point, + this_node_name); + if (error_code != 0) + break; + if (state_val != NO_VAL) + node_record_point->node_state = + state_val; + } + else { #if DEBUG_SYSTEM - fprintf(stderr, "Parse_Node_Spec: Reconfiguration for node %s ignored.\n", - This_Node_Name); + fprintf (stderr, + "parse_node_spec: reconfiguration for node %s ignored.\n", + this_node_name); #else - syslog(LOG_ERR, "Parse_Node_Spec: Reconfiguration for node %s ignored.\n", - This_Node_Name); + syslog (log_err, + "parse_node_spec: reconfiguration for node %s ignored.\n", + this_node_name); #endif - } /* else */ - } /* else */ - } /* for (i */ + } /* else */ + } /* else */ + } /* for (i */ - /* Free allocated storage */ - if (Format) free(Format); - return Error_Code; -} /* Parse_Node_Spec */ + /* free allocated storage */ + if (format) + free (format); + return error_code; +} /* - * Parse_Part_Spec - Parse the partition specification, build table and set values - * Output: 0 if no error, error code otherwise + * parse_part_spec - parse the partition specification, build table and set values + * output: 0 if no error, error code otherwise */ -int Parse_Part_Spec (char *In_Line) { - int Line_Num; /* Line number in input file */ - char *AllowGroups, *Nodes, *PartitionName; - int MaxTime_Val, MaxNodes_Val, Key_Val, Default_Val, StateUp_Val, Shared_Val; - int Error_Code, i; - struct Part_Record *Part_Record_Point; - - AllowGroups = Nodes = PartitionName = (char *)NULL; - MaxTime_Val = MaxNodes_Val = Key_Val = Default_Val = StateUp_Val = Shared_Val = NO_VAL; - - if (Error_Code=Load_String(&PartitionName, "PartitionName=", In_Line)) return Error_Code; - if (PartitionName == NULL) return 0; /* No partition info */ - if (strlen(PartitionName) >= MAX_NAME_LEN) { +int parse_part_spec (char *in_line) { + int line_num; /* line number in input file */ + char *allow_groups, *nodes, *partition_name; + int max_time_val, max_nodes_val, key_val, default_val, state_up_val, + shared_val; + int error_code, i; + struct part_record *part_record_point; + + allow_groups = nodes = partition_name = (char *) NULL; + max_time_val = max_nodes_val = key_val = default_val = state_up_val = + shared_val = NO_VAL; + + if (error_code = + load_string (&partition_name, "PartitionName=", in_line)) + return error_code; + if (partition_name == NULL) + return 0; /* no partition info */ + if (strlen (partition_name) >= MAX_NAME_LEN) { #if DEBUG_SYSTEM - fprintf(stderr, "Parse_Part_Spec: Partition name %s too long\n", PartitionName); + fprintf (stderr, + "parse_part_spec: partition name %s too long\n", + partition_name); #else - syslog(LOG_ERR, "Parse_Part_Spec: Partition name %s too long\n", PartitionName); + syslog (log_err, + "parse_part_spec: partition name %s too long\n", + partition_name); #endif - free(PartitionName); - return EINVAL; - } /* if */ - - if (Error_Code == 0) Error_Code = Load_Integer(&MaxTime_Val, "MaxTime=", In_Line); - if (Error_Code == 0) Error_Code = Load_Integer(&MaxNodes_Val, "MaxNodes=", In_Line); - if (Error_Code == 0) Error_Code = Load_Integer(&Default_Val, "Default=NO", In_Line); - if (Default_Val == 1) Default_Val=0; - if (Error_Code == 0) Error_Code = Load_Integer(&Default_Val, "Default=YES", In_Line); - if (Error_Code == 0) Error_Code = Load_Integer(&Shared_Val, "Shared=NO", In_Line); - if (StateUp_Val == 1) Shared_Val=0; - if (Error_Code == 0) Error_Code = Load_Integer(&Shared_Val, "Shared=FORCE", In_Line); - if (StateUp_Val == 1) Shared_Val=2; - if (Error_Code == 0) Error_Code = Load_Integer(&Shared_Val, "Shared=YES", In_Line); - if (Error_Code == 0) Error_Code = Load_Integer(&StateUp_Val, "State=DOWN", In_Line); - if (StateUp_Val == 1) StateUp_Val=0; - if (Error_Code == 0) Error_Code = Load_Integer(&StateUp_Val, "State=UP", In_Line); - if (Error_Code == 0) Error_Code = Load_Integer(&Key_Val, "Key=NO", In_Line); - if (Key_Val == 1) Key_Val=0; - if (Error_Code == 0) Error_Code = Load_Integer(&Key_Val, "Key=YES", In_Line); - if (Error_Code != 0) { - free(PartitionName); - return Error_Code; - } /* if */ - - Error_Code = Load_String (&Nodes, "Nodes=", In_Line); - if (Error_Code) { - free(PartitionName); - return Error_Code; - } /* if */ - - Error_Code = Load_String (&AllowGroups, "AllowGroups=", In_Line); - if (Error_Code) { - free(PartitionName); - if (Nodes) free(Nodes); - return Error_Code; - } /* if */ - - if (strcmp(PartitionName, "DEFAULT") == 0) { - free(PartitionName); - if (MaxTime_Val != NO_VAL) Default_Part.MaxTime = MaxTime_Val; - if (MaxNodes_Val != NO_VAL) Default_Part.MaxNodes = MaxNodes_Val; - if (Key_Val != NO_VAL) Default_Part.Key = Key_Val; - if (StateUp_Val != NO_VAL) Default_Part.StateUp = StateUp_Val; - if (Shared_Val != NO_VAL) Default_Part.Shared = Shared_Val; - if (AllowGroups) { - if (Default_Part.AllowGroups) free(Default_Part.AllowGroups); - Default_Part.AllowGroups = AllowGroups; - } /* if */ - if (Nodes) { - if (Default_Part.Nodes) free(Default_Part.Nodes); - Default_Part.Nodes = Nodes; - } /* if */ - return 0; - } /* if */ - - Part_Record_Point = list_find_first(Part_List, &List_Find_Part, PartitionName); - if (Part_Record_Point == NULL) { - Part_Record_Point = Create_Part_Record(&Error_Code); - if (Error_Code) { - free(PartitionName); - if (Nodes) free(Nodes); - if (AllowGroups) free(AllowGroups); - return Error_Code; - } /* if */ - strcpy(Part_Record_Point->Name, PartitionName); - } else { + free (partition_name); + return EINVAL; + } + + if (error_code == 0) + error_code = + load_integer (&max_time_val, "MaxTime=", in_line); + if (error_code == 0) + error_code = + load_integer (&max_nodes_val, "MaxNodes=", in_line); + if (error_code == 0) + error_code = + load_integer (&default_val, "Default=NO", in_line); + if (default_val == 1) + default_val = 0; + if (error_code == 0) + error_code = + load_integer (&default_val, "Default=YES", in_line); + if (error_code == 0) + error_code = load_integer (&shared_val, "Shared=NO", in_line); + if (state_up_val == 1) + shared_val = 0; + if (error_code == 0) + error_code = + load_integer (&shared_val, "Shared=FORCE", in_line); + if (state_up_val == 1) + shared_val = 2; + if (error_code == 0) + error_code = + load_integer (&shared_val, "Shared=YES", in_line); + if (error_code == 0) + error_code = + load_integer (&state_up_val, "State=DOWN", in_line); + if (state_up_val == 1) + state_up_val = 0; + if (error_code == 0) + error_code = + load_integer (&state_up_val, "State=UP", in_line); + if (error_code == 0) + error_code = load_integer (&key_val, "Key=NO", in_line); + if (key_val == 1) + key_val = 0; + if (error_code == 0) + error_code = load_integer (&key_val, "Key=YES", in_line); + if (error_code != 0) { + free (partition_name); + return error_code; + } + + error_code = load_string (&nodes, "Nodes=", in_line); + if (error_code) { + free (partition_name); + return error_code; + } + + error_code = load_string (&allow_groups, "AllowGroups=", in_line); + if (error_code) { + free (partition_name); + if (nodes) + free (nodes); + return error_code; + } + + if (strcmp (partition_name, "DEFAULT") == 0) { + free (partition_name); + if (max_time_val != NO_VAL) + default_part.max_time = max_time_val; + if (max_nodes_val != NO_VAL) + default_part.max_nodes = max_nodes_val; + if (key_val != NO_VAL) + default_part.key = key_val; + if (state_up_val != NO_VAL) + default_part.state_up = state_up_val; + if (shared_val != NO_VAL) + default_part.shared = shared_val; + if (allow_groups) { + if (default_part.allow_groups) + free (default_part.allow_groups); + default_part.allow_groups = allow_groups; + } + if (nodes) { + if (default_part.nodes) + free (default_part.nodes); + default_part.nodes = nodes; + } + return 0; + } + + part_record_point = + list_find_first (part_list, &list_find_part, partition_name); + if (part_record_point == NULL) { + part_record_point = create_part_record (&error_code); + if (error_code) { + free (partition_name); + if (nodes) + free (nodes); + if (allow_groups) + free (allow_groups); + return error_code; + } + strcpy (part_record_point->name, partition_name); + } + else { #if DEBUG_SYSTEM - fprintf(stderr, "Parse_Part_Spec: duplicate entry for partition %s\n", PartitionName); + fprintf (stderr, + "parse_part_spec: duplicate entry for partition %s\n", + partition_name); #else - syslog(LOG_NOTICE, "Parse_Node_Spec: duplicate entry for partition %s\n", PartitionName); + syslog (log_notice, + "parse_node_spec: duplicate entry for partition %s\n", + partition_name); #endif - } /* else */ - if (Default_Val == 1) { - if (strlen(Default_Part_Name) > 0) { + } /* else */ + if (default_val == 1) { + if (strlen (default_part_name) > 0) { #if DEBUG_SYSTEM - fprintf(stderr, "Parse_Part_Spec: changing default partition from %s to %s\n", - Default_Part_Name, PartitionName); + fprintf (stderr, + "parse_part_spec: changing default partition from %s to %s\n", + default_part_name, partition_name); #else - syslog(LOG_NOTICE, "Parse_Node_Spec: changing default partition from %s to %s\n", - Default_Part_Name, PartitionName); + syslog (log_notice, + "parse_node_spec: changing default partition from %s to %s\n", + default_part_name, partition_name); #endif - } /* if */ - strcpy(Default_Part_Name, PartitionName); - Default_Part_Loc = Part_Record_Point; - } /* if */ - if (MaxTime_Val != NO_VAL) Part_Record_Point->MaxTime = MaxTime_Val; - if (MaxNodes_Val != NO_VAL) Part_Record_Point->MaxNodes = MaxNodes_Val; - if (Key_Val != NO_VAL) Part_Record_Point->Key = Key_Val; - if (StateUp_Val != NO_VAL) Part_Record_Point->StateUp = StateUp_Val; - if (Shared_Val != NO_VAL) Part_Record_Point->Shared = Shared_Val; - if (AllowGroups) { - if (Part_Record_Point->AllowGroups) free(Part_Record_Point->AllowGroups); - Part_Record_Point->AllowGroups = AllowGroups; - } /* if */ - if (Nodes) { - if (Part_Record_Point->Nodes) free(Part_Record_Point->Nodes); - Part_Record_Point->Nodes = Nodes; - } /* if */ - free(PartitionName); - return 0; -} /* Parse_Part_Spec */ + } + strcpy (default_part_name, partition_name); + default_part_loc = part_record_point; + } + if (max_time_val != NO_VAL) + part_record_point->max_time = max_time_val; + if (max_nodes_val != NO_VAL) + part_record_point->max_nodes = max_nodes_val; + if (key_val != NO_VAL) + part_record_point->key = key_val; + if (state_up_val != NO_VAL) + part_record_point->state_up = state_up_val; + if (shared_val != NO_VAL) + part_record_point->shared = shared_val; + if (allow_groups) { + if (part_record_point->allow_groups) + free (part_record_point->allow_groups); + part_record_point->allow_groups = allow_groups; + } + if (nodes) { + if (part_record_point->nodes) + free (part_record_point->nodes); + part_record_point->nodes = nodes; + } + free (partition_name); + return 0; +} /* - * Read_SLURM_Conf - Load the SLURM configuration from the specified file. - * Call Init_SLURM_Conf before ever calling Read_SLURM_Conf. - * Read_SLURM_Conf can be called more than once if so desired. - * Input: File_Name - Name of the file containing overall SLURM configuration information - * Output: return - 0 if no error, otherwise an error code + * read_slurm_conf - load the slurm configuration from the specified file. + * call init_slurm_conf before ever calling read_slurm_conf. + * read_slurm_conf can be called more than once if so desired. + * input: file_name - name of the file containing overall slurm configuration information + * output: return - 0 if no error, otherwise an error code */ -int Read_SLURM_Conf (char *File_Name) { - FILE *SLURM_Spec_File; /* Pointer to input data file */ - int Line_Num; /* Line number in input file */ - char In_Line[BUF_SIZE]; /* Input line */ - char Scratch[BUF_SIZE]; /* Scratch area for parsing the input line */ - char *str_ptr1, *str_ptr2, *str_ptr3; - int i, j, Error_Code; - - /* Initialization */ - SLURM_Spec_File = fopen(File_Name, "r"); - if (SLURM_Spec_File == NULL) { +int read_slurm_conf (char *file_name) { + FILE *slurm_spec_file; /* pointer to input data file */ + int line_num; /* line number in input file */ + char in_line[BUF_SIZE]; /* input line */ + char scratch[BUF_SIZE]; /* scratch area for parsing the input line */ + char *str_ptr1, *str_ptr2, *str_ptr3; + int i, j, error_code; + + /* initialization */ + slurm_spec_file = fopen (file_name, "r"); + if (slurm_spec_file == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "Read_SLURM_Conf error %d opening file %s\n", errno, File_Name); + fprintf (stderr, "read_slurm_conf error %d opening file %s\n", + errno, file_name); #else - syslog(LOG_ALERT, "Read_SLURM_Conf error %d opening file %s\n", errno, File_Name); + syslog (log_alert, + "read_slurm_conf error %d opening file %s\n", errno, + file_name); #endif - return errno; - } /* if */ + return errno; + } #if DEBUG_SYSTEM - fprintf(stderr, "Read_SLURM_Conf: Loading configuration from %s\n", File_Name); + fprintf (stderr, "read_slurm_conf: loading configuration from %s\n", + file_name); #else - syslog(LOG_NOTICE, "Read_SLURM_Conf: Loading configuration from %s\n", File_Name); + syslog (log_notice, + "read_slurm_conf: loading configuration from %s\n", + file_name); #endif - /* Process the data file */ - Line_Num = 0; - while (fgets(In_Line, BUF_SIZE, SLURM_Spec_File) != NULL) { - Line_Num++; - if (strlen(In_Line) >= (BUF_SIZE-1)) { + /* process the data file */ + line_num = 0; + while (fgets (in_line, BUF_SIZE, slurm_spec_file) != NULL) { + line_num++; + if (strlen (in_line) >= (BUF_SIZE - 1)) { #if DEBUG_SYSTEM - fprintf(stderr, "Read_SLURM_Conf line %d, of input file %s too long\n", - Line_Num, File_Name); + fprintf (stderr, + "read_slurm_conf line %d, of input file %s too long\n", + line_num, file_name); #else - syslog(LOG_ALERT, "Read_SLURM_Conf line %d, of input file %s too long\n", - Line_Num, File_Name); + syslog (log_alert, + "read_slurm_conf line %d, of input file %s too long\n", + line_num, file_name); #endif - fclose(SLURM_Spec_File); - return E2BIG; - break; - } /* if */ - - /* Everything after a non-escaped "#" is a comment */ - /* Replace comment flag "#" with an end of string (NULL) */ - for (i=0; i<BUF_SIZE; i++) { - if (In_Line[i] == (char)NULL) break; - if (In_Line[i] != '#') continue; - if ((i>0) && (In_Line[i-1]=='\\')) { /* escaped "#" */ - for (j=i; j<BUF_SIZE; j++) { - In_Line[j-1] = In_Line[j]; - } /* for */ - continue; - } /* if */ - In_Line[i] = (char)NULL; - break; - } /* for */ - - /* Parse what is left */ - /* Overall SLURM configuration parameters */ - if (Error_Code=Load_String(&ControlMachine, "ControlMachine=", In_Line)) { - fclose(SLURM_Spec_File); - return Error_Code; - } /* if */ - if (Error_Code=Load_String(&BackupController, "BackupController=", In_Line)) { - fclose(SLURM_Spec_File); - return Error_Code; - } /* if */ - - /* Node configuration parameters */ - if (Error_Code=Parse_Node_Spec(In_Line)) { - fclose(SLURM_Spec_File); - return Error_Code; - } /* if */ - - /* Partition configuration parameters */ - if (Error_Code=Parse_Part_Spec(In_Line)) { - fclose(SLURM_Spec_File); - return Error_Code; - } /* if */ - - /* Report any leftover strings on input line */ - Report_Leftover(In_Line, Line_Num); - } /* while */ - fclose(SLURM_Spec_File); - - /* If values not set in configuration file, set defaults */ - if (BackupController == NULL) { + fclose (slurm_spec_file); + return E2BIG; + break; + } + + /* everything after a non-escaped "#" is a comment */ + /* replace comment flag "#" with an end of string (NULL) */ + for (i = 0; i < BUF_SIZE; i++) { + if (in_line[i] == (char) NULL) + break; + if (in_line[i] != '#') + continue; + if ((i > 0) && (in_line[i - 1] == '\\')) { /* escaped "#" */ + for (j = i; j < BUF_SIZE; j++) { + in_line[j - 1] = in_line[j]; + } + continue; + } + in_line[i] = (char) NULL; + break; + } + + /* parse what is left */ + /* overall slurm configuration parameters */ + if (error_code = + load_string (&control_machine, "ControlMachine=", + in_line)) { + fclose (slurm_spec_file); + return error_code; + } + if (error_code = + load_string (&backup_controller, "BackupController=", + in_line)) { + fclose (slurm_spec_file); + return error_code; + } + + /* node configuration parameters */ + if (error_code = parse_node_spec (in_line)) { + fclose (slurm_spec_file); + return error_code; + } + + /* partition configuration parameters */ + if (error_code = parse_part_spec (in_line)) { + fclose (slurm_spec_file); + return error_code; + } + + /* report any leftover strings on input line */ + report_leftover (in_line, line_num); + } + fclose (slurm_spec_file); + + /* if values not set in configuration file, set defaults */ + if (backup_controller == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "Read_SLURM_Conf: BackupController value not specified.\n"); + fprintf (stderr, + "read_slurm_conf: backup_controller value not specified.\n"); #else - syslog(LOG_WARNING, "Read_SLURM_Conf: BackupController value not specified.\n"); + syslog (log_warning, + "read_slurm_conf: backup_controller value not specified.\n"); #endif - } /* if */ + } - if (ControlMachine == NULL) { + if (control_machine == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "Read_SLURM_Conf: ControlMachine value not specified.\n"); + fprintf (stderr, + "read_slurm_conf: control_machine value not specified.\n"); #else - syslog(LOG_ALERT, "Read_SLURM_Conf: ControlMachine value not specified.\n"); + syslog (log_alert, + "read_slurm_conf: control_machine value not specified.\n"); #endif - return EINVAL; - } /* if */ + return EINVAL; + } - if (Default_Part_Loc == NULL) { + if (default_part_loc == NULL) { #if DEBUG_SYSTEM - fprintf(stderr, "Read_SLURM_Conf: Default partition not set.\n"); + fprintf (stderr, + "read_slurm_conf: default partition not set.\n"); #else - syslog(LOG_ALERT, "Read_SLURM_Conf: Default partition not set.\n"); + syslog (log_alert, + "read_slurm_conf: default partition not set.\n"); #endif - return EINVAL; - } /* if */ - Rehash(); - if (Error_Code=Build_BitMaps()) return Error_Code; - list_sort(Config_List, &List_Compare_Config); + return EINVAL; + } + rehash (); + if (error_code = build_bitmaps ()) + return error_code; + list_sort (config_list, &list_compare_config); #if DEBUG_SYSTEM - fprintf(stderr, "Read_SLURM_Conf: Finished loading configuration\n"); + fprintf (stderr, "read_slurm_conf: finished loading configuration\n"); #else - syslog(LOG_NOTICE, "Read_SLURM_Conf: Finished loading configuration\n"); + syslog (log_notice, + "read_slurm_conf: finished loading configuration\n"); #endif - return 0; -} /* Read_SLURM_Conf */ + return 0; +}