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} {key} {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))
93 * XXX: The fsname can be configed by user, it should pass into as a parameter.
94 * Since we only need one client on mdt node for remote set{get}facl, it is
95 * unnecessary to do the accurate match for fsname, but match ":/" temporary.
97 //if (strstr(mnt->mnt_fsname, ":/lustre")) {
98 /* save the mountpoint dir part */
99 strncpy(mntpath, mnt->mnt_dir, sizeof(mntpath));
109 int main(int argc, char **argv)
111 struct rmtacl_downcall_data *data;
112 char procname[1024], *buf, *mntpath;
113 int out_pipe[2], err_pipe[2], pid, size, buflen, fd, rc;
115 progname = basename(argv[0]);
122 size = offsetof(struct rmtacl_downcall_data, add_buf[RMTACL_SIZE_MAX]);
125 fprintf(stderr, "malloc %d failed\n", size);
128 memset(data, 0, size);
129 data->add_magic = RMTACL_DOWNCALL_MAGIC;
130 data->add_key = strtoll(argv[4], NULL, 10);
131 data->add_handle = strtoul(argv[5], NULL, 10);
134 mntpath = get_lustre_mount();
136 errlog(buf, MDS_ERR"(no lustre mounted on MDS)\n");
141 if (pipe(out_pipe) < 0 || pipe(err_pipe) < 0) {
142 errlog(buf, MDS_ERR"(pipe failed): %s\n", strerror(errno));
146 if ((pid = fork()) < 0) {
147 errlog(buf, MDS_ERR"(fork failed): %s\n", strerror(errno));
149 } else if (pid == 0) {
154 if (out_pipe[1] != STDOUT_FILENO) {
155 dup2(out_pipe[1], STDOUT_FILENO);
159 if (err_pipe[1] != STDERR_FILENO) {
160 dup2(err_pipe[1], STDERR_FILENO);
165 if (chdir(mntpath) < 0) {
166 fprintf(stderr, "chdir %s failed: %s\n",
167 mntpath, strerror(errno));
171 gid = (gid_t)atoi(argv[2]);
173 if (setgid(gid) == -1) {
174 fprintf(stderr, "setgid %u failed: %s\n",
175 gid, strerror(errno));
180 uid = (uid_t)atoi(argv[1]);
182 if (setuid(uid) == -1) {
183 fprintf(stderr, "setuid %u failed: %s\n",
184 uid, strerror(errno));
189 execl("/bin/sh", "sh", "-c", argv[6], NULL);
190 fprintf(stderr, "execl %s failed: %s\n",
191 argv[6], strerror(errno));
196 /* parent process handling */
202 rc = read(out_pipe[0], buf + buflen, RMTACL_SIZE_MAX - buflen);
204 errlog(buf, MDS_ERR"(read failed): %s\n",
211 if (buflen >= RMTACL_SIZE_MAX)
221 rc = read(err_pipe[0], buf + buflen, RMTACL_SIZE_MAX - buflen);
223 errlog(buf, MDS_ERR"(read failed): %s\n",
230 if (buflen >= RMTACL_SIZE_MAX)
237 buf[RMTACL_SIZE_MAX - 1] = 0;
238 data->add_buflen = strlen(buf) + 1;
239 if (getenv("L_FACL_TEST")) {
245 snprintf(procname, sizeof(procname),
246 "/proc/fs/lustre/mdt/%s/rmtacl_info", argv[3]);
247 fd = open(procname, O_WRONLY);
249 fprintf(stderr, "open %s failed: %s\n",
250 procname, strerror(errno));
255 buflen = offsetof(struct rmtacl_downcall_data,
256 add_buf[data->add_buflen]);
257 rc = write(fd, data, buflen);
260 fprintf(stderr, "write %s len %d return %d: %s\n",
261 procname, buflen, rc, strerror(errno));