PageRenderTime 53ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/src/sreport/common.c

https://github.com/cfenoy/slurm
C | 389 lines | 261 code | 56 blank | 72 comment | 98 complexity | 928e6b4fc8f43ea1cbdaec23cf1b9782 MD5 | raw file
Possible License(s): GPL-2.0, AGPL-1.0
  1. /*****************************************************************************\
  2. * common.c - common functions for generating reports
  3. * from accounting infrastructure.
  4. *****************************************************************************
  5. *
  6. * Copyright (C) 2008 Lawrence Livermore National Security.
  7. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
  8. * Written by Danny Auble <da@llnl.gov>
  9. * CODE-OCEC-09-009. All rights reserved.
  10. *
  11. * This file is part of SLURM, a resource management program.
  12. * For details, see <http://www.schedmd.com/slurmdocs/>.
  13. * Please also read the included file: DISCLAIMER.
  14. *
  15. * SLURM is free software; you can redistribute it and/or modify it under
  16. * the terms of the GNU General Public License as published by the Free
  17. * Software Foundation; either version 2 of the License, or (at your option)
  18. * any later version.
  19. *
  20. * In addition, as a special exception, the copyright holders give permission
  21. * to link the code of portions of this program with the OpenSSL library under
  22. * certain conditions as described in each individual source file, and
  23. * distribute linked combinations including the two. You must obey the GNU
  24. * General Public License in all respects for all of the code used other than
  25. * OpenSSL. If you modify file(s) with this exception, you may extend this
  26. * exception to your version of the file(s), but you are not obligated to do
  27. * so. If you do not wish to do so, delete this exception statement from your
  28. * version. If you delete this exception statement from all source files in
  29. * the program, then also delete it here.
  30. *
  31. * SLURM is distributed in the hope that it will be useful, but WITHOUT ANY
  32. * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  33. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  34. * details.
  35. *
  36. * You should have received a copy of the GNU General Public License along
  37. * with SLURM; if not, write to the Free Software Foundation, Inc.,
  38. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  39. \*****************************************************************************/
  40. #include "sreport.h"
  41. extern void slurmdb_report_print_time(print_field_t *field, uint64_t value,
  42. uint64_t total_time, int last)
  43. {
  44. int abs_len = abs(field->len);
  45. if(!total_time)
  46. total_time = 1;
  47. /* (value == unset) || (value == cleared) */
  48. if((value == NO_VAL) || (value == INFINITE)) {
  49. if(print_fields_parsable_print
  50. == PRINT_FIELDS_PARSABLE_NO_ENDING
  51. && last)
  52. ;
  53. else if(print_fields_parsable_print)
  54. printf("|");
  55. else
  56. printf("%-*s ", abs_len, " ");
  57. } else {
  58. char *output = NULL;
  59. double percent = (double)value;
  60. double temp_d = (double)value;
  61. switch(time_format) {
  62. case SLURMDB_REPORT_TIME_SECS:
  63. output = xstrdup_printf("%"PRIu64"", value);
  64. break;
  65. case SLURMDB_REPORT_TIME_MINS:
  66. temp_d /= 60;
  67. output = xstrdup_printf("%.0lf", temp_d);
  68. break;
  69. case SLURMDB_REPORT_TIME_HOURS:
  70. temp_d /= 3600;
  71. output = xstrdup_printf("%.0lf", temp_d);
  72. break;
  73. case SLURMDB_REPORT_TIME_PERCENT:
  74. percent /= total_time;
  75. percent *= 100;
  76. output = xstrdup_printf("%.2lf%%", percent);
  77. break;
  78. case SLURMDB_REPORT_TIME_SECS_PER:
  79. percent /= total_time;
  80. percent *= 100;
  81. output = xstrdup_printf("%"PRIu64"(%.2lf%%)",
  82. value, percent);
  83. break;
  84. case SLURMDB_REPORT_TIME_MINS_PER:
  85. percent /= total_time;
  86. percent *= 100;
  87. temp_d /= 60;
  88. output = xstrdup_printf("%.0lf(%.2lf%%)",
  89. temp_d, percent);
  90. break;
  91. case SLURMDB_REPORT_TIME_HOURS_PER:
  92. percent /= total_time;
  93. percent *= 100;
  94. temp_d /= 3600;
  95. output = xstrdup_printf("%.0lf(%.2lf%%)",
  96. temp_d, percent);
  97. break;
  98. default:
  99. temp_d /= 60;
  100. output = xstrdup_printf("%.0lf", temp_d);
  101. break;
  102. }
  103. if(print_fields_parsable_print
  104. == PRINT_FIELDS_PARSABLE_NO_ENDING
  105. && last)
  106. printf("%s", output);
  107. else if(print_fields_parsable_print)
  108. printf("%s|", output);
  109. else if(field->len == abs_len)
  110. printf("%*.*s ", abs_len, abs_len, output);
  111. else
  112. printf("%-*.*s ", abs_len, abs_len, output);
  113. xfree(output);
  114. }
  115. }
  116. extern int parse_option_end(char *option)
  117. {
  118. int end = 0;
  119. if(!option)
  120. return 0;
  121. while(option[end] && option[end] != '=')
  122. end++;
  123. if(!option[end])
  124. return 0;
  125. end++;
  126. return end;
  127. }
  128. /* you need to xfree whatever is sent from here */
  129. extern char *strip_quotes(char *option, int *increased)
  130. {
  131. int end = 0;
  132. int i=0, start=0;
  133. char *meat = NULL;
  134. if(!option)
  135. return NULL;
  136. /* first strip off the ("|')'s */
  137. if (option[i] == '\"' || option[i] == '\'')
  138. i++;
  139. start = i;
  140. while(option[i]) {
  141. if(option[i] == '\"' || option[i] == '\'') {
  142. end++;
  143. break;
  144. }
  145. i++;
  146. }
  147. end += i;
  148. meat = xmalloc((i-start)+1);
  149. memcpy(meat, option+start, (i-start));
  150. if(increased)
  151. (*increased) += end;
  152. return meat;
  153. }
  154. extern void addto_char_list(List char_list, char *names)
  155. {
  156. int i=0, start=0;
  157. char *name = NULL, *tmp_char = NULL;
  158. ListIterator itr = NULL;
  159. if(!char_list) {
  160. error("No list was given to fill in");
  161. return;
  162. }
  163. itr = list_iterator_create(char_list);
  164. if(names) {
  165. if (names[i] == '\"' || names[i] == '\'')
  166. i++;
  167. start = i;
  168. while(names[i]) {
  169. if(names[i] == '\"' || names[i] == '\'')
  170. break;
  171. else if(names[i] == ',') {
  172. if((i-start) > 0) {
  173. name = xmalloc((i-start+1));
  174. memcpy(name, names+start, (i-start));
  175. while((tmp_char = list_next(itr))) {
  176. if(!strcasecmp(tmp_char, name))
  177. break;
  178. }
  179. if(!tmp_char)
  180. list_append(char_list, name);
  181. else
  182. xfree(name);
  183. list_iterator_reset(itr);
  184. }
  185. i++;
  186. start = i;
  187. }
  188. i++;
  189. }
  190. if((i-start) > 0) {
  191. name = xmalloc((i-start)+1);
  192. memcpy(name, names+start, (i-start));
  193. while((tmp_char = list_next(itr))) {
  194. if(!strcasecmp(tmp_char, name))
  195. break;
  196. }
  197. if(!tmp_char)
  198. list_append(char_list, name);
  199. else
  200. xfree(name);
  201. }
  202. }
  203. list_iterator_destroy(itr);
  204. }
  205. /*
  206. * Comparator used for sorting users largest cpu to smallest cpu
  207. *
  208. * returns: 1: user_a > user_b 0: user_a == user_b -1: user_a < user_b
  209. *
  210. */
  211. extern int sort_user_dec(slurmdb_report_user_rec_t *user_a,
  212. slurmdb_report_user_rec_t *user_b)
  213. {
  214. int diff = 0;
  215. if(sort_flag == SLURMDB_REPORT_SORT_TIME) {
  216. if (user_a->cpu_secs > user_b->cpu_secs)
  217. return -1;
  218. else if (user_a->cpu_secs < user_b->cpu_secs)
  219. return 1;
  220. }
  221. if(!user_a->name || !user_b->name)
  222. return 0;
  223. diff = strcmp(user_a->name, user_b->name);
  224. if (diff > 0)
  225. return 1;
  226. else if (diff < 0)
  227. return -1;
  228. return 0;
  229. }
  230. /*
  231. * Comparator used for sorting clusters alphabetically
  232. *
  233. * returns: 1: cluster_a > cluster_b
  234. * 0: cluster_a == cluster_b
  235. * -1: cluster_a < cluster_b
  236. *
  237. */
  238. extern int sort_cluster_dec(slurmdb_report_cluster_rec_t *cluster_a,
  239. slurmdb_report_cluster_rec_t *cluster_b)
  240. {
  241. int diff = 0;
  242. if(!cluster_a->name || !cluster_b->name)
  243. return 0;
  244. diff = strcmp(cluster_a->name, cluster_b->name);
  245. if (diff > 0)
  246. return 1;
  247. else if (diff < 0)
  248. return -1;
  249. return 0;
  250. }
  251. /*
  252. * Comparator used for sorting assocs alphabetically by acct and then
  253. * by user. The association with a total count of time is at the top
  254. * of the accts.
  255. *
  256. * returns: -1: assoc_a > assoc_b
  257. * 0: assoc_a == assoc_b
  258. * 1: assoc_a < assoc_b
  259. *
  260. */
  261. extern int sort_assoc_dec(slurmdb_report_assoc_rec_t *assoc_a,
  262. slurmdb_report_assoc_rec_t *assoc_b)
  263. {
  264. int diff = 0;
  265. if(!assoc_a->acct || !assoc_b->acct)
  266. return 0;
  267. diff = strcmp(assoc_a->acct, assoc_b->acct);
  268. if (diff > 0)
  269. return 1;
  270. else if (diff < 0)
  271. return -1;
  272. if(!assoc_a->user && assoc_b->user)
  273. return 1;
  274. else if(!assoc_b->user)
  275. return -1;
  276. diff = strcmp(assoc_a->user, assoc_b->user);
  277. if (diff > 0)
  278. return 1;
  279. else if (diff < 0)
  280. return -1;
  281. return 0;
  282. }
  283. /*
  284. * Comparator used for sorting resvs largest cpu to smallest cpu
  285. *
  286. * returns: 1: resv_a > resv_b 0: resv_a == resv_b -1: resv_a < resv_b
  287. *
  288. */
  289. extern int sort_reservations_dec(slurmdb_reservation_rec_t *resv_a,
  290. slurmdb_reservation_rec_t *resv_b)
  291. {
  292. int diff = 0;
  293. if(!resv_a->cluster || !resv_b->cluster)
  294. return 0;
  295. diff = strcmp(resv_a->cluster, resv_b->cluster);
  296. if (diff > 0)
  297. return 1;
  298. else if (diff < 0)
  299. return -1;
  300. if(!resv_a->name || !resv_b->name)
  301. return 0;
  302. diff = strcmp(resv_a->name, resv_b->name);
  303. if (diff > 0)
  304. return 1;
  305. else if (diff < 0)
  306. return -1;
  307. if(resv_a->time_start < resv_b->time_start)
  308. return 1;
  309. else if(resv_a->time_start > resv_b->time_start)
  310. return -1;
  311. return 0;
  312. }
  313. extern int get_uint(char *in_value, uint32_t *out_value, char *type)
  314. {
  315. char *ptr = NULL, *meat = NULL;
  316. long num;
  317. if(!(meat = strip_quotes(in_value, NULL))) {
  318. error("Problem with strip_quotes");
  319. return SLURM_ERROR;
  320. }
  321. num = strtol(meat, &ptr, 10);
  322. if ((num == 0) && ptr && ptr[0]) {
  323. error("Invalid value for %s (%s)", type, meat);
  324. xfree(meat);
  325. return SLURM_ERROR;
  326. }
  327. xfree(meat);
  328. if (num < 0)
  329. *out_value = INFINITE; /* flag to clear */
  330. else
  331. *out_value = (uint32_t) num;
  332. return SLURM_SUCCESS;
  333. }