1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (C) 2004 Cluster File Systems, Inc.
6 * This file is part of Lustre, http://www.lustre.org.
8 * Lustre is free software; you can redistribute it and/or
9 * modify it under the terms of version 2 of the GNU General Public
10 * License as published by the Free Software Foundation.
12 * Lustre is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Lustre; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
36 #include <lustre/lustre_user.h>
38 static char *progname;
42 fprintf(out, "\nusage: %s {-d | mdsname} {uid}\n"
43 "Normally invoked as an upcall from Lustre, set via:\n"
44 " /proc/fs/lustre/mds/{mdsname}/group_upcall\n"
45 "\t-d: debug, print values to stdout instead of Lustre\n",
49 static int compare_u32(const void *v1, const void *v2)
51 return (*(__u32 *)v1 - *(__u32 *)v2);
54 static void errlog(const char *fmt, ...)
58 openlog(progname, LOG_PERROR, LOG_AUTHPRIV);
61 vsyslog(LOG_NOTICE, fmt, arg);
67 int get_groups_local(struct mds_grp_downcall_data **grp)
69 struct mds_grp_downcall_data *param;
70 int i, maxgroups, size;
74 pw = getpwuid((*grp)->mgd_uid);
76 errlog("no such user %u\n", (*grp)->mgd_uid);
77 (*grp)->mgd_err = errno ? errno : EIDRM;
78 return sizeof(*param);
80 (*grp)->mgd_gid = pw->pw_gid;
82 maxgroups = sysconf(_SC_NGROUPS_MAX);
83 size = offsetof(struct mds_grp_downcall_data, mgd_groups[maxgroups]);
86 errlog("fail to alloc %d bytes for uid %u with %d groups\n",
87 size, (*grp)->mgd_uid, maxgroups);
88 return sizeof(*param);
91 memcpy(param, *grp, sizeof(*param));
92 param->mgd_groups[param->mgd_ngroups++] = pw->pw_gid;
94 while ((gr = getgrent())) {
95 if (gr->gr_gid == pw->pw_gid)
99 for (i = 0; gr->gr_mem[i]; i++) {
100 if (strcmp(gr->gr_mem[i], pw->pw_name) == 0) {
101 param->mgd_groups[param->mgd_ngroups++] =
106 if (param->mgd_ngroups == maxgroups)
110 qsort(param->mgd_groups, param->mgd_ngroups,
111 sizeof(param->mgd_groups[0]), compare_u32);
116 /* Note that we need to make the downcall regardless of error, so that the
117 * MDS doesn't continue to wait on the upcall. */
118 int main(int argc, char **argv)
120 int fd, rc, size, debug = 0;
121 struct mds_grp_downcall_data sparam = { MDS_GRP_DOWNCALL_MAGIC };
122 struct mds_grp_downcall_data *param = &sparam;
123 char pathname[1024], *end;
125 progname = strrchr(argv[0], '/');
126 if (progname == NULL)
132 fprintf(stderr, "%s: bad parameter count\n", progname);
137 if (strcmp(argv[1], "-d") == 0)
140 param->mgd_uid = strtoul(argv[2], &end, 0);
142 fprintf(stderr, "%s: invalid uid '%s'\n", progname, argv[2]);
147 size = get_groups_local(¶m);
150 if (param->mgd_err) {
151 if (param->mgd_err != ENXIO)
153 "%s: error getting uid %d groups: %s\n",
154 progname, param->mgd_uid,
155 strerror(param->mgd_err));
158 printf("uid=%d gid=", param->mgd_uid);
159 for (i = 0; i < param->mgd_ngroups; i++)
160 printf("%s%d", i > 0 ? "," : "",
161 param->mgd_groups[i]);
166 snprintf(pathname, 1024, "/proc/fs/lustre/mds/%s/group_info",
168 fd = open(pathname, O_WRONLY);
170 fprintf(stderr, "%s: can't open device %s: %s\n",
171 progname, pathname, strerror(errno));
174 rc = write(fd, param, size);