summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaleb KEITHLEY <kkeithle@redhat.com>2012-01-09 12:32:46 -0500
committerAnand Avati <avati@gluster.com>2012-01-14 04:51:20 -0800
commit3007bdddb1cae3d2b036ebddfc76ca6f6e06a184 (patch)
tree8ea0779ea5e3d53324e6d23135a9f2d3bb52739b
parent0e1679aee746040cdd509c5cd4004a4641c4c203 (diff)
don't try to get ngroups from /proc on non-Linux systems
Emmanual Dreyfus abandoned his changes, seemingly because he couldn't get rfc.sh to correctly generate his changed patch set. Since Mac OS is an important port, I suggest we keep this change alive. (This change also works on the other BSDs too) Now with added Solaris support BUG: 764655 Change-Id: I6a9ab7383777f9a09ab5c9a6914f45eee43461fb Signed-off-by: Kaleb S. KEITHLEY <kkeithle@redhat.com> Reviewed-on: http://review.gluster.com/2617 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Amar Tumballi <amar@gluster.com> Reviewed-by: Anand Avati <avati@gluster.com>
-rw-r--r--xlators/mount/fuse/src/fuse-helpers.c64
1 files changed, 58 insertions, 6 deletions
diff --git a/xlators/mount/fuse/src/fuse-helpers.c b/xlators/mount/fuse/src/fuse-helpers.c
index f0e9fb60296..941907cea8b 100644
--- a/xlators/mount/fuse/src/fuse-helpers.c
+++ b/xlators/mount/fuse/src/fuse-helpers.c
@@ -18,6 +18,11 @@
*/
#include "fuse-bridge.h"
+#if defined(GF_SOLARIS_HOST_OS)
+#include <sys/procfs.h>
+#else
+#include <sys/sysctl.h>
+#endif
xlator_t *
fuse_state_subvol (fuse_state_t *state)
@@ -138,25 +143,26 @@ get_fuse_state (xlator_t *this, fuse_in_header_t *finh)
void
frame_fill_groups (call_frame_t *frame)
{
- char filename[128];
+#if defined(GF_LINUX_HOST_OS)
+ char filename[32];
char line[128];
char *ptr = NULL;
- int ret = 0;
FILE *fp = NULL;
int idx = 0;
long int id = 0;
char *saveptr = NULL;
char *endptr = NULL;
+ int ret = 0;
- ret = snprintf (filename, 128, "/proc/%d/status", frame->root->pid);
- if (ret == 128)
+ ret = snprintf (filename, sizeof filename, "/proc/%d/status", frame->root->pid);
+ if (ret >= sizeof filename)
goto out;
fp = fopen (filename, "r");
if (!fp)
goto out;
- while ((ptr = fgets (line, 128, fp))) {
+ while ((ptr = fgets (line, sizeof line, fp))) {
if (strncmp (ptr, "Groups:", 7) != 0)
continue;
@@ -182,7 +188,53 @@ frame_fill_groups (call_frame_t *frame)
out:
if (fp)
fclose (fp);
- return;
+#elif defined(GF_SOLARIS_HOST_OS)
+ char filename[32];
+ char scratch[128];
+ prcred_t *prcred = (prcred_t *) scratch;
+ FILE *fp = NULL;
+ int ret = 0;
+
+ ret = snprintf (filename, sizeof filename,
+ "/proc/%d/cred", frame->root->pid);
+
+ if (ret < sizeof filename) {
+ fp = fopen (filename, "r");
+ if (fp != NULL) {
+ if (fgets (scratch, sizeof scratch, fp) != NULL) {
+ frame->root->ngrps = MIN(prcred->pr_ngroups,
+ GF_REQUEST_MAXGROUPS);
+ }
+ fclose (fp);
+ }
+ }
+#elif defined(CTL_KERN) /* DARWIN and *BSD */
+ /*
+ N.B. CTL_KERN is an enum on Linux. (Meaning, if it's not
+ obvious, that it's not subject to preprocessor directives
+ like '#if defined'.)
+ Unlike Linux, on Mac OS and the BSDs it is a #define. We
+ could test to see that KERN_PROC is defined, but, barring any
+ evidence to the contrary, I think that's overkill.
+ We might also test that GF_DARWIN_HOST_OS is defined, why
+ limit this to just Mac OS. It's equally valid for the BSDs
+ and we do have people building on NetBSD and FreeBSD.
+ */
+ int name[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, frame->root->pid };
+ size_t namelen = sizeof name / sizeof name[0];
+ struct kinfo_proc kp;
+ size_t kplen = sizeof(kp);
+ int i, ngroups;
+
+ if (sysctl(name, namelen, &kp, &kplen, NULL, 0) != 0)
+ return;
+ ngroups = MIN(kp.kp_eproc.e_ucred.cr_ngroups, GF_REQUEST_MAXGROUPS);
+ for (i = 0; i < ngroups; i++)
+ frame->root->groups[i] = kp.kp_eproc.e_ucred.cr_groups[i];
+ frame->root->ngrps = ngroups;
+#else
+ frame->root->ngrps = 0;
+#endif /* GF_LINUX_HOST_OS */
}