src/main.c | 70 ++++++++++++------------------------------------------------- 1 file changed, 14 insertions(+), 56 deletions(-)
New commits: commit fe871876d0c04b4abb67e7f1990bdd96e7556aa5 Author: Nir Soffer nsoffer@redhat.com Date: Wed Oct 14 12:51:33 2015 -0500
sanlock: setup supplementary groups before daemonizing
Sanlock daemon used to setup the supplementary groups after daemonizing. This may be slow on overloaded machines creating a window where sanlock supplementary groups are empty, confusing vdsm-tool.
This patch set the supplementary groups before daemonizing, so programs managing sanlock would wait until it the daemon is configured properly, eliminating the race during startup. The child process inherits the supplementary groups set by the parent.
The complex code for setting groups was replaced with a call to initgroups().
Signed-off-by: Nir Soffer nsoffer@redhat.com
diff --git a/src/main.c b/src/main.c index 958b57b..7038e4e 100644 --- a/src/main.c +++ b/src/main.c @@ -1431,65 +1431,23 @@ static void setup_limits(void)
static void setup_groups(void) { - int rv, i, j, h; - int pngroups, sngroups, ngroups_max; - gid_t *pgroup, *sgroup; + int rv;
if (!com.uname || !com.gname) return;
- ngroups_max = sysconf(_SC_NGROUPS_MAX); - if (ngroups_max < 0) { - log_error("cannot get the max number of groups %i", errno); - return; - } - - pgroup = malloc(ngroups_max * 2 * sizeof(gid_t)); - if (!pgroup) { - log_error("cannot malloc the group list %i", errno); - exit(EXIT_FAILURE); - } - - pngroups = getgroups(ngroups_max, pgroup); - if (pngroups < 0) { - log_error("cannot get the process groups %i", errno); - goto out; - } - - sgroup = pgroup + ngroups_max; - sngroups = ngroups_max; - - rv = getgrouplist(com.uname, com.gid, sgroup, &sngroups); + rv = initgroups(com.uname, com.gid); if (rv < 0) { - log_error("cannot get the user %s groups %i", com.uname, errno); - goto out; + log_error("error initializing groups errno %i", errno); } +}
- for (i = 0, j = pngroups; i < sngroups; i++) { - if (j >= ngroups_max) { - log_error("too many groups for the user %s", com.uname); - break; - } - - /* check if the groups is already present in the list */ - for (h = 0; h < j; h++) { - if (pgroup[h] == sgroup[i]) { - goto skip_gid; - } - } - - pgroup[j] = sgroup[i]; - j++; - - skip_gid: - ; /* skipping the gid because it's already present */ - } +static void setup_uid_gid(void) +{ + int rv;
- rv = setgroups(j, pgroup); - if (rv < 0) { - log_error("cannot set the user %s groups %i", com.uname, errno); - goto out; - } + if (!com.uname || !com.gname) + return;
rv = setgid(com.gid); if (rv < 0) { @@ -1509,9 +1467,6 @@ static void setup_groups(void) if (rv < 0) { log_error("cannot set dumpable process errno %i", errno); } - - out: - free(pgroup); }
static void setup_signals(void) @@ -1660,9 +1615,12 @@ static int do_daemon(void) { int fd, rv;
- /* TODO: copy comprehensive daemonization method from libvirtd */ + + /* This can take a while so do it before forking. */ + setup_groups();
if (!com.debug) { + /* TODO: copy comprehensive daemonization method from libvirtd */ if (daemon(0, 0) < 0) { log_tool("cannot fork daemon\n"); exit(EXIT_FAILURE); @@ -1699,7 +1657,7 @@ static int do_daemon(void)
setup_host_name();
- setup_groups(); + setup_uid_gid();
log_level(0, 0, NULL, LOG_WARNING, "sanlock daemon started %s host %s", VERSION, our_host_name_global);
sanlock-devel@lists.fedorahosted.org