1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (C) 2004-2006 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.
35 #include <sys/types.h>
39 #include <lustre/liblustreapi.h>
40 #include <lustre/lustre_user.h>
44 static char *progname;
46 static void usage(void)
49 "\nusage: %s {uid} {gid} {mdtname} {ino} {handle} {cmd}\n"
50 "Normally invoked as an upcall from Lustre, set via:\n"
51 " /proc/fs/lustre/mdt/{mdtname}/rmtacl_upcall\n",
55 static inline void show_result(struct rmtacl_downcall_data *data)
57 fprintf(stdout, "buflen %d\n\n%s\n", data->add_buflen, data->add_buf);
60 #define MDS_ERR "server processing error"
62 static void errlog(char *buf, const char *fmt, ...)
67 vsprintf(buf, fmt, args);
71 static char *get_lustre_mount(void)
75 static char mntpath[PATH_MAX] = "";
77 fp = setmntent(MOUNTED, "r");
79 fprintf(stderr, "setmntent %s failed: %s\n",
80 MOUNTED, strerror(errno));
89 if (!llapi_is_lustre_mnttype(mnt))
92 if (strstr(mnt->mnt_fsname, ":/lustre")) {
93 /* save the mountpoint dir part */
94 strncpy(mntpath, mnt->mnt_dir, sizeof(mntpath));
104 int main(int argc, char **argv)
106 struct rmtacl_downcall_data *data;
107 char procname[1024], *buf, *mntpath;
108 int out_pipe[2], err_pipe[2], pid, size, buflen, fd, rc;
110 progname = basename(argv[0]);
117 size = offsetof(struct rmtacl_downcall_data, add_buf[RMTACL_SIZE_MAX]);
120 fprintf(stderr, "malloc %d failed\n", size);
123 memset(data, 0, size);
124 data->add_magic = RMTACL_DOWNCALL_MAGIC;
125 data->add_key = strtoll(argv[4], NULL, 10);
126 data->add_handle = strtoul(argv[5], NULL, 10);
129 mntpath = get_lustre_mount();
131 errlog(buf, MDS_ERR"(no lustre mounted on MDS)\n");
136 if (pipe(out_pipe) < 0 || pipe(err_pipe) < 0) {
137 errlog(buf, MDS_ERR"(pipe failed): %s\n", strerror(errno));
141 if ((pid = fork()) < 0) {
142 errlog(buf, MDS_ERR"(fork failed): %s\n", strerror(errno));
144 } else if (pid == 0) {
149 if (out_pipe[1] != STDOUT_FILENO) {
150 dup2(out_pipe[1], STDOUT_FILENO);
154 if (err_pipe[1] != STDERR_FILENO) {
155 dup2(err_pipe[1], STDERR_FILENO);
160 if (chdir(mntpath) < 0) {
161 fprintf(stderr, "chdir %s failed: %s\n",
162 mntpath, strerror(errno));
166 gid = (gid_t)atoi(argv[2]);
168 if (setgid(gid) == -1) {
169 fprintf(stderr, "setgid %u failed: %s\n",
170 gid, strerror(errno));
175 uid = (uid_t)atoi(argv[1]);
177 if (setuid(uid) == -1) {
178 fprintf(stderr, "setuid %u failed: %s\n",
179 uid, strerror(errno));
184 execl("/bin/sh", "sh", "-c", argv[6], NULL);
185 fprintf(stderr, "execl %s failed: %s\n",
186 argv[6], strerror(errno));
191 /* parent process handling */
197 rc = read(out_pipe[0], buf + buflen, RMTACL_SIZE_MAX - buflen);
199 errlog(buf, MDS_ERR"(read failed): %s\n",
206 if (buflen >= RMTACL_SIZE_MAX)
216 rc = read(err_pipe[0], buf + buflen, RMTACL_SIZE_MAX - buflen);
218 errlog(buf, MDS_ERR"(read failed): %s\n",
225 if (buflen >= RMTACL_SIZE_MAX)
232 buf[RMTACL_SIZE_MAX - 1] = 0;
233 data->add_buflen = strlen(buf) + 1;
234 if (getenv("L_FACL_TEST")) {
240 snprintf(procname, sizeof(procname),
241 "/proc/fs/lustre/mdt/%s/rmtacl_info", argv[3]);
242 fd = open(procname, O_WRONLY);
244 fprintf(stderr, "open %s failed: %s\n",
245 procname, strerror(errno));
250 buflen = offsetof(struct rmtacl_downcall_data,
251 add_buf[data->add_buflen]);
252 rc = write(fd, data, buflen);
255 fprintf(stderr, "write %s len %d return %d: %s\n",
256 procname, buflen, rc, strerror(errno));