4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21 * CA 95054 USA or visit www.sun.com if you need additional information or
27 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Use is subject to license terms.
30 * Copyright (c) 2012, 2013, Intel Corporation.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
36 * lustre/mdt/mdt_capa.c
38 * Lustre Metadata Target (mdt) capability key read/write/update.
40 * Author: Lai Siyao <lsy@clusterfs.com>
43 #define DEBUG_SUBSYSTEM S_MDS
45 #include "mdt_internal.h"
47 static inline void set_capa_key_expiry(struct mdt_device *mdt)
49 mdt->mdt_ck_expiry = jiffies + mdt->mdt_ck_timeout * HZ;
52 static void make_capa_key(struct lustre_capa_key *key,
53 mdsno_t mdsnum, int keyid)
56 key->lk_keyid = keyid + 1;
57 cfs_get_random_bytes(key->lk_key, sizeof(key->lk_key));
60 static inline void lck_cpu_to_le(struct lustre_capa_key *tgt,
61 struct lustre_capa_key *src)
63 tgt->lk_seq = cpu_to_le64(src->lk_seq);
64 tgt->lk_keyid = cpu_to_le32(src->lk_keyid);
65 tgt->lk_padding = cpu_to_le32(src->lk_padding);
66 memcpy(tgt->lk_key, src->lk_key, sizeof(src->lk_key));
69 static inline void lck_le_to_cpu(struct lustre_capa_key *tgt,
70 struct lustre_capa_key *src)
72 tgt->lk_seq = le64_to_cpu(src->lk_seq);
73 tgt->lk_keyid = le32_to_cpu(src->lk_keyid);
74 tgt->lk_padding = le32_to_cpu(src->lk_padding);
75 memcpy(tgt->lk_key, src->lk_key, sizeof(src->lk_key));
78 static int write_capa_keys(const struct lu_env *env,
79 struct mdt_device *mdt,
80 struct lustre_capa_key *keys)
82 struct mdt_thread_info *mti;
83 struct lustre_capa_key *tmp;
88 mti = lu_context_key_get(&env->le_ctx, &mdt_thread_key);
89 th = dt_trans_create(env, mdt->mdt_bottom);
93 rc = dt_declare_record_write(env, mdt->mdt_ck_obj,
94 mdt_buf_const(env, NULL,
95 sizeof(*tmp) * 3), 0, th);
99 rc = dt_trans_start_local(env, mdt->mdt_bottom, th);
103 tmp = &mti->mti_capa_key;
105 for (i = 0; i < 2; i++) {
106 lck_cpu_to_le(tmp, &keys[i]);
108 rc = dt_record_write(env, mdt->mdt_ck_obj,
109 mdt_buf_const(env, tmp, sizeof(*tmp)),
116 dt_trans_stop(env, mdt->mdt_bottom, th);
118 CDEBUG(D_INFO, "write capability keys rc = %d:\n", rc);
122 static int read_capa_keys(const struct lu_env *env,
123 struct mdt_device *mdt,
124 struct lustre_capa_key *keys)
126 struct mdt_thread_info *mti;
127 struct lustre_capa_key *tmp;
131 mti = lu_context_key_get(&env->le_ctx, &mdt_thread_key);
132 tmp = &mti->mti_capa_key;
134 for (i = 0; i < 2; i++) {
135 rc = dt_record_read(env, mdt->mdt_ck_obj,
136 mdt_buf(env, tmp, sizeof(*tmp)), &off);
140 lck_le_to_cpu(&keys[i], tmp);
141 DEBUG_CAPA_KEY(D_SEC, &keys[i], "read");
147 int mdt_capa_keys_init(const struct lu_env *env, struct mdt_device *mdt)
149 struct lustre_capa_key *keys = mdt->mdt_capa_keys;
150 struct mdt_thread_info *mti;
151 struct dt_object *obj;
158 mdsnum = mdt_seq_site(mdt)->ss_node_id;
160 mti = lu_context_key_get(&env->le_ctx, &mdt_thread_key);
161 LASSERT(mti != NULL);
162 la = &mti->mti_attr.ma_attr;
164 obj = mdt->mdt_ck_obj;
165 rc = obj->do_ops->do_attr_get(env, mdt->mdt_ck_obj, la, BYPASS_CAPA);
169 size = (unsigned long)la->la_size;
173 for (i = 0; i < 2; i++) {
174 make_capa_key(&keys[i], mdsnum, i);
175 DEBUG_CAPA_KEY(D_SEC, &keys[i], "initializing");
178 rc = write_capa_keys(env, mdt, keys);
180 CERROR("error writing MDS %s: rc %d\n", CAPA_KEYS, rc);
184 rc = read_capa_keys(env, mdt, keys);
186 CERROR("error reading MDS %s: rc %d\n", CAPA_KEYS, rc);
190 set_capa_key_expiry(mdt);
191 cfs_timer_arm(&mdt->mdt_ck_timer, mdt->mdt_ck_expiry);
192 CDEBUG(D_SEC, "mds_ck_timer %lu\n", mdt->mdt_ck_expiry);
196 void mdt_ck_timer_callback(unsigned long castmeharder)
198 struct mdt_device *mdt = (struct mdt_device *)castmeharder;
199 struct ptlrpc_thread *thread = &mdt->mdt_ck_thread;
202 thread_add_flags(thread, SVC_EVENT);
203 wake_up(&thread->t_ctl_waitq);
207 static int mdt_ck_thread_main(void *args)
209 struct mdt_device *mdt = args;
210 struct ptlrpc_thread *thread = &mdt->mdt_ck_thread;
211 struct lustre_capa_key *bkey = &mdt->mdt_capa_keys[0],
212 *rkey = &mdt->mdt_capa_keys[1];
213 struct lustre_capa_key *tmp;
215 struct mdt_thread_info *info;
216 struct md_device *next;
217 struct l_wait_info lwi = { 0 };
225 thread_set_flags(thread, SVC_RUNNING);
226 wake_up(&thread->t_ctl_waitq);
228 rc = lu_env_init(&env, LCT_MD_THREAD|LCT_REMEMBER|LCT_NOREF);
232 thread->t_env = &env;
233 env.le_ctx.lc_thread = thread;
234 env.le_ctx.lc_cookie = 0x1;
236 info = lu_context_key_get(&env.le_ctx, &mdt_thread_key);
237 LASSERT(info != NULL);
239 tmp = &info->mti_capa_key;
240 mdsnum = mdt_seq_site(mdt)->ss_node_id;
242 l_wait_event(thread->t_ctl_waitq,
243 thread_is_stopping(thread) ||
244 thread_is_event(thread),
247 if (thread_is_stopping(thread))
249 thread_clear_flags(thread, SVC_EVENT);
251 if (cfs_time_before(cfs_time_current(), mdt->mdt_ck_expiry))
255 make_capa_key(tmp, mdsnum, rkey->lk_keyid);
257 next = mdt->mdt_child;
258 rc = next->md_ops->mdo_update_capa_key(&env, next, tmp);
260 spin_lock(&capa_lock);
263 spin_unlock(&capa_lock);
265 rc = write_capa_keys(&env, mdt, mdt->mdt_capa_keys);
267 spin_lock(&capa_lock);
269 memset(bkey, 0, sizeof(*bkey));
270 spin_unlock(&capa_lock);
272 set_capa_key_expiry(mdt);
273 DEBUG_CAPA_KEY(D_SEC, rkey, "new");
277 DEBUG_CAPA_KEY(D_ERROR, rkey, "update failed for");
278 /* next retry is in 300 sec */
279 mdt->mdt_ck_expiry = jiffies + 300 * HZ;
282 cfs_timer_arm(&mdt->mdt_ck_timer, mdt->mdt_ck_expiry);
283 CDEBUG(D_SEC, "mdt_ck_timer %lu\n", mdt->mdt_ck_expiry);
287 thread_set_flags(thread, SVC_STOPPED);
288 wake_up(&thread->t_ctl_waitq);
292 int mdt_ck_thread_start(struct mdt_device *mdt)
294 struct ptlrpc_thread *thread = &mdt->mdt_ck_thread;
295 struct task_struct *task;
297 init_waitqueue_head(&thread->t_ctl_waitq);
298 task = kthread_run(mdt_ck_thread_main, mdt, "mdt_ck");
300 CERROR("cannot start mdt_ck thread, rc = %ld\n", PTR_ERR(task));
301 return PTR_ERR(task);
304 l_wait_condition(thread->t_ctl_waitq, thread_is_running(thread));
308 void mdt_ck_thread_stop(struct mdt_device *mdt)
310 struct ptlrpc_thread *thread = &mdt->mdt_ck_thread;
312 if (!thread_is_running(thread))
315 thread_set_flags(thread, SVC_STOPPING);
316 wake_up(&thread->t_ctl_waitq);
317 l_wait_condition(thread->t_ctl_waitq, thread_is_stopped(thread));