1 /*****************************************************************************\
2  *  slurm_priority.c - Define priority plugin functions
3  *****************************************************************************
4  *  Copyright (C) 2008 Lawrence Livermore National Security.
5  *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
6  *  Written by Danny Auble <da@llnl.gov>
7  *  CODE-OCEC-09-009. All rights reserved.
8  *
9  *  This file is part of Slurm, a resource management program.
10  *  For details, see <https://slurm.schedmd.com/>.
11  *  Please also read the included file: DISCLAIMER.
12  *
13  *  Slurm is free software; you can redistribute it and/or modify it under
14  *  the terms of the GNU General Public License as published by the Free
15  *  Software Foundation; either version 2 of the License, or (at your option)
16  *  any later version.
17  *
18  *  In addition, as a special exception, the copyright holders give permission
19  *  to link the code of portions of this program with the OpenSSL library under
20  *  certain conditions as described in each individual source file, and
21  *  distribute linked combinations including the two. You must obey the GNU
22  *  General Public License in all respects for all of the code used other than
23  *  OpenSSL. If you modify file(s) with this exception, you may extend this
24  *  exception to your version of the file(s), but you are not obligated to do
25  *  so. If you do not wish to do so, delete this exception statement from your
26  *  version.  If you delete this exception statement from all source files in
27  *  the program, then also delete it here.
28  *
29  *  Slurm is distributed in the hope that it will be useful, but WITHOUT ANY
30  *  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
31  *  FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
32  *  details.
33  *
34  *  You should have received a copy of the GNU General Public License along
35  *  with Slurm; if not, write to the Free Software Foundation, Inc.,
36  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA.
37 \*****************************************************************************/
38 
39 #include "src/common/slurm_priority.h"
40 #include "src/common/plugin.h"
41 #include "src/common/plugrack.h"
42 #include "src/common/xstring.h"
43 
44 typedef struct slurm_priority_ops {
45 	uint32_t (*set)            (uint32_t last_prio,
46 				    job_record_t *job_ptr);
47 	void     (*reconfig)       (bool assoc_clear);
48 	void     (*set_assoc_usage)(slurmdb_assoc_rec_t *assoc);
49 	double   (*calc_fs_factor) (long double usage_efctv,
50 				    long double shares_norm);
51 	List	 (*get_priority_factors)
52 	(priority_factors_request_msg_t *req_msg, uid_t uid);
53 	void     (*job_end)        (job_record_t *job_ptr);
54 } slurm_priority_ops_t;
55 
56 /*
57  * Must be synchronized with slurm_priority_ops_t above.
58  */
59 static const char *syms[] = {
60 	"priority_p_set",
61 	"priority_p_reconfig",
62 	"priority_p_set_assoc_usage",
63 	"priority_p_calc_fs_factor",
64 	"priority_p_get_priority_factors_list",
65 	"priority_p_job_end",
66 };
67 
68 static slurm_priority_ops_t ops;
69 static plugin_context_t *g_priority_context = NULL;
70 static pthread_mutex_t g_priority_context_lock = PTHREAD_MUTEX_INITIALIZER;
71 static bool init_run = false;
72 
priority_sort_part_tier(void * x,void * y)73 extern int priority_sort_part_tier(void *x, void *y)
74 {
75 	part_record_t *parta = *(part_record_t **) x;
76 	part_record_t *partb = *(part_record_t **) y;
77 
78 	if (parta->priority_tier > partb->priority_tier)
79 		return -1;
80 	if (parta->priority_tier < partb->priority_tier)
81 		return 1;
82 
83 	return 0;
84 }
85 
86 /*
87  * Initialize context for priority plugin
88  */
slurm_priority_init(void)89 extern int slurm_priority_init(void)
90 {
91 	int retval = SLURM_SUCCESS;
92 	char *plugin_type = "priority";
93 	char *type = NULL;
94 
95 	if (init_run && g_priority_context)
96 		return retval;
97 
98 	slurm_mutex_lock(&g_priority_context_lock);
99 
100 	if (g_priority_context)
101 		goto done;
102 
103 	type = slurm_get_priority_type();
104 
105 	g_priority_context = plugin_context_create(
106 		plugin_type, type, (void **)&ops, syms, sizeof(syms));
107 
108 	if (!g_priority_context) {
109 		error("cannot create %s context for %s", plugin_type, type);
110 		retval = SLURM_ERROR;
111 		goto done;
112 	}
113 	init_run = true;
114 
115 done:
116 	slurm_mutex_unlock(&g_priority_context_lock);
117 	xfree(type);
118 	return retval;
119 }
120 
slurm_priority_fini(void)121 extern int slurm_priority_fini(void)
122 {
123 	int rc;
124 
125 	if (!g_priority_context)
126 		return SLURM_SUCCESS;
127 
128 	init_run = false;
129 	rc = plugin_context_destroy(g_priority_context);
130 	g_priority_context = NULL;
131 	return rc;
132 }
133 
priority_g_set(uint32_t last_prio,job_record_t * job_ptr)134 extern uint32_t priority_g_set(uint32_t last_prio, job_record_t *job_ptr)
135 {
136 	if (slurm_priority_init() < 0)
137 		return 0;
138 
139 	return (*(ops.set))(last_prio, job_ptr);
140 }
141 
priority_g_reconfig(bool assoc_clear)142 extern void priority_g_reconfig(bool assoc_clear)
143 {
144 	if (slurm_priority_init() < 0)
145 		return;
146 
147 	(*(ops.reconfig))(assoc_clear);
148 
149 	return;
150 }
151 
priority_g_set_assoc_usage(slurmdb_assoc_rec_t * assoc)152 extern void priority_g_set_assoc_usage(slurmdb_assoc_rec_t *assoc)
153 {
154 	if (slurm_priority_init() < 0)
155 		return;
156 
157 	(*(ops.set_assoc_usage))(assoc);
158 	return;
159 }
160 
priority_g_calc_fs_factor(long double usage_efctv,long double shares_norm)161 extern double priority_g_calc_fs_factor(long double usage_efctv,
162 					long double shares_norm)
163 {
164 	if (slurm_priority_init() < 0)
165 		return 0.0;
166 
167 	return (*(ops.calc_fs_factor))
168 		(usage_efctv, shares_norm);
169 }
170 
priority_g_get_priority_factors_list(priority_factors_request_msg_t * req_msg,uid_t uid)171 extern List priority_g_get_priority_factors_list(
172 	priority_factors_request_msg_t *req_msg, uid_t uid)
173 {
174 	if (slurm_priority_init() < 0)
175 		return NULL;
176 
177 	return (*(ops.get_priority_factors))(req_msg, uid);
178 }
179 
priority_g_job_end(job_record_t * job_ptr)180 extern void priority_g_job_end(job_record_t *job_ptr)
181 {
182 	if (slurm_priority_init() < 0)
183 		return;
184 
185 	(*(ops.job_end))(job_ptr);
186 }
187