1 /*****************************************************************************\ 2 * layouts_mgr.h - layouts manager data structures and main functions 3 ***************************************************************************** 4 * Initially written by Francois Chevallier <chevallierfrancois@free.fr> 5 * at Bull for slurm-2.6. 6 * Adapted by Matthieu Hautreux <matthieu.hautreux@cea.fr> for slurm-14.11. 7 * Enhanced by Matthieu Hautreux <matthieu.hautreux@cea.fr> for slurm-15.x. 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 #ifndef __LAYOUTS_MGR_1NRINRSD__INC__ 40 #define __LAYOUTS_MGR_1NRINRSD__INC__ 41 42 #include "src/common/list.h" 43 #include "src/common/xhash.h" 44 #include "src/common/xtree.h" 45 #include "src/common/pack.h" 46 #include "src/common/parse_config.h" 47 48 #include "src/common/layout.h" 49 #include "src/common/entity.h" 50 51 /* 52 * Layouts are managed through a "layouts manager" of type layouts_mgr_t. 53 * 54 * The layouts_mgr_t manages the layouts and entities loaded through the list 55 * of layouts specified in the Slurm configuration file (slurm.conf) 56 * 57 * At startup, Slurm initialize one layouts_mgr_t using layouts_init() 58 * and then load the required layouts defined in the configuration using 59 * layouts_load_config(). 60 * 61 * The different layouts and entities can then be queried using either 62 * layouts_get_layout() and layouts_get_entity(). 63 * 64 * Note that each entity contains a list of nodes appearing inside the 65 * associated layouts. 66 */ 67 68 /* 69 * Potential enhancement to complete: agregate specified plugin etypes in a 70 * xhash in the mgr, avoiding same string to be duplicated again and again. 71 * (in short: apply the same logic for etypes as for entity data keys.) 72 */ 73 74 typedef enum layouts_keydef_types_en { 75 L_T_ERROR = 0, 76 L_T_STRING, 77 L_T_LONG, 78 L_T_UINT16, 79 L_T_UINT32, 80 L_T_BOOLEAN, 81 L_T_FLOAT, 82 L_T_DOUBLE, 83 L_T_LONG_DOUBLE, 84 L_T_CUSTOM, 85 } layouts_keydef_types_t; 86 87 /* keyspec flags */ 88 #define KEYSPEC_RDONLY 0x00000001 89 90 #define KEYSPEC_UPDATE_CHILDREN_SUM 0x00010000 91 #define KEYSPEC_UPDATE_CHILDREN_AVG 0x00020000 92 #define KEYSPEC_UPDATE_CHILDREN_MIN 0x00040000 93 #define KEYSPEC_UPDATE_CHILDREN_MAX 0x00080000 94 #define KEYSPEC_UPDATE_CHILDREN_COUNT 0x00110000 95 #define KEYSPEC_UPDATE_CHILDREN_MASK 0x00FF0000 96 97 #define KEYSPEC_UPDATE_PARENTS_SUM 0x01000000 98 #define KEYSPEC_UPDATE_PARENTS_AVG 0x02000000 99 #define KEYSPEC_UPDATE_PARENTS_MIN 0x04000000 100 #define KEYSPEC_UPDATE_PARENTS_MAX 0x08000000 101 #define KEYSPEC_UPDATE_PARENTS_FSHARE 0x11000000 102 #define KEYSPEC_UPDATE_PARENTS_MASK 0xFF000000 103 104 typedef struct layouts_keyspec_st { 105 char* key; 106 layouts_keydef_types_t type; 107 uint32_t flags; 108 char* ref_key; /* reference key to use for update 109 * NULL means use the same key in my 110 * neighborhood */ 111 void (*custom_destroy)(void*); 112 char* (*custom_dump)(void*); 113 } layouts_keyspec_t; 114 115 typedef struct layouts_plugin_spec_st { 116 const s_p_options_t* options; 117 const layouts_keyspec_t* keyspec; 118 int struct_type; 119 const char** etypes; 120 bool automerge; 121 bool autoupdate; 122 } layouts_plugin_spec_t; 123 124 /*****************************************************************************\ 125 * PLUGIN FUNCTIONS * 126 \*****************************************************************************/ 127 128 /* 129 * layouts_init - intialize the layouts mgr, load the required plugins 130 * and initialize the internal hash tables for entities, keydefs and 131 * layouts. 132 * 133 * Return SLURM_SUCCESS or SLURM_ERROR if all the required layouts were not 134 * loaded correctly. 135 * 136 * Notes: this call do not try to read and parse the layouts configuration 137 * files. It only loads the layouts plugins, dlsym the layout API and conf 138 * elements to prepare the reading and parsing performed in the adhoc call 139 * layouts_load_config() 140 * 141 */ 142 int layouts_init(void); 143 144 /* 145 * layouts_fini - uninitialize the layouts mgr and free the internal 146 * hash tables. 147 */ 148 int layouts_fini(void); 149 150 /* 151 * layouts_load_config - use the layouts plugins details loaded during 152 * layouts_init() and read+parse the different layouts 153 * configuration files, creating the entities and the relational 154 * structures associated the eaf of them. 155 * 156 * IN recover - update entities information with the latest available 157 * information depending upon value 158 * 0 = use no saved state information, rebuild everything from 159 * layouts conf files contents 160 * 1 = recover saved entities information 161 * 2 = recover saved entities information 162 * 163 * Return SLURM_SUCCESS or SLURM_ERROR if all the required layouts were not 164 * loaded correctly. 165 */ 166 int layouts_load_config(int recover); 167 168 /* 169 * layouts_get_layout - return the layout from a given type 170 * 171 * Return a pointer to the layout_t struct of the layout or NULL if not found 172 */ 173 layout_t* layouts_get_layout(const char* type); 174 175 /* 176 * layouts_get_entity - return the entity from a given name 177 * 178 * Return a pointer to the entity_t struct of the entity or NULL if not found 179 */ 180 entity_t* layouts_get_entity(const char* name); 181 182 /* 183 * layouts_pack_layout - pack the layout of the target type into the provided 184 * buffer. 185 * 186 * The buffer will be appended with multiple strings representing an expanded 187 * form of its configuration element, terminated by a "\0" string. 188 * 189 * Return SLURM_SUCCES or SLURM_ERROR in case of failure 190 */ 191 int layouts_pack_layout(char *l_type, char *entities, char *type, 192 uint32_t flags, Buf buffer); 193 194 /* 195 * layouts_update_layout - update a particular layout loading the information 196 * provided in the input buffer. 197 * 198 * The buffer must contain multiple strings corresponding to the different 199 * configuration lines similar to those that can be put in a configuration 200 * file that will be parsed and integrated. 201 * 202 * Note that the entities key/value entries will be updated only. 203 * 204 * Return SLURM_SUCCES or SLURM_ERROR in case of failure 205 */ 206 int layouts_update_layout(char *l_type, Buf buffer); 207 208 /* 209 * layouts_state_save_layout - save the state of a particular layout 210 * in the adhoc file in slurm state save location. 211 * 212 * The file produced will be an ASCII file created from the configuration 213 * strings packed using layouts_pack_layout(). Thus it will be the expanded 214 * form of the current configuration of the layout that could be used as 215 * a perfect updated replacement of the layout configuration file. 216 * 217 * Return SLURM_SUCCES or SLURM_ERROR in case of failure 218 */ 219 int layouts_state_save_layout(char* l_type); 220 221 /* 222 * layouts_state_save - save the state of all the loaded layouts iterating 223 * over each one of them and applying layouts_state_save_layout(). 224 * 225 * Return SLURM_SUCCES or SLURM_ERROR in case of failure 226 */ 227 int layouts_state_save(void); 228 229 /* 230 * layouts_entity_get_kv_type - get the type of the value associated with a key 231 * of an entity in a particular layout. 232 * 233 * The returned type is a member of the layouts_keydef_types_t enum : 234 * L_T_ERROR, L_T_STRING, L_T_LONG, L_T_UINT16, ... 235 * 236 * Return the requested type or SLURM_ERROR in case of failure 237 */ 238 int layouts_entity_get_kv_type(char* layout, char* entity, 239 char* key); 240 241 /* 242 * layouts_entity_get_kv_flags - get the keyspec flags associated with the 243 * targeted key/value pair of an entity in a particular layout. 244 * 245 * Return the associated flags or SLURM_ERROR in case of failure 246 */ 247 int layouts_entity_get_kv_flags(char* layout, char* entity, 248 char* key); 249 250 /* 251 * layouts_entity_push_kv - update the layout internal states to take into 252 * account the current state of the targeted key/value pair. 253 * 254 * This ensures that the child and/or parents of the targeted entity in the 255 * targeted layout are synchronized with the current value associated with 256 * the key. 257 * 258 * Note: this call only makes sense when the targeted k/v is a k/v that helps 259 * to dynamically compute its parents and/or children. It is a 260 * no-op otherwise that just returns SLURM_SUCCESS. 261 * 262 * Return SLURM_SUCCES or SLURM_ERROR in case of failure 263 */ 264 int layouts_entity_push_kv(char* layout, char* entity, 265 char* key); 266 267 /* 268 * layouts_entity_pull_kv - synchronize the targeted key/value pair based on 269 * the states of their neighborhood in the targeted layout. 270 * 271 * This ensures that the K/V is up-to-date and correspond to the values that 272 * its neighborhood in the layout think it should have. 273 * 274 * Note: this call only makes sense when the targeted k/v is a k/v that is 275 * dynamically computed based on its parents and/or children. It is a 276 * no-op otherwise that just returns SLURM_SUCCESS. 277 * 278 * Return SLURM_SUCCES or SLURM_ERROR in case of failure 279 */ 280 int layouts_entity_pull_kv(char* layout, char* entity, 281 char* key); 282 283 /* 284 * layouts_entity_set_kv - update an entity with a new value for a particular 285 * key in the targeted layout. 286 * 287 * The input key_type will force the call to check types consistency between 288 * the requester and the underlying keyspec associated with the key. To skip 289 * that check the caller will have to pass a 0 value. 290 * 291 * Note : in case the key/value is already set for the entity, the content of 292 * the provided buffer will override the current content. In case the key/value 293 * already exists, it will be xfree and a new memory allocation will be 294 * performed and the content of the provided buffer dumped into it. 295 * 296 * Return SLURM_SUCCES or SLURM_ERROR in case of failure 297 */ 298 int layouts_entity_set_kv(char* layout, char* entity, 299 char* key, void* value, 300 layouts_keydef_types_t key_type); 301 302 /* 303 * layouts_entity_set_kv_ref - replace an entity key value with a new memory 304 * area for a particular key in the targeted layout 305 * 306 * The input key_type will force the call to check types consistency between 307 * the requester and the underlying keyspec associated with the key. To skip 308 * that check the caller will have to pass a 0 value. 309 * 310 * Note : in case the key/value is already set for the entity, the older value 311 * will be free and the provided buffer will be associated to the new value. 312 * Once done, the caller must not free the provided buffer has it will then 313 * be owned by the layout logic and will be free automatically when the layout 314 * framework will be unloaded or at a next call to that function. 315 * 316 * Return SLURM_SUCCES or SLURM_ERROR in case of failure 317 */ 318 int layouts_entity_set_kv_ref(char* layout, char* entity, 319 char* key, void* value, 320 layouts_keydef_types_t key_type); 321 322 /* 323 * layouts_entity_setpush_kv - combination of layouts_entity_set_kv and 324 * layouts_entity_push_kv to update an entity with a new value and force 325 * the synchronization of its neighborhood in the layout. 326 * 327 * The input key_type will force the call to check types consistency between 328 * the requester and the underlying keyspec associated with the key. To skip 329 * that check the caller will have to pass a 0 value. 330 * 331 * Note: see layouts_entity_push_kv. 332 * 333 * Return SLURM_SUCCES or SLURM_ERROR in case of failure 334 */ 335 int layouts_entity_setpush_kv(char* layout, char* entity, 336 char* key, void* value, 337 layouts_keydef_types_t key_type); 338 339 /* 340 * layouts_entity_setpush_kv - combination of layouts_entity_set_kv_ref and 341 * layouts_entity_push_kv to replace an entity key value with a new 342 * memory area and force the synchronization of its neighborhood in 343 * the layout. 344 * 345 * The input key_type will force the call to check types consistency between 346 * the requester and the underlying keyspec associated with the key. To skip 347 * that check the caller will have to pass a 0 value. 348 * 349 * Note: see layouts_entity_push_kv. 350 * 351 * Return SLURM_SUCCES or SLURM_ERROR in case of failure 352 */ 353 int layouts_entity_setpush_kv_ref(char* layout, char* entity, 354 char* key, void* value, 355 layouts_keydef_types_t key_type); 356 357 /* 358 * layouts_entity_get_kv - get the value associated with a key of an entity 359 * in a particular layout. 360 * 361 * The input key_type will force the call to check types consistency between 362 * the requester and the underlying keyspec associated with the key. To skip 363 * that check the caller will have to pass a 0 value. 364 * 365 * Note : the destination buffer will be filled with the content of the 366 * value associated with the requested key in the entity except for these 367 * types for which : 368 * L_T_STRING : value must be the address of the char* that will be 369 * xstrduped with the key value. The char* will have to be 370 * xfree() after that. 371 * L_T_CUSTOM : value must be the address of the char* that will result 372 * of the custom_dump function. The char* will have to be 373 * xfree() after that. 374 * L_T_ERROR : will return SLURM_ERROR in all cases. 375 * 376 * Return SLURM_SUCCES or SLURM_ERROR in case of failure 377 */ 378 int layouts_entity_get_kv(char* layout, char* entity, 379 char* key, void* value, 380 layouts_keydef_types_t key_type); 381 382 /* 383 * layouts_entity_get_kv_ref - get a pointer to the value associated with a key 384 * of an entity in a particular layout. 385 * 386 * The input key_type will force the call to check types consistency between 387 * the requester and the underlying keyspec associated with the key. To skip 388 * that check the caller will have to pass a 0 value. 389 * 390 * Note : this call must be used with caution as the pointer could be free 391 * sooner or later by the underlying layout engine in reply to the execution 392 * of the layouts_entity_set_kv_ref(). 393 * 394 * Return SLURM_SUCCES or SLURM_ERROR in case of failure 395 */ 396 int layouts_entity_get_kv_ref(char* layout, char* entity, 397 char* key, void** pvalue, 398 layouts_keydef_types_t key_type); 399 400 /* 401 * layouts_entity_pullget_kv - combination of layouts_entity_pull_kv and 402 * layouts_entity_get_kv to retrieve the up-to-date value of a particular 403 * entity key in the targeted layout. 404 * 405 * The input key_type will force the call to check types consistency between 406 * the requester and the underlying keyspec associated with the key. To skip 407 * that check the caller will have to pass a 0 value. 408 * 409 * Note: see layouts_entity_pull_kv. 410 * 411 * Return SLURM_SUCCES or SLURM_ERROR in case of failure 412 */ 413 int layouts_entity_pullget_kv(char* layout, char* entity, 414 char* key, void* value, 415 layouts_keydef_types_t key_type); 416 417 /* 418 * layouts_entity_pullget_kv - combination of layouts_entity_pull_kv_ref and 419 * layouts_entity_get_kv to retrieve a reference to the up-to-date value 420 * of a particular entity key in the targeted layout. 421 * 422 * The input key_type will force the call to check types consistency between 423 * the requester and the underlying keyspec associated with the key. To skip 424 * that check the caller will have to pass a 0 value. 425 * 426 * Note: see layouts_entity_pull_kv_ref. 427 * 428 * Return SLURM_SUCCES or SLURM_ERROR in case of failure 429 */ 430 int layouts_entity_pullget_kv_ref(char* layout, char* entity, 431 char* key, void** value, 432 layouts_keydef_types_t key_type); 433 434 /* 435 * layouts_entity_get_mkv - get the values associated with a set of keys of an 436 * entity in a particular layout. 437 * 438 * The input key_type will force the call to check types consistency between 439 * the requester and the underlying keyspec associated with the key. To skip 440 * that check the caller will have to pass a 0 value. This is mandatory for 441 * cases where the keyspecs of the requested keys do not share the same type. 442 * 443 * Note : the destination buffer will be sequentially filled with the content of 444 * the values associated with the requested keys in the entity. 445 * If the length of the buffer is too small, the remaining references will not 446 * be added and the counter of missed keys incremented as necessary. 447 * The first encountered error terminates the logic and the missing elements 448 * counter will reflect all the unprocessed elements including the faulty one. 449 450 * Special care must be taken for the following types of key : 451 * L_T_STRING : a char* will be added to the buffer. It will be xstrduped 452 * with the associated key value. The char* will have to be 453 * xfree() after that. 454 * L_T_CUSTOM : a char* will be added to the buffer. It will be xstrduped 455 * with the result of the custom_dump function. It will have to 456 * be xfree() after that. 457 * L_T_ERROR : will generate an error that will force the function to return 458 * the count of missing elements (at least 1, depending on where 459 * this type first appeared in the ordered list of keys to get. 460 * 461 * Note: keys correspond to a list of keys that can be represented as 462 * an hostlist expression (i.e. keys[1-10]). 463 * 464 * Return SLURM_SUCCES or the count of missed keys/references 465 */ 466 int layouts_entity_get_mkv(char* layout, char* entity, 467 char* keys, void* value, size_t length, 468 layouts_keydef_types_t key_type); 469 470 /* 471 * layouts_entity_get_mkv_ref - get a set of pointers to the values associated 472 * with a set of keys of an entity in a particular layout. 473 * 474 * The input key_type will force the call to check types consistency between 475 * the requester and the underlying keyspecs associated with the keys. To skip 476 * that check the caller will have to pass a 0 value. This is mandatory for cases 477 * where the keyspecs of the requested keys do not share the same type. 478 * 479 * The output buffer will be filled with the different references. 480 * If the length of the buffer is too small, the remaining references will not 481 * be added and the counter of missed keys incremented as necessary. 482 * The first encountered error terminates the logic and the missing elements 483 * counter will reflect all the unprocessed elements including the faulty one. 484 * 485 * Note: this call must be used with caution as the pointers could be free 486 * sooner or later by the underlying layout engine in reply to the execution 487 * of the layouts_entity_set_kv_ref(). 488 * 489 * Note: keys correspond to a list of keys that can be represented as 490 * an hostlist expression (i.e. keys[1-10]). 491 * 492 * Return SLURM_SUCCES or the count of missed keys/references 493 */ 494 int layouts_entity_get_mkv_ref(char* layout, char* entity, 495 char* keys, void* buffer, size_t length, 496 layouts_keydef_types_t key_type); 497 498 #endif /* end of include guard: __LAYOUTS_MGR_1NRINRSD__INC__ */ 499