1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (C) 2004, 2005 Cluster File Systems, Inc.
6 * Author: Lai Siyao <lsy@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.
24 #define DEBUG_SUBSYSTEM S_MDS
27 #include <linux/version.h>
28 #include <asm/uaccess.h>
29 #include <linux/file.h>
30 #include <linux/kmod.h>
31 #include <linux/random.h>
33 #include <linux/obd.h>
34 #include <linux/lustre_mds.h>
35 #include <linux/lustre_fsfilt.h>
36 #include <linux/lustre_sec.h>
38 #include "mds_internal.h"
40 static struct ptlrpc_thread mds_eck_thread;
42 static struct thread_ctl {
43 struct completion ctl_starting;
44 struct completion ctl_finishing;
47 static LIST_HEAD(mds_capa_key_list);
48 static LIST_HEAD(mds_expired_capa_keys);
49 static spinlock_t mds_capa_lock; /* protect capa and capa key */
50 struct timer_list mds_eck_timer;
52 #define CUR_MDS_CAPA_KEY(mds) mds->mds_capa_keys[mds->mds_capa_key_idx]
53 #define CUR_CAPA_KEY(mds) CUR_MDS_CAPA_KEY(mds).k_key
54 #define CUR_CAPA_KEY_ID(mds) CUR_MDS_CAPA_KEY(mds).k_key->lk_keyid
55 #define CUR_CAPA_KEY_EXPIRY(mds) expiry_to_jiffies(CUR_CAPA_KEY(mds)->lk_expiry)
56 #define CUR_CAPA_KEY_LIST(mds) CUR_MDS_CAPA_KEY(mds).k_list
58 static int mds_write_capa_key(struct obd_device *obd, int force_sync)
60 struct mds_obd *mds = &obd->u.mds;
61 struct mds_capa_key *keys = mds->mds_capa_keys;
62 struct file *filp = mds->mds_capa_keys_filp;
63 struct lvfs_run_ctxt saved;
68 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
69 for (i = 0; i < 2 && keys[i].k_key; i++) {
70 rc = fsfilt_write_record(obd, filp, keys[i].k_key,
71 sizeof(*keys[i].k_key),
74 CERROR("error writing MDS capa key: rc = %d\n", rc);
78 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
84 mds_capa_key_cmp(struct mds_obd *mds)
86 return capa_key_cmp(mds->mds_capa_keys[0].k_key,
87 mds->mds_capa_keys[1].k_key);
91 do_update_capa_key(struct mds_obd *mds, struct lustre_capa_key *key)
96 if (CUR_CAPA_KEY(mds))
97 keyid = le32_to_cpu(CUR_CAPA_KEY(mds)->lk_keyid) + 1;
98 expiry_rounded = round_expiry(mds->mds_capa_key_timeout);
100 key->lk_mdsid = cpu_to_le32(mds->mds_num);
101 key->lk_keyid = cpu_to_le32(keyid);
102 key->lk_expiry = cpu_to_le64(expiry_rounded);
103 get_random_bytes(key->lk_key, sizeof(key->lk_key));
106 static void list_add_capa_key(struct mds_capa_key *key, struct list_head *head)
108 struct mds_capa_key *tmp;
110 list_for_each_entry_reverse(tmp, head, k_list) {
111 if (key->k_key->lk_expiry > tmp->k_key->lk_expiry) {
112 list_add(&key->k_list, &tmp->k_list);
117 list_add(&key->k_list, head);
120 int mds_read_capa_key(struct obd_device *obd, struct file *file)
123 struct mds_obd *mds = &obd->u.mds;
124 struct lustre_capa_key *key;
125 unsigned long capa_keys_size = file->f_dentry->d_inode->i_size;
129 if (capa_keys_size == 0) {
130 CWARN("%s: initializing new %s\n", obd->obd_name,
131 file->f_dentry->d_name.name);
133 OBD_ALLOC(key, sizeof(*key));
137 do_update_capa_key(mds, key);
139 mds->mds_capa_keys[0].k_key = key;
140 mds->mds_capa_keys[0].k_obd = obd;
141 INIT_LIST_HEAD(&mds->mds_capa_keys[0].k_list);
142 mds->mds_capa_key_idx = 0;
144 rc = mds_write_capa_key(obd, 1);
148 LASSERT(capa_keys_size == sizeof(*key) ||
149 capa_keys_size == 2 * sizeof(*key));
151 while (capa_keys_size > i * sizeof(*key)) {
152 OBD_ALLOC(key, sizeof(*key));
156 rc = fsfilt_read_record(obd, file, key, sizeof(*key),
159 CERROR("error reading MDS %s capa key: %d\n",
160 file->f_dentry->d_name.name, rc);
161 OBD_FREE(key, sizeof(*key));
165 mds->mds_capa_keys[i].k_key = key;
166 mds->mds_capa_keys[i].k_obd = obd;
167 INIT_LIST_HEAD(&mds->mds_capa_keys[i].k_list);
171 mds->mds_capa_key_idx = 0;
172 if (mds->mds_capa_keys[1].k_key && mds_capa_key_cmp(mds) < 0)
173 mds->mds_capa_key_idx = 1;
176 spin_lock(&mds_capa_lock);
177 if (time_before(CUR_CAPA_KEY_EXPIRY(mds), mds_eck_timer.expires)
178 || !timer_pending(&mds_eck_timer))
179 mod_timer(&mds_eck_timer, CUR_CAPA_KEY_EXPIRY(mds));
181 list_add_capa_key(&CUR_MDS_CAPA_KEY(mds), &mds_capa_key_list);
182 spin_unlock(&mds_capa_lock);
187 void mds_capa_keys_cleanup(struct obd_device *obd)
189 struct mds_obd *mds = &obd->u.mds;
192 spin_lock(&mds_capa_lock);
193 if (CUR_CAPA_KEY(mds))
194 list_del_init(&CUR_CAPA_KEY_LIST(mds));
195 spin_unlock(&mds_capa_lock);
197 for (i = 0; i < 2; i++)
198 if (mds->mds_capa_keys[i].k_key)
199 OBD_FREE(mds->mds_capa_keys[i].k_key,
200 sizeof(struct lustre_capa_key));
203 static int mds_set_capa_key(struct obd_device *obd, struct lustre_capa_key *key)
205 struct mds_obd *mds = &obd->u.mds;
209 rc = obd_set_info(mds->mds_dt_exp, strlen("capa_key"), "capa_key",
212 CERROR("obd_set_info capa_key failed: rc = %d\n", rc);
218 mds_update_capa_key(struct obd_device *obd, struct mds_capa_key *mkey,
221 struct mds_obd *mds = &obd->u.mds;
222 int to_update = mds->mds_capa_key_idx ^ 1;
223 struct lustre_capa_key *key = mds->mds_capa_keys[to_update].k_key;
228 LASSERT(mkey != &mds->mds_capa_keys[to_update]);
232 OBD_ALLOC(key, sizeof(*key));
235 mds->mds_capa_keys[to_update].k_key = key;
236 mds->mds_capa_keys[to_update].k_obd = obd;
239 do_update_capa_key(mds, key);
241 keyid = le32_to_cpu(key->lk_keyid);
243 rc = mds_set_capa_key(obd, key);
245 CERROR("error set capa key(id %u), err = %d\n", keyid, rc);
249 CDEBUG(D_INFO, "MDS capa_keyid is %u\n", keyid);
251 rc = mds_write_capa_key(obd, 1);
255 CDEBUG(D_INFO, "wrote capa keyid %u: err = %d\n", keyid, rc);
257 spin_lock(&mds_capa_lock);
258 list_del_init(&CUR_CAPA_KEY_LIST(mds));
259 mds->mds_capa_key_idx = to_update;
260 list_add_capa_key(&CUR_MDS_CAPA_KEY(mds), &mds_capa_key_list);
261 spin_unlock(&mds_capa_lock);
263 /* TODO: update timer here */
268 static inline int have_expired_capa_key(void)
270 struct mds_capa_key *key;
274 spin_lock(&mds_capa_lock);
275 if (!list_empty(&mds_capa_key_list)) {
276 key = list_entry(mds_capa_key_list.next, struct mds_capa_key,
278 expired = time_before(expiry_to_jiffies(key->k_key->lk_expiry),
281 spin_unlock(&mds_capa_lock);
286 static int inline mds_capa_key_check_stop(void)
288 return (mds_eck_thread.t_flags & SVC_STOPPING) ? 1: 0;
291 static int mds_capa_key_thread_main(void *arg)
293 struct thread_ctl *ctl = arg;
298 char name[sizeof(current->comm)];
299 snprintf(name, sizeof(name) - 1, "mds_ck");
300 kportal_daemonize(name);
303 SIGNAL_MASK_LOCK(current, flags);
304 sigfillset(¤t->blocked);
306 SIGNAL_MASK_UNLOCK(current, flags);
309 * letting starting function know, that we are ready and control may be
312 mds_eck_thread.t_flags = SVC_RUNNING;
313 complete(&ctl->ctl_starting);
315 while (!mds_capa_key_check_stop()) {
316 struct l_wait_info lwi = { 0 };
317 struct mds_capa_key *key, *tmp, *next = NULL;
319 l_wait_event(mds_eck_thread.t_ctl_waitq,
320 (have_expired_capa_key() ||
321 mds_capa_key_check_stop()),
324 spin_lock(&mds_capa_lock);
325 list_for_each_entry_safe(key, tmp, &mds_capa_key_list, k_list) {
326 if (time_after(expiry_to_jiffies(key->k_key->lk_expiry),
332 spin_unlock(&mds_capa_lock);
334 CDEBUG(D_INFO, "mds capa key expired, wake up updating "
335 "thread: mds #%u, key #%u\n",
336 le32_to_cpu(key->k_key->lk_mdsid),
337 le32_to_cpu(key->k_key->lk_keyid));
339 mds_update_capa_key(key->k_obd, key, 1);
340 spin_lock(&mds_capa_lock);
344 mod_timer(&mds_eck_timer,
345 expiry_to_jiffies(next->k_key->lk_expiry));
346 spin_unlock(&mds_capa_lock);
349 mds_eck_thread.t_flags = SVC_STOPPED;
351 /* this is SMP-safe way to finish thread. */
352 complete_and_exit(&ctl->ctl_finishing, 0);
356 void mds_capa_key_timer_callback(unsigned long unused)
359 wake_up(&mds_eck_thread.t_ctl_waitq);
363 int mds_capa_key_start_thread(void)
368 LASSERT(mds_eck_thread.t_flags == 0);
369 init_completion(&mds_eck_ctl.ctl_starting);
370 init_completion(&mds_eck_ctl.ctl_finishing);
371 init_waitqueue_head(&mds_eck_thread.t_ctl_waitq);
372 spin_lock_init(&mds_capa_lock);
374 rc = kernel_thread(mds_capa_key_thread_main, &mds_eck_ctl,
375 (CLONE_VM | CLONE_FILES));
377 CERROR("cannot start capa key thread, "
382 wait_for_completion(&mds_eck_ctl.ctl_starting);
383 LASSERT(mds_eck_thread.t_flags == SVC_RUNNING);
387 void mds_capa_key_stop_thread(void)
390 mds_eck_thread.t_flags = SVC_STOPPING;
391 wake_up(&mds_eck_thread.t_ctl_waitq);
392 wait_for_completion(&mds_eck_ctl.ctl_finishing);
393 LASSERT(mds_eck_thread.t_flags == SVC_STOPPED);
394 mds_eck_thread.t_flags = 0;
398 int mds_pack_capa(struct obd_device *obd, struct mds_body *req_body,
399 struct lustre_capa *req_capa, struct lustre_msg *repmsg,
400 int *offset, struct mds_body *body)
402 struct mds_obd *mds = &obd->u.mds;
403 struct lustre_capa *capa;
404 struct obd_capa *ocapa;
405 __u8 key[CAPA_KEY_LEN]; /* key */
409 if (mds->mds_capa_stat == 0) {
411 RETURN(0); /* capability is disabled */
414 if (OBD_FAIL_CHECK(OBD_FAIL_MDS_PACK_CAPA))
418 /* capa renewal, check capa op against open mode */
419 struct mds_file_data *mfd;
422 mfd = mds_handle2mfd(&req_body->handle);
424 CERROR("no handle for capa renewal ino "LPD64
425 ": cookie "LPX64"\n",
426 req_capa->lc_ino, req_body->handle.cookie);
430 mode = accmode(mfd->mfd_mode);
431 if (!(req_capa->lc_op & mode)) {
432 CERROR("invalid capa to renew ino "LPD64
433 ": op %d mismatch with mode %d\n",
434 req_capa->lc_ino, req_capa->lc_op, mfd->mfd_mode);
439 LASSERT(repmsg->buflens[*offset] == sizeof(*capa));
440 capa = lustre_msg_buf(repmsg, (*offset)++, sizeof(*capa));
441 LASSERT(capa != NULL);
443 ocapa = capa_get(req_capa->lc_uid, req_capa->lc_op, req_capa->lc_mdsid,
444 req_capa->lc_ino, MDS_CAPA, NULL, NULL, NULL);
446 expired = capa_is_to_expire(ocapa);
448 capa_dup(capa, ocapa);
449 capa_put(ocapa, MDS_CAPA);
452 capa_put(ocapa, MDS_CAPA);
455 memcpy(capa, req_capa, sizeof(*capa));
457 spin_lock(&mds_capa_lock);
458 capa->lc_keyid = le32_to_cpu(CUR_CAPA_KEY_ID(mds));
459 capa->lc_expiry = round_expiry(mds->mds_capa_timeout);
460 if (mds->mds_capa_timeout < CAPA_EXPIRY)
461 capa->lc_flags |= CAPA_FL_NOROUND;
462 memcpy(key, CUR_CAPA_KEY(mds)->lk_key, sizeof(key));
463 spin_unlock(&mds_capa_lock);
465 capa_hmac(mds->mds_capa_hmac, key, capa);
467 rc = capa_renew(capa, MDS_CAPA);
470 body->valid |= OBD_MD_CAPA;