1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
6 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 only,
10 * as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License version 2 for more details (a copy is included
16 * in the LICENSE file that accompanied this code).
18 * You should have received a copy of the GNU General Public License
19 * version 2 along with this program; If not, see
20 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
22 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23 * CA 95054 USA or visit www.sun.com if you need additional information or
29 * Copyright 2008 Sun Microsystems, Inc. All rights reserved
30 * Use is subject to license terms.
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>
44 # define EXPORT_SYMTAB
46 #define DEBUG_SUBSYSTEM S_MDS
48 #include "mdt_internal.h"
50 static inline void set_capa_key_expiry(struct mdt_device *mdt)
52 mdt->mdt_ck_expiry = jiffies + mdt->mdt_ck_timeout * HZ;
55 static void make_capa_key(struct lustre_capa_key *key,
56 mdsno_t mdsnum, int keyid)
58 key->lk_mdsid = mdsnum;
59 key->lk_keyid = keyid + 1;
60 ll_get_random_bytes(key->lk_key, sizeof(key->lk_key));
64 MDT_TXN_CAPA_KEYS_WRITE_CREDITS = 1
67 static inline void lck_cpu_to_le(struct lustre_capa_key *tgt,
68 struct lustre_capa_key *src)
70 tgt->lk_mdsid = cpu_to_le64(src->lk_mdsid);
71 tgt->lk_keyid = cpu_to_le32(src->lk_keyid);
72 tgt->lk_padding = cpu_to_le32(src->lk_padding);
73 memcpy(tgt->lk_key, src->lk_key, sizeof(src->lk_key));
76 static inline void lck_le_to_cpu(struct lustre_capa_key *tgt,
77 struct lustre_capa_key *src)
79 tgt->lk_mdsid = le64_to_cpu(src->lk_mdsid);
80 tgt->lk_keyid = le32_to_cpu(src->lk_keyid);
81 tgt->lk_padding = le32_to_cpu(src->lk_padding);
82 memcpy(tgt->lk_key, src->lk_key, sizeof(src->lk_key));
85 static int write_capa_keys(const struct lu_env *env,
86 struct mdt_device *mdt,
87 struct lustre_capa_key *keys)
89 struct mdt_thread_info *mti;
90 struct lustre_capa_key *tmp;
95 mti = lu_context_key_get(&env->le_ctx, &mdt_thread_key);
97 th = mdt_trans_start(env, mdt, MDT_TXN_CAPA_KEYS_WRITE_CREDITS);
101 tmp = &mti->mti_capa_key;
103 for (i = 0; i < 2; i++) {
104 lck_cpu_to_le(tmp, &keys[i]);
106 rc = mdt_record_write(env, mdt->mdt_ck_obj,
107 mdt_buf_const(env, tmp, sizeof(*tmp)),
113 mdt_trans_stop(env, mdt, th);
115 CDEBUG(D_INFO, "write capability keys rc = %d:\n", rc);
119 static int read_capa_keys(const struct lu_env *env,
120 struct mdt_device *mdt,
121 struct lustre_capa_key *keys)
123 struct mdt_thread_info *mti;
124 struct lustre_capa_key *tmp;
128 mti = lu_context_key_get(&env->le_ctx, &mdt_thread_key);
129 tmp = &mti->mti_capa_key;
131 for (i = 0; i < 2; i++) {
132 rc = mdt_record_read(env, mdt->mdt_ck_obj,
133 mdt_buf(env, tmp, sizeof(*tmp)), &off);
137 lck_le_to_cpu(&keys[i], tmp);
138 DEBUG_CAPA_KEY(D_SEC, &keys[i], "read");
144 int mdt_capa_keys_init(const struct lu_env *env, struct mdt_device *mdt)
146 struct lustre_capa_key *keys = mdt->mdt_capa_keys;
147 struct mdt_thread_info *mti;
148 struct dt_object *obj;
155 mdsnum = mdt_md_site(mdt)->ms_node_id;
157 mti = lu_context_key_get(&env->le_ctx, &mdt_thread_key);
158 LASSERT(mti != NULL);
159 la = &mti->mti_attr.ma_attr;
161 obj = mdt->mdt_ck_obj;
162 rc = obj->do_ops->do_attr_get(env, mdt->mdt_ck_obj, la, BYPASS_CAPA);
166 size = (unsigned long)la->la_size;
170 for (i = 0; i < 2; i++) {
171 make_capa_key(&keys[i], mdsnum, i);
172 DEBUG_CAPA_KEY(D_SEC, &keys[i], "initializing");
175 rc = write_capa_keys(env, mdt, keys);
177 CERROR("error writing MDS %s: rc %d\n", CAPA_KEYS, rc);
181 rc = read_capa_keys(env, mdt, keys);
183 CERROR("error reading MDS %s: rc %d\n", CAPA_KEYS, rc);
187 set_capa_key_expiry(mdt);
188 cfs_timer_arm(&mdt->mdt_ck_timer, mdt->mdt_ck_expiry);
189 CDEBUG(D_SEC, "mds_ck_timer %lu\n", mdt->mdt_ck_expiry);
193 void mdt_ck_timer_callback(unsigned long castmeharder)
195 struct mdt_device *mdt = (struct mdt_device *)castmeharder;
196 struct ptlrpc_thread *thread = &mdt->mdt_ck_thread;
199 thread->t_flags |= SVC_EVENT;
200 cfs_waitq_signal(&thread->t_ctl_waitq);
204 static int mdt_ck_thread_main(void *args)
206 struct mdt_device *mdt = args;
207 struct ptlrpc_thread *thread = &mdt->mdt_ck_thread;
208 struct lustre_capa_key *bkey = &mdt->mdt_capa_keys[0],
209 *rkey = &mdt->mdt_capa_keys[1];
210 struct lustre_capa_key *tmp;
212 struct mdt_thread_info *info;
213 struct md_device *next;
214 struct l_wait_info lwi = { 0 };
219 ptlrpc_daemonize("mdt_ck");
222 thread->t_flags = SVC_RUNNING;
223 cfs_waitq_signal(&thread->t_ctl_waitq);
225 rc = lu_env_init(&env, NULL, LCT_MD_THREAD);
229 thread->t_env = &env;
230 env.le_ctx.lc_thread = thread;
232 info = lu_context_key_get(&env.le_ctx, &mdt_thread_key);
233 LASSERT(info != NULL);
235 tmp = &info->mti_capa_key;
236 mdsnum = mdt_md_site(mdt)->ms_node_id;
238 l_wait_event(thread->t_ctl_waitq,
239 thread->t_flags & (SVC_STOPPING | SVC_EVENT),
242 if (thread->t_flags & SVC_STOPPING)
244 thread->t_flags &= ~SVC_EVENT;
246 if (cfs_time_before(cfs_time_current(), mdt->mdt_ck_expiry))
250 make_capa_key(tmp, mdsnum, rkey->lk_keyid);
252 next = mdt->mdt_child;
253 rc = next->md_ops->mdo_update_capa_key(&env, next, tmp);
255 spin_lock(&capa_lock);
258 spin_unlock(&capa_lock);
260 rc = write_capa_keys(&env, mdt, mdt->mdt_capa_keys);
262 spin_lock(&capa_lock);
264 memset(bkey, 0, sizeof(*bkey));
265 spin_unlock(&capa_lock);
267 set_capa_key_expiry(mdt);
268 DEBUG_CAPA_KEY(D_SEC, rkey, "new");
272 DEBUG_CAPA_KEY(D_ERROR, rkey, "update failed for");
273 /* next retry is in 300 sec */
274 mdt->mdt_ck_expiry = jiffies + 300 * HZ;
277 cfs_timer_arm(&mdt->mdt_ck_timer, mdt->mdt_ck_expiry);
278 CDEBUG(D_SEC, "mdt_ck_timer %lu\n", mdt->mdt_ck_expiry);
282 thread->t_flags = SVC_STOPPED;
283 cfs_waitq_signal(&thread->t_ctl_waitq);
287 int mdt_ck_thread_start(struct mdt_device *mdt)
289 struct ptlrpc_thread *thread = &mdt->mdt_ck_thread;
292 cfs_waitq_init(&thread->t_ctl_waitq);
293 rc = cfs_kernel_thread(mdt_ck_thread_main, mdt,
294 (CLONE_VM | CLONE_FILES));
296 CERROR("cannot start mdt_ck thread, rc = %d\n", rc);
300 cfs_wait_event(thread->t_ctl_waitq, thread->t_flags & SVC_RUNNING);
304 void mdt_ck_thread_stop(struct mdt_device *mdt)
306 struct ptlrpc_thread *thread = &mdt->mdt_ck_thread;
308 if (!(thread->t_flags & SVC_RUNNING))
311 thread->t_flags = SVC_STOPPING;
312 cfs_waitq_signal(&thread->t_ctl_waitq);
313 cfs_wait_event(thread->t_ctl_waitq, thread->t_flags & SVC_STOPPED);