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.
5 * Author: Lai Siyao <lsy@clusterfs.com>
6 * Author: Fan Yong <fanyong@clusterfs.com>
8 * This file is part of Lustre, http://www.lustre.org.
10 * Lustre is free software; you can redistribute it and/or
11 * modify it under the terms of version 2 of the GNU General Public
12 * License as published by the Free Software Foundation.
14 * Lustre is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with Lustre; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 #define DEBUG_SUBSYSTEM S_MDS
29 #include <linux/config.h>
30 #include <linux/module.h>
31 #include <linux/kernel.h>
33 #include <linux/kmod.h>
34 #include <linux/string.h>
35 #include <linux/stat.h>
36 #include <linux/errno.h>
37 #include <linux/version.h>
38 #include <linux/unistd.h>
39 #include <asm/system.h>
40 #include <asm/uaccess.h>
42 #include <linux/stat.h>
43 #include <asm/uaccess.h>
44 #include <linux/slab.h>
45 #include <asm/segment.h>
47 #include <libcfs/kp30.h>
49 #include <obd_class.h>
50 #include <obd_support.h>
51 #include <lustre_net.h>
52 #include <lustre_import.h>
53 #include <lustre_dlm.h>
54 #include <lustre_lib.h>
55 #include <lustre_ucache.h>
57 #include "mdt_internal.h"
59 #define MAX_CMD_LEN 256
61 static void mdt_rmtacl_entry_init(struct upcall_cache_entry *entry, void *args)
63 struct rmtacl_upcall_data *data = args;
64 struct mdt_rmtacl *acl = &entry->u.acl;
67 /* we use address of this cache entry as handle */
68 acl->ra_handle = (__u32)entry;
69 OBD_ALLOC(cmd, strlen(data->aud_cmd) + 1);
71 return; /* upcall will fail later! */
73 strcpy(cmd, data->aud_cmd);
74 entry->u.acl.ra_cmd = cmd;
77 static void mdt_rmtacl_entry_free(struct upcall_cache *cache,
78 struct upcall_cache_entry *entry)
80 struct mdt_rmtacl *acl = &entry->u.acl;
84 len = strlen(acl->ra_cmd) + 1;
85 OBD_FREE(acl->ra_cmd, len);
89 len = strlen(acl->ra_buf) + 1;
90 OBD_FREE(acl->ra_buf, len);
94 static int mdt_rmtacl_upcall_compare(struct upcall_cache *cache,
95 struct upcall_cache_entry *entry,
96 __u64 key, void *args)
98 struct rmtacl_upcall_data *data = args;
100 LASSERT(entry && data);
101 LASSERT(entry->u.acl.ra_cmd && data->aud_cmd);
102 return strncmp(entry->u.acl.ra_cmd, data->aud_cmd, MAX_CMD_LEN);
105 static int mdt_rmtacl_downcall_compare(struct upcall_cache *cache,
106 struct upcall_cache_entry *entry,
107 __u64 key, void *args)
109 struct rmtacl_downcall_data *data = args;
111 return entry->u.acl.ra_handle - data->add_handle;
114 static int mdt_rmtacl_do_upcall(struct upcall_cache *cache,
115 struct upcall_cache_entry *entry)
117 struct mdt_rmtacl *acl = &entry->u.acl;
118 char handle[20] = "";
119 char keystr[20] = "";
121 [0] = cache->uc_upcall,
122 [1] = cache->uc_name,
130 [1] = "PATH=/bin:/usr/bin:/sbin:/usr/sbin",
139 snprintf(keystr, sizeof(keystr), LPU64, entry->ue_key);
140 snprintf(handle, sizeof(handle), "%u", acl->ra_handle);
142 LASSERTF(strcmp(cache->uc_upcall, "NONE"), "no upcall set!");
144 CDEBUG(D_INFO, "%s: remote acl upcall %s %s %s %s %s\n",
145 cache->uc_name, argv[0], argv[1], argv[2], argv[3], argv[4]);
147 rc = USERMODEHELPER(argv[0], argv, envp);
149 CERROR("%s: error invoking upcall %s %s %s %s %s: rc %d; "
150 "check /proc/fs/lustre/mdt/%s/rmtacl_upcall\n",
151 cache->uc_name, argv[0], argv[1], argv[2], argv[3],
152 argv[4], rc, cache->uc_name);
154 CDEBUG(D_HA, "%s: invoked upcall %s %s %s %s %s\n",
155 cache->uc_name, argv[0], argv[1], argv[2], argv[3],
162 static int mdt_rmtacl_parse_downcall(struct upcall_cache *cache,
163 struct upcall_cache_entry *entry,
166 struct mdt_rmtacl *acl = &entry->u.acl;
167 struct rmtacl_downcall_data *data;
172 data = (struct rmtacl_downcall_data *)args;
175 len = strlen(data->add_buf) + 1;
180 memcpy(buf, data->add_buf, len);
183 CDEBUG(D_OTHER, "parse mdt acl@%p: %s %s\n",
184 acl, acl->ra_cmd, acl->ra_buf);
189 struct upcall_cache_ops mdt_rmtacl_upcall_cache_ops = {
190 .init_entry = mdt_rmtacl_entry_init,
191 .free_entry = mdt_rmtacl_entry_free,
192 .upcall_compare = mdt_rmtacl_upcall_compare,
193 .downcall_compare = mdt_rmtacl_downcall_compare,
194 .do_upcall = mdt_rmtacl_do_upcall,
195 .parse_downcall = mdt_rmtacl_parse_downcall,
198 int mdt_rmtacl_upcall(struct mdt_thread_info *info, unsigned long key,
199 char *cmd, char *buf, int buflen)
201 struct ptlrpc_request *req = mdt_info_req(info);
202 struct obd_device *obd = req->rq_export->exp_obd;
203 struct mdt_device *mdt = info->mti_mdt;
204 struct lvfs_ucred uc;
205 struct lvfs_run_ctxt saved;
206 struct rmtacl_upcall_data data;
207 struct upcall_cache_entry *entry;
212 OBD_ALLOC(tmp, PAGE_SIZE);
218 uc.luc_uid = info->mti_uc.mu_uid;
219 uc.luc_gid = info->mti_uc.mu_gid;
220 uc.luc_fsuid = info->mti_uc.mu_fsuid;
221 uc.luc_fsgid = info->mti_uc.mu_fsgid;
222 uc.luc_cap = info->mti_uc.mu_cap;
223 uc.luc_umask = info->mti_uc.mu_umask;
224 uc.luc_ginfo = info->mti_uc.mu_ginfo;
225 uc.luc_identity = info->mti_uc.mu_identity;
227 push_ctxt(&saved, &obd->obd_lvfs_ctxt, &uc);
228 entry = upcall_cache_get_entry(mdt->mdt_rmtacl_cache, (__u64)key,
230 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, &uc);
233 GOTO(out, rc = PTR_ERR(entry));
235 if (buflen <= strlen(entry->u.acl.ra_buf))
236 GOTO(out, rc = -EFAULT);
238 memcpy(buf, entry->u.acl.ra_buf, strlen(entry->u.acl.ra_buf));
239 /* remote acl operation expire at once! */
240 UC_CACHE_SET_EXPIRED(entry);
241 upcall_cache_put_entry(mdt->mdt_rmtacl_cache, entry);
245 sprintf(buf, "server processing error: %d\n", rc);
246 OBD_FREE(tmp, PAGE_SIZE);