diff --git a/contribs/lua/job_submit.lua b/contribs/lua/job_submit.lua index 939e0464d5d509f614dd376ba71f4ac9057acb1a..1e70fbd320d9f27d97c5a020c678c7e38b7739c2 100644 --- a/contribs/lua/job_submit.lua +++ b/contribs/lua/job_submit.lua @@ -34,12 +34,19 @@ function slurm_job_submit ( job_desc_addr, part_list ) job_desc.user_id, account) job_desc.account = account end +-- If no default partition, the set the partition to the highest +-- priority partition this user has access to if job_desc.partition == nil then local new_partition = nil - local top_priority = -1 + local top_priority = -1 local last_priority = -1 i = 1 while part_rec[i] do +-- log_info("part name[%d]:%s", i, part_rec[i].name) + if part_rec[i].flag_default ~= 0 then + top_priority = -1 + break + end last_priority = part_rec[i].priority if last_priority > top_priority then top_priority = last_priority diff --git a/doc/html/job_submit_plugins.shtml b/doc/html/job_submit_plugins.shtml index fb742e1ce48089077eed11afd9495a862f2d2e6a..6d924cf7d4c710088d33b0e31f6062cc6f8306b2 100644 --- a/doc/html/job_submit_plugins.shtml +++ b/doc/html/job_submit_plugins.shtml @@ -37,7 +37,7 @@ submission parameters and available partitions. implemented must be stubbed. <p class="commandline"> -int job_submit(struct job_descriptor *job_desc) +int job_submit(struct job_descriptor *job_desc, uint32_t submit_uid) <p style="margin-left:.2in"><b>Description</b>:<br> This function is called by the slurmctld daemon with job submission parameters supplied by the salloc, sbatch or srun command. It can be used to log and/or @@ -47,12 +47,15 @@ to examine the available partitions, reservations, etc. <p style="margin-left:.2in"><b>Arguments</b>: <br> <span class="commandline">job_desc</span> (input/output) the job allocation request specifications.<br> +<span class="commandline">submit_uid</span> +(input) user ID initiating the request.<br> <p style="margin-left:.2in"><b>Returns</b>: <br> <span class="commandline">SLURM_SUCCESS</span> on success, or<br> <span class="commandline">SLURM_ERROR</span> on failure. <p class="commandline"> -int job_modify(struct job_descriptor *job_desc, struct job_record *job_ptr) +int job_modify(struct job_descriptor *job_desc, struct job_record *job_ptr, +uint32_t submit_uid) <p style="margin-left:.2in"><b>Description</b>:<br> This function is called by the slurmctld daemon with job modification parameters supplied by the scontrol or sview command. It can be used to log and/or @@ -65,6 +68,8 @@ examine the available partitions, reservations, etc. <span class="commandline">job_ptr</span> (input/output) slurmctld daemon's current data structure for the job to be modified.<br> +<span class="commandline">submit_uid</span> +(input) user ID initiating the request.<br> <p style="margin-left:.2in"><b>Returns</b>: <br> <span class="commandline">SLURM_SUCCESS</span> on success, or<br> <span class="commandline">SLURM_ERROR</span> on failure. @@ -74,6 +79,6 @@ be modified.<br> releases of SLURM may revise this API. <p class="footer"><a href="#top">top</a> -<p style="text-align:center;">Last modified 13 April 2010</p> +<p style="text-align:center;">Last modified 9 September 2010</p> <!--#include virtual="footer.txt"--> diff --git a/src/plugins/job_submit/defaults/job_submit_defaults.c b/src/plugins/job_submit/defaults/job_submit_defaults.c index 98dbbc913db63bc5ac3971eccc3d6ffbf2ba0b15..f413664315869c9b660aa0068740bcd543bddab1 100644 --- a/src/plugins/job_submit/defaults/job_submit_defaults.c +++ b/src/plugins/job_submit/defaults/job_submit_defaults.c @@ -110,7 +110,7 @@ const uint32_t min_plug_version = 100; * of less than 30 seconds in order to insure more precise accounting. * Also remove any QOS value set by the user in order to use the default value * from the database. */ -extern int job_submit(struct job_descriptor *job_desc) +extern int job_submit(struct job_descriptor *job_desc, uint32_t submit_uid) { if (job_desc->acctg_freq < MIN_ACCTG_FREQUENCY) { info("Changing accounting frequency of submitted job " @@ -132,7 +132,7 @@ extern int job_submit(struct job_descriptor *job_desc) * Also remove any QOS value set by the user in order to use the default value * from the database. */ extern int job_modify(struct job_descriptor *job_desc, - struct job_record *job_ptr) + struct job_record *job_ptr, uint32_t submit_uid) { if (job_desc->acctg_freq < MIN_ACCTG_FREQUENCY) { info("Changing accounting frequency of modify job %u " diff --git a/src/plugins/job_submit/logging/job_submit_logging.c b/src/plugins/job_submit/logging/job_submit_logging.c index 4366ef90f355caf1f5e797ed7443353fe1fb1477..4a441ffe9eea8a2e2e965a387f8d7c32599ff629 100644 --- a/src/plugins/job_submit/logging/job_submit_logging.c +++ b/src/plugins/job_submit/logging/job_submit_logging.c @@ -105,31 +105,33 @@ const uint32_t min_plug_version = 100; * please post it to slurm-dev@lists.llnl.gov Thanks! \*****************************************************************************/ -extern int job_submit(struct job_descriptor *job_desc) +extern int job_submit(struct job_descriptor *job_desc, uint32_t submit_uid) { /* Log select fields from a job submit request. See slurm/slurm.h * for information about additional fields in struct job_descriptor. * Note that default values for most numbers is NO_VAL */ info("Job submit request: account:%s begin_time:%u dependency:%s " - "name:%s partition:%s qos:%s time_limit:%u user_id:%u", + "name:%s partition:%s qos:%s submit_uid:%u time_limit:%u " + "user_id:%u", job_desc->account, job_desc->begin_time, job_desc->dependency, job_desc->name, job_desc->partition, job_desc->qos, - job_desc->time_limit, job_desc->user_id); + submit_uid, job_desc->time_limit, job_desc->user_id); return SLURM_SUCCESS; } extern int job_modify(struct job_descriptor *job_desc, - struct job_record *job_ptr) + struct job_record *job_ptr, uint32_t submit_uid) { /* Log select fields from a job modify request. See slurm/slurm.h * for information about additional fields in struct job_descriptor. * Note that default values for most numbers is NO_VAL */ info("Job modify request: account:%s begin_time:%u dependency:%s " - "job_id:%u name:%s partition:%s qos:%s time_limit:%u", + "job_id:%u name:%s partition:%s qos:%s submit_uid:%u " + "time_limit:%u", job_desc->account, job_desc->begin_time, job_desc->dependency, job_desc->job_id, job_desc->name, job_desc->partition, - job_desc->qos, job_desc->time_limit); + job_desc->qos, submit_uid, job_desc->time_limit); return SLURM_SUCCESS; } diff --git a/src/plugins/job_submit/lua/job_submit_lua.c b/src/plugins/job_submit/lua/job_submit_lua.c index a41081ba606670666495d5ae874a1e6e8d4f7aca..dd6869675a7dc7bb13946827819bd8913908fd70 100644 --- a/src/plugins/job_submit/lua/job_submit_lua.c +++ b/src/plugins/job_submit/lua/job_submit_lua.c @@ -497,6 +497,13 @@ static int _get_part_rec_field (lua_State *L) if (part_ptr == NULL) { error("_get_part_field: part_ptr is NULL"); lua_pushnil (L); + } else if (!strcmp(name, "flag_default")) { + int is_default = 0; + if (part_ptr->flags & PART_FLAG_DEFAULT) + is_default = 1; + lua_pushnumber (L, is_default); + } else if (!strcmp(name, "flags")) { + lua_pushnumber (L, part_ptr->flags); } else if (!strcmp(name, "max_nodes")) { lua_pushnumber (L, part_ptr->max_nodes); } else if (!strcmp(name, "max_nodes_orig")) { @@ -578,7 +585,31 @@ static int _check_lua_script_functions() return (rc); } -static void _push_partition_list(void) +static bool _user_can_use_part(uint32_t user_id, uint32_t submit_uid, + struct part_record *part_ptr) +{ + int i; + + if (user_id == 0) { + if (part_ptr->flags & PART_FLAG_NO_ROOT) + return false; + return true; + } + + if ((part_ptr->flags & PART_FLAG_ROOT_ONLY) && (submit_uid != 0)) + return false; + + if (part_ptr->allow_uids == NULL) + return true; /* No user ID filters */ + + for (i=0; part_ptr->allow_uids[i]; i++) { + if (user_id == part_ptr->allow_uids[i]) + return true; + } + return false; +} + +static void _push_partition_list(uint32_t user_id, uint32_t submit_uid) { int i = 1; ListIterator part_iterator; @@ -589,6 +620,8 @@ static void _push_partition_list(void) if (!part_iterator) fatal("list_iterator_create malloc"); while ((part_ptr = (struct part_record *) list_next(part_iterator))) { + if (!_user_can_use_part(user_id, submit_uid, part_ptr)) + continue; lua_pushlightuserdata (L, part_ptr); lua_rawseti(L, -2, i++); } @@ -663,7 +696,7 @@ int fini (void) /* Lua script hook called for "submit job" event. */ -extern int job_submit(struct job_descriptor *job_desc) +extern int job_submit(struct job_descriptor *job_desc, uint32_t submit_uid) { int rc = SLURM_ERROR; slurm_mutex_lock (&lua_lock); @@ -677,7 +710,7 @@ extern int job_submit(struct job_descriptor *job_desc) goto out; lua_pushlightuserdata (L, job_desc); - _push_partition_list(); + _push_partition_list(job_desc->user_id, submit_uid); if (lua_pcall (L, 2, 0, 0) != 0) { error("%s/lua: %s: %s", __func__, lua_script_path, lua_tostring (L, -1)); @@ -690,7 +723,7 @@ out: slurm_mutex_unlock (&lua_lock); /* Lua script hook called for "modify job" event. */ extern int job_modify(struct job_descriptor *job_desc, - struct job_record *job_ptr) + struct job_record *job_ptr, uint32_t submit_uid) { int rc = SLURM_ERROR; slurm_mutex_lock (&lua_lock); @@ -705,7 +738,7 @@ extern int job_modify(struct job_descriptor *job_desc, lua_pushlightuserdata (L, job_desc); lua_pushlightuserdata (L, job_ptr); - _push_partition_list(); + _push_partition_list(job_ptr->user_id, submit_uid); if (lua_pcall (L, 3, 0, 0) != 0) { error("%s/lua: %s: %s", __func__, lua_script_path, lua_tostring (L, -1)); diff --git a/src/plugins/job_submit/partition/job_submit_partition.c b/src/plugins/job_submit/partition/job_submit_partition.c index 6ca1d5530791b657df8dae4f250e73821c2229c3..d98a1e443690c49d68b00a2b80e19944e30fb763 100644 --- a/src/plugins/job_submit/partition/job_submit_partition.c +++ b/src/plugins/job_submit/partition/job_submit_partition.c @@ -107,14 +107,21 @@ const uint32_t min_plug_version = 100; /* Test if this user can run jobs in the selected partition based upon * the partition's AllowGroups parameter. */ -static bool _user_access(uid_t run_uid, struct part_record *part_ptr) +static bool _user_access(uid_t run_uid, uint32_t submit_uid, + struct part_record *part_ptr) { int i; - if ((run_uid == 0) || (run_uid == getuid())) - return true; /* Superuser can run anywhere */ + if (run_uid == 0) { + if (part_ptr->flags & PART_FLAG_NO_ROOT) + return false; + return true; + } + + if ((part_ptr->flags & PART_FLAG_ROOT_ONLY) && (submit_uid != 0)) + return false; - if (!part_ptr->allow_uids) + if (part_ptr->allow_uids == NULL) return true; /* AllowGroups=ALL */ for (i=0; part_ptr->allow_uids[i]; i++) { @@ -127,7 +134,7 @@ static bool _user_access(uid_t run_uid, struct part_record *part_ptr) /* This exampe code will set a job's default partition to the highest * priority partition that is available to this user. This is only an * example and tremendous flexibility is available. */ -extern int job_submit(struct job_descriptor *job_desc) +extern int job_submit(struct job_descriptor *job_desc, uint32_t submit_uid) { ListIterator part_iterator; struct part_record *part_ptr; @@ -142,7 +149,7 @@ extern int job_submit(struct job_descriptor *job_desc) while ((part_ptr = (struct part_record *) list_next(part_iterator))) { if (!(part_ptr->state_up & PARTITION_SUBMIT)) continue; /* nobody can submit jobs here */ - if (!_user_access(job_desc->user_id, part_ptr)) + if (!_user_access(job_desc->user_id, submit_uid, part_ptr)) continue; /* AllowGroups prevents use */ if (!top_prio_part || (top_prio_part->priority < part_ptr->priority)) { @@ -162,7 +169,7 @@ extern int job_submit(struct job_descriptor *job_desc) } extern int job_modify(struct job_descriptor *job_desc, - struct job_record *job_ptr) + struct job_record *job_ptr, uint32_t submit_uid) { return SLURM_SUCCESS; } diff --git a/src/slurmctld/job_mgr.c b/src/slurmctld/job_mgr.c index 76ee06c96ef992d9c5508492ebfc3755fa5607ca..85f2dd81415f5faab3a9165612e37e0755e40ca8 100644 --- a/src/slurmctld/job_mgr.c +++ b/src/slurmctld/job_mgr.c @@ -3057,7 +3057,7 @@ static int _job_create(job_desc_msg_t * job_desc, int allocate, int will_run, *job_pptr = (struct job_record *) NULL; - error_code = job_submit_plugin_submit(job_desc); + error_code = job_submit_plugin_submit(job_desc, (uint32_t) submit_uid); if (error_code != SLURM_SUCCESS) return error_code; @@ -5621,7 +5621,8 @@ int update_job(job_desc_msg_t * job_specs, uid_t uid) return ESLURM_INVALID_JOB_ID; } - error_code = job_submit_plugin_modify(job_specs, job_ptr); + error_code = job_submit_plugin_modify(job_specs, job_ptr, + (uint32_t) uid); if (error_code != SLURM_SUCCESS) return error_code; diff --git a/src/slurmctld/job_submit.c b/src/slurmctld/job_submit.c index f2cc2ad1da84f8bce10d36cf7812f48a5f95984c..493bef05ca186af438266f0e65a6639371e2d01c 100644 --- a/src/slurmctld/job_submit.c +++ b/src/slurmctld/job_submit.c @@ -74,9 +74,11 @@ #include "src/slurmctld/slurmctld.h" typedef struct slurm_submit_ops { - int (*submit) ( struct job_descriptor *job_desc ); + int (*submit) ( struct job_descriptor *job_desc, + uint32_t submit_uid ); int (*modify) ( struct job_descriptor *job_desc, - struct job_record *job_ptr); + struct job_record *job_ptr, + uint32_t submit_uid ); } slurm_submit_ops_t; typedef struct slurm_submit_context { @@ -290,14 +292,15 @@ extern int job_submit_plugin_reconfig(void) * If any plugin function returns anything other than SLURM_SUCCESS * then stop and forward it's return value. */ -extern int job_submit_plugin_submit(struct job_descriptor *job_desc) +extern int job_submit_plugin_submit(struct job_descriptor *job_desc, + uint32_t submit_uid) { int i, rc; rc = job_submit_plugin_init(); slurm_mutex_lock(&submit_context_lock); for (i=0; ((i < submit_context_cnt) && (rc == SLURM_SUCCESS)); i++) - rc = (*(submit_context[i].ops.submit))(job_desc); + rc = (*(submit_context[i].ops.submit))(job_desc, submit_uid); slurm_mutex_unlock(&submit_context_lock); return rc; } @@ -308,14 +311,16 @@ extern int job_submit_plugin_submit(struct job_descriptor *job_desc) * then stop and forward it's return value. */ extern int job_submit_plugin_modify(struct job_descriptor *job_desc, - struct job_record *job_ptr) + struct job_record *job_ptr, + uint32_t submit_uid) { int i, rc; rc = job_submit_plugin_init(); slurm_mutex_lock(&submit_context_lock); for (i=0; ((i < submit_context_cnt) && (rc == SLURM_SUCCESS)); i++) - rc = (*(submit_context[i].ops.modify))(job_desc, job_ptr); + rc = (*(submit_context[i].ops.modify))(job_desc, job_ptr, + submit_uid); slurm_mutex_unlock(&submit_context_lock); return rc; } diff --git a/src/slurmctld/job_submit.h b/src/slurmctld/job_submit.h index c263b7026c2336ffc80450e577277916610c0be2..70110ba5f04d5f42bd8e750daf1a81333a2d83e7 100644 --- a/src/slurmctld/job_submit.h +++ b/src/slurmctld/job_submit.h @@ -71,7 +71,8 @@ extern int job_submit_plugin_reconfig(void); * If any plugin function returns anything other than SLURM_SUCCESS * then stop and forward it's return value. */ -extern int job_submit_plugin_submit(struct job_descriptor *job_desc); +extern int job_submit_plugin_submit(struct job_descriptor *job_desc, + uint32_t submit_uid); /* * Execute the job_modify() function in each job submit plugin. @@ -80,6 +81,7 @@ extern int job_submit_plugin_submit(struct job_descriptor *job_desc); * then stop and forward it's return value. */ extern int job_submit_plugin_modify(struct job_descriptor *job_desc, - struct job_record *job_ptr); + struct job_record *job_ptr, + uint32_t submit_uid); #endif /* !_JOB_SUBMIT_H */