From 0a13d2d33a438e711ecb991c777e413f7a68a222 Mon Sep 17 00:00:00 2001 From: Moe Jette <jette1@llnl.gov> Date: Tue, 29 Jul 2008 23:29:08 +0000 Subject: [PATCH] svn merge -r14620:14652 https://eris.llnl.gov/svn/slurm/branches/slurm-1.2 --- NEWS | 2 + src/common/read_config.c | 8 +- src/common/uid.c | 127 +++++++++++++++--- src/common/uid.h | 5 + src/plugins/jobcomp/filetxt/jobcomp_filetxt.c | 16 +-- src/plugins/sched/wiki/get_jobs.c | 13 +- src/plugins/sched/wiki2/get_jobs.c | 13 +- .../select/bluegene/plugin/block_sys.c | 23 ++-- .../select/bluegene/plugin/select_bluegene.c | 11 +- src/slurmctld/partition_mgr.c | 75 +++++++---- src/slurmd/slurmd/req.c | 20 +-- 11 files changed, 200 insertions(+), 113 deletions(-) diff --git a/NEWS b/NEWS index cee59fd1229..9fa39721878 100644 --- a/NEWS +++ b/NEWS @@ -421,6 +421,8 @@ documents those changes that are of interest to users and admins. requeued. -- Ignore the show_flag when getting job, step, node or partition information for user root. + -- Convert some functions to thread-safe versions: getpwnam, getpwuid, + getgrnam, and getgrgid to similar functions with "_r" suffix. * Changes in SLURM 1.2.33 ========================= diff --git a/src/common/read_config.c b/src/common/read_config.c index 2faba8f6ada..6ba28b2a59f 100644 --- a/src/common/read_config.c +++ b/src/common/read_config.c @@ -70,6 +70,7 @@ #include "src/common/parse_time.h" #include "src/common/slurm_selecttype_info.h" #include "src/common/util-net.h" +#include "src/common/uid.h" /* Instantiation of the "extern slurm_ctl_conf_t slurmcltd_conf" * found in slurmctld.h */ @@ -1918,14 +1919,13 @@ validate_and_set_defaults(slurm_ctl_conf_t *conf, s_p_hashtbl_t *hashtbl) conf->slurm_user_name = xstrdup("root"); conf->slurm_user_id = 0; } else { - struct passwd *slurm_passwd; - slurm_passwd = getpwnam(conf->slurm_user_name); - if (slurm_passwd == NULL) { + uid_t my_uid = uid_from_string(conf->slurm_user_name); + if (my_uid == (uid_t) -1) { error ("Invalid user for SlurmUser %s, ignored", conf->slurm_user_name); xfree(conf->slurm_user_name); } else { - conf->slurm_user_id = slurm_passwd->pw_uid; + conf->slurm_user_id = my_uid; } } diff --git a/src/common/uid.c b/src/common/uid.c index fe0ad85acfb..021d3afc352 100644 --- a/src/common/uid.c +++ b/src/common/uid.c @@ -41,48 +41,135 @@ #include <grp.h> #include <ctype.h> -#include "uid.h" +#include "src/common/uid.h" +#include "src/common/xmalloc.h" uid_t uid_from_string (char *name) { - struct passwd *pwd = NULL; - char *p = NULL; + struct passwd pwd, *result; + size_t bufsize; + char *buffer, *p = NULL; + int rc; uid_t uid = (uid_t) strtoul (name, &p, 10); - if (*p != '\0') - pwd = getpwnam (name); - else - pwd = getpwuid (uid); - - return pwd ? pwd->pw_uid : (uid_t) -1; + bufsize = sysconf(_SC_GETPW_R_SIZE_MAX); + buffer = xmalloc(bufsize); + if (*p != '\0') { + while (1) { + rc = getpwnam_r(name, &pwd, buffer, bufsize, &result); + if (rc == EINTR) + continue; + if (rc != 0) + result = NULL; + break; + } + if (result == NULL) + uid = (uid_t) -1; + else + uid = result->pw_uid; + } else { + while (1) { + rc = getpwuid_r(uid, &pwd, buffer, bufsize, &result); + if (rc == EINTR) + continue; + if (rc != 0) + result = NULL; + break; + } + if (result == NULL) + uid = (uid_t) -1; + /* else uid is already correct */ + } + xfree(buffer); + return uid; } char * uid_to_string (uid_t uid) { - struct passwd *pwd = NULL; + struct passwd pwd, *result; + size_t bufsize; + char *buffer; + int rc; /* Suse Linux does not handle multiple users with UID=0 well */ if (uid == 0) return "root"; - pwd = getpwuid(uid); - return pwd ? pwd->pw_name : "nobody"; + bufsize = sysconf(_SC_GETPW_R_SIZE_MAX); + buffer = xmalloc(bufsize); + while (1) { + rc = getpwuid_r(uid, &pwd, buffer, bufsize, &result); + if (rc == EINTR) + continue; + if (rc != 0) + result = NULL; + break; + } + xfree(buffer); + return result ? result->pw_name : "nobody"; } gid_t gid_from_string (char *name) { - struct group *g = NULL; - char *p = NULL; + struct group grp, *result; + size_t bufsize; + char *buffer, *p = NULL; + int rc; gid_t gid = (gid_t) strtoul (name, &p, 10); - if (*p != '\0') - g = getgrnam (name); - else - g = getgrgid (gid); - - return g ? g->gr_gid : (gid_t) -1; + bufsize = sysconf(_SC_GETGR_R_SIZE_MAX); + buffer = xmalloc(bufsize); + if (*p != '\0') { + while (1) { + rc = getgrnam_r(name, &grp, buffer, bufsize, &result); + if (rc == EINTR) + continue; + if (rc != 0) + result = NULL; + break; + } + if (result == NULL) + gid = (gid_t) -1; + else + gid = result->gr_gid; + } else { + while (1) { + rc = getgrgid_r(gid, &grp, buffer, bufsize, &result); + if (rc == EINTR) + continue; + if (rc != 0) + result = NULL; + break; + } + if (result == NULL) + gid = (gid_t) -1; + /* else gid is already correct */ + } + xfree(buffer); + return gid; } +char * +gid_to_string (gid_t gid) +{ + struct group grp, *result; + size_t bufsize; + char *buffer; + int rc; + + bufsize = sysconf(_SC_GETGR_R_SIZE_MAX); + buffer = xmalloc(bufsize); + while (1) { + rc = getgrgid_r(gid, &grp, buffer, bufsize, &result); + if (rc == EINTR) + continue; + if (rc != 0) + result = NULL; + break; + } + xfree(buffer); + return result ? result->gr_name : "nobody"; +} diff --git a/src/common/uid.h b/src/common/uid.h index 533934ab716..d79a2f6a800 100644 --- a/src/common/uid.h +++ b/src/common/uid.h @@ -40,6 +40,7 @@ #define __SLURM_UID_UTILITY_H__ #include <sys/types.h> +#include <unistd.h> /* * Return validated uid_t for string in ``name'' which contains @@ -60,4 +61,8 @@ gid_t gid_from_string (char *name); */ char *uid_to_string (uid_t uid); +/* + * Same as uid_to_string, but for group name. +*/ +char *gid_to_string (gid_t gid); #endif /*__SLURM_UID_UTILITY_H__*/ diff --git a/src/plugins/jobcomp/filetxt/jobcomp_filetxt.c b/src/plugins/jobcomp/filetxt/jobcomp_filetxt.c index a4e67243bab..432a7be1586 100644 --- a/src/plugins/jobcomp/filetxt/jobcomp_filetxt.c +++ b/src/plugins/jobcomp/filetxt/jobcomp_filetxt.c @@ -53,6 +53,7 @@ #include "src/common/slurm_protocol_defs.h" #include "src/common/slurm_jobcomp.h" #include "src/common/parse_time.h" +#include "src/common/uid.h" #include "filetxt_jobcomp_process.h" /* @@ -116,20 +117,13 @@ _get_user_name(uint32_t user_id, char *user_name, int buf_size) { static uint32_t cache_uid = 0; static char cache_name[32] = "root"; - struct passwd * user_info = NULL; - if (user_id == cache_uid) - snprintf(user_name, buf_size, "%s", cache_name); - else { - user_info = getpwuid((uid_t) user_id); - if (user_info && user_info->pw_name[0]) - snprintf(cache_name, sizeof(cache_name), "%s", - user_info->pw_name); - else - snprintf(cache_name, sizeof(cache_name), "Unknown"); + if (user_id != cache_uid) { + snprintf(cache_name, sizeof(cache_name), "%s", + uid_to_string((uid_t) user_id)); cache_uid = user_id; - snprintf(user_name, buf_size, "%s", cache_name); } + snprintf(user_name, buf_size, "%s", cache_name); } /* get the group name for the give group_id */ diff --git a/src/plugins/sched/wiki/get_jobs.c b/src/plugins/sched/wiki/get_jobs.c index 46dbce9a1cc..ece3ed12cda 100644 --- a/src/plugins/sched/wiki/get_jobs.c +++ b/src/plugins/sched/wiki/get_jobs.c @@ -48,7 +48,6 @@ static char * _dump_all_jobs(int *job_cnt, time_t update_time); static char * _dump_job(struct job_record *job_ptr, time_t update_time); -static char * _get_group_name(gid_t gid); static uint16_t _get_job_cpus_per_task(struct job_record *job_ptr); static uint32_t _get_job_end_time(struct job_record *job_ptr); static char * _get_job_features(struct job_record *job_ptr); @@ -320,7 +319,7 @@ static char * _dump_job(struct job_record *job_ptr, time_t update_time) snprintf(tmp, sizeof(tmp), "UNAME=%s;GNAME=%s;", uid_to_string((uid_t) job_ptr->user_id), - _get_group_name(job_ptr->group_id)); + gid_to_string(job_ptr->group_id)); xstrcat(buf, tmp); return buf; @@ -363,16 +362,6 @@ static uint32_t _get_job_min_nodes(struct job_record *job_ptr) return (uint32_t) 1; } -static char * _get_group_name(gid_t gid) -{ - struct group *grp; - - grp = getgrgid(gid); - if (grp) - return grp->gr_name; - return "nobody"; -} - static uint32_t _get_job_submit_time(struct job_record *job_ptr) { if (job_ptr->details) diff --git a/src/plugins/sched/wiki2/get_jobs.c b/src/plugins/sched/wiki2/get_jobs.c index ed5d46d0601..ec130759637 100644 --- a/src/plugins/sched/wiki2/get_jobs.c +++ b/src/plugins/sched/wiki2/get_jobs.c @@ -48,7 +48,6 @@ static char * _dump_all_jobs(int *job_cnt, time_t update_time); static char * _dump_job(struct job_record *job_ptr, time_t update_time); -static char * _get_group_name(gid_t gid); static void _get_job_comment(struct job_record *job_ptr, char *buffer, int buf_size); static uint16_t _get_job_cpus_per_task(struct job_record *job_ptr); @@ -370,7 +369,7 @@ static char * _dump_job(struct job_record *job_ptr, time_t update_time) snprintf(tmp, sizeof(tmp), "UNAME=%s;GNAME=%s;", uid_to_string((uid_t) job_ptr->user_id), - _get_group_name(job_ptr->group_id)); + gid_to_string(job_ptr->group_id)); xstrcat(buf, tmp); return buf; @@ -469,16 +468,6 @@ static uint32_t _get_job_min_nodes(struct job_record *job_ptr) return (uint32_t) 1; } -static char * _get_group_name(gid_t gid) -{ - struct group *grp; - - grp = getgrgid(gid); - if (grp) - return grp->gr_name; - return "nobody"; -} - static uint32_t _get_job_submit_time(struct job_record *job_ptr) { if (job_ptr->details) diff --git a/src/plugins/select/bluegene/plugin/block_sys.c b/src/plugins/select/bluegene/plugin/block_sys.c index badee49ef4a..40e11e4e430 100755 --- a/src/plugins/select/bluegene/plugin/block_sys.c +++ b/src/plugins/select/bluegene/plugin/block_sys.c @@ -37,7 +37,7 @@ \*****************************************************************************/ #include "bluegene.h" - +#include "src/common/uid.h" /** these are used in the dynamic partitioning algorithm */ @@ -158,7 +158,7 @@ static int _post_allocate(bg_record_t *bg_record) #ifdef HAVE_BG_FILES int i; pm_partition_id_t block_id; - struct passwd *pw_ent = NULL; + uint_t my_uid; /* Add partition record to the DB */ debug2("adding block\n"); @@ -208,11 +208,12 @@ static int _post_allocate(bg_record_t *bg_record) bg_record->user_name = xstrdup(slurmctld_conf.slurm_user_name); slurm_conf_unlock(); - - if((pw_ent = getpwnam(bg_record->user_name)) == NULL) { - error("getpwnam(%s): %m", bg_record->user_name); + + my_uid = uid_from_string(bg_record->user_name); + if (my_uid == (uid_t) -1) { + error("getpwnam_r(%s): %m", bg_record->user_name); } else { - bg_record->user_uid = pw_ent->pw_uid; + bg_record->user_uid = my_uid; } } /* We are done with the block */ @@ -378,7 +379,7 @@ int read_bg_blocks() rm_partition_t *block_ptr = NULL; char node_name_tmp[255], *user_name = NULL; bg_record_t *bg_record = NULL; - struct passwd *pw_ent = NULL; + uid_t my_uid; int *coord = NULL; int block_number, block_count; @@ -707,12 +708,12 @@ int read_bg_blocks() free(user_name); } - if((pw_ent = getpwnam(bg_record->user_name)) - == NULL) { - error("getpwnam(%s): %m", + my_uid = uid_from_string(bg_record->user_name); + if (my_uid == (uid_t) -1) { + error("getpwnam_r(%s): %m", bg_record->user_name); } else { - bg_record->user_uid = pw_ent->pw_uid; + bg_record->user_uid = my_uid; } } diff --git a/src/plugins/select/bluegene/plugin/select_bluegene.c b/src/plugins/select/bluegene/plugin/select_bluegene.c index 3e569b21a7e..ca9039997cb 100644 --- a/src/plugins/select/bluegene/plugin/select_bluegene.c +++ b/src/plugins/select/bluegene/plugin/select_bluegene.c @@ -43,6 +43,7 @@ #include "defined_block.h" #endif +#include "src/common/uid.h" #include "src/slurmctld/trigger_mgr.h" #include <fcntl.h> @@ -360,8 +361,8 @@ extern int select_p_state_restore(char *dir_name) int data_allocated, data_read = 0; char *ver_str = NULL; uint32_t ver_str_len; - struct passwd *pw_ent = NULL; int blocks = 0; + uid_t my_uid; debug("bluegene: select_p_state_restore"); #ifdef HAVE_BG_FILES @@ -542,12 +543,12 @@ extern int select_p_state_restore(char *dir_name) bg_record->user_name = xstrdup(slurmctld_conf.slurm_user_name); slurm_conf_unlock(); - if((pw_ent = getpwnam(bg_record->user_name)) - == NULL) { - error("getpwnam(%s): %m", + my_uid = uid_from_string(bg_record->user_name); + if (my_uid == (uid_t) -1) { + error("getpwnam_r(%s): %m", bg_record->user_name); } else { - bg_record->user_uid = pw_ent->pw_uid; + bg_record->user_uid = my_uid; } bg_record->blrtsimage = diff --git a/src/slurmctld/partition_mgr.c b/src/slurmctld/partition_mgr.c index 7876a88ed02..a1cc06871c6 100644 --- a/src/slurmctld/partition_mgr.c +++ b/src/slurmctld/partition_mgr.c @@ -58,6 +58,7 @@ #include "src/common/list.h" #include "src/common/node_select.h" #include "src/common/pack.h" +#include "src/common/uid.h" #include "src/common/xstring.h" #include "src/slurmctld/locks.h" @@ -1051,49 +1052,65 @@ uid_t *_get_groups_members(char *group_names) */ uid_t *_get_group_members(char *group_name) { - struct group *group_struct_ptr; - struct passwd *user_pw_ptr; - int i, j; - uid_t *group_uids = NULL; - int uid_cnt = 0; - - group_struct_ptr = getgrnam(group_name); /* Note: static memory, - * do not free */ - if (group_struct_ptr == NULL) { + size_t grp_bufsize, pwd_bufsize; + char *grp_buffer, *pwd_buffer; + struct group grp, *grp_result; + struct passwd pwd, *pwd_result; + uid_t *group_uids; + gid_t my_gid; + int i, j, rc, uid_cnt; + + grp_bufsize = sysconf(_SC_GETGR_R_SIZE_MAX); + grp_buffer = xmalloc(grp_bufsize); + if (getgrnam_r(group_name, &grp, grp_buffer, grp_bufsize, + &grp_result)) { error("Could not find configured group %s", group_name); - setgrent(); + xfree(grp_buffer); return NULL; } + my_gid = grp_result->gr_gid; - for (i = 0;; i++) { - if (group_struct_ptr->gr_mem[i] == NULL) + for (uid_cnt=0; ; uid_cnt++) { + if (grp_result->gr_mem[uid_cnt] == NULL) break; } - - uid_cnt = i; group_uids = (uid_t *) xmalloc(sizeof(uid_t) * (uid_cnt + 1)); - + + pwd_bufsize = sysconf(_SC_GETGR_R_SIZE_MAX); + pwd_buffer = xmalloc(pwd_bufsize); j = 0; - for (i = 0; i < uid_cnt; i++) { - user_pw_ptr = getpwnam(group_struct_ptr->gr_mem[i]); - if (user_pw_ptr) { - if (user_pw_ptr->pw_uid) - group_uids[j++] = user_pw_ptr->pw_uid; - } else + for (i=0; i<uid_cnt; i++) { + while (1) { + rc = getpwnam_r(grp_result->gr_mem[i], &pwd, pwd_buffer, + pwd_bufsize, &pwd_result); + if (rc == EINTR) + continue; + else if (rc != 0) + pwd_result = NULL; + break; + } + if (pwd_result == NULL) { error("Could not find user %s in configured group %s", - group_struct_ptr->gr_mem[i], group_name); - setpwent(); + grp_result->gr_mem[i], group_name); + } else { + if (pwd_result->pw_uid) + group_uids[j++] = pwd_result->pw_uid; + } } - - while((user_pw_ptr = getpwent())) { - if(user_pw_ptr->pw_gid != group_struct_ptr->gr_gid) + xfree(pwd_buffer); + xfree(grp_buffer); + + /* NOTE: code below not reentrant, avoid these functions elsewhere */ + setpwent(); + while ((pwd_result = getpwent())) { + if (pwd_result->pw_gid != my_gid) continue; j++; xrealloc(group_uids, ((j+1) * sizeof(uid_t))); - group_uids[j-1] = user_pw_ptr->pw_uid; + group_uids[j-1] = pwd_result->pw_uid; } - setpwent(); - setgrent(); + endpwent(); + return group_uids; } diff --git a/src/slurmd/slurmd/req.c b/src/slurmd/slurmd/req.c index d5314fced80..96cbc4cb586 100644 --- a/src/slurmd/slurmd/req.c +++ b/src/slurmd/slurmd/req.c @@ -319,15 +319,15 @@ _send_slurmstepd_init(int fd, slurmd_step_type_t type, void *req, Buf buffer = NULL; slurm_msg_t msg; uid_t uid = (uid_t)-1; - struct passwd pwd, *pwd_ptr; - char *pwd_buf; - size_t buf_size; gids_t *gids = NULL; int rank; int parent_rank, children, depth, max_depth; char *parent_alias = NULL; slurm_addr parent_addr = {0}; + size_t pwd_bufsize; + char *pwd_buffer; + struct passwd pwd, *pwd_result; slurm_msg_t_init(&msg); /* send type over to slurmstepd */ @@ -452,18 +452,20 @@ _send_slurmstepd_init(int fd, slurmd_step_type_t type, void *req, /* send cached group ids array for the relevant uid */ debug3("_send_slurmstepd_init: call to getpwuid_r"); - buf_size = sysconf(_SC_GETPW_R_SIZE_MAX); - pwd_buf = xmalloc(buf_size); - if (getpwuid_r(uid, &pwd, pwd_buf, buf_size, &pwd_ptr)) { - xfree(pwd_buf); + pwd_bufsize = sysconf(_SC_GETPW_R_SIZE_MAX); + pwd_buffer = xmalloc(pwd_bufsize); + if (getpwuid_r(uid, &pwd, pwd_buffer, pwd_bufsize, &pwd_result) || + (pwd_result == NULL)) { error("_send_slurmstepd_init getpwuid_r: %m"); len = 0; safe_write(fd, &len, sizeof(int)); + xfree(pwd_buffer); return -1; } debug3("_send_slurmstepd_init: return from getpwuid_r"); - if ((gids = _gids_cache_lookup(pwd.pw_name, pwd.pw_gid))) { + if ((gids = _gids_cache_lookup(pwd_result->pw_name, + pwd_result->pw_gid))) { int i; uint32_t tmp32; safe_write(fd, &gids->ngids, sizeof(int)); @@ -475,7 +477,7 @@ _send_slurmstepd_init(int fd, slurmd_step_type_t type, void *req, len = 0; safe_write(fd, &len, sizeof(int)); } - xfree(pwd_buf); + xfree(pwd_buffer); return 0; rwfail: -- GitLab