1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * lustre/mdt/mdt_capa.c
5 * Lustre Metadata Target (mdt) capability key read/write/update.
7 * Copyright (C) 2005 Cluster File Systems, Inc.
8 * Author: Lai Siyao <lsy@clusterfs.com>
10 * This file is part of the Lustre file system, http://www.lustre.org
11 * Lustre is a trademark of Cluster File Systems, Inc.
13 * You may have signed or agreed to another license before downloading
14 * this software. If so, you are bound by the terms and conditions
15 * of that agreement, and the following does not apply to you. See the
16 * LICENSE file included with this distribution for more information.
18 * If you did not agree to a different license, then this copy of Lustre
19 * is open source software; you can redistribute it and/or modify it
20 * under the terms of version 2 of the GNU General Public License as
21 * published by the Free Software Foundation.
23 * In either case, Lustre is distributed in the hope that it will be
24 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
25 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * license text for more details.
30 # define EXPORT_SYMTAB
32 #define DEBUG_SUBSYSTEM S_MDS
34 #include "mdt_internal.h"
36 static inline void set_capa_key_expiry(struct mdt_device *mdt)
38 mdt->mdt_ck_expiry = jiffies + mdt->mdt_ck_timeout * HZ;
41 static void make_capa_key(struct lustre_capa_key *key,
42 mdsno_t mdsnum, int keyid)
44 key->lk_mdsid = mdsnum;
45 key->lk_keyid = keyid + 1;
46 ll_get_random_bytes(key->lk_key, sizeof(key->lk_key));
50 MDT_TXN_CAPA_KEYS_WRITE_CREDITS = 1
53 static inline void lck_cpu_to_le(struct lustre_capa_key *tgt,
54 struct lustre_capa_key *src)
56 tgt->lk_mdsid = cpu_to_le64(src->lk_mdsid);
57 tgt->lk_keyid = cpu_to_le32(src->lk_keyid);
58 tgt->lk_padding = cpu_to_le32(src->lk_padding);
59 memcpy(tgt->lk_key, src->lk_key, sizeof(src->lk_key));
62 static inline void lck_le_to_cpu(struct lustre_capa_key *tgt,
63 struct lustre_capa_key *src)
65 tgt->lk_mdsid = le64_to_cpu(src->lk_mdsid);
66 tgt->lk_keyid = le32_to_cpu(src->lk_keyid);
67 tgt->lk_padding = le32_to_cpu(src->lk_padding);
68 memcpy(tgt->lk_key, src->lk_key, sizeof(src->lk_key));
71 static int write_capa_keys(const struct lu_env *env,
72 struct mdt_device *mdt,
73 struct lustre_capa_key *keys)
75 struct mdt_thread_info *mti;
76 struct lustre_capa_key *tmp;
81 mti = lu_context_key_get(&env->le_ctx, &mdt_thread_key);
83 th = mdt_trans_start(env, mdt, MDT_TXN_CAPA_KEYS_WRITE_CREDITS);
87 tmp = &mti->mti_capa_key;
89 for (i = 0; i < 2; i++) {
90 lck_cpu_to_le(tmp, &keys[i]);
92 rc = mdt_record_write(env, mdt->mdt_ck_obj,
93 mdt_buf_const(env, tmp, sizeof(*tmp)),
99 mdt_trans_stop(env, mdt, th);
101 CDEBUG(D_INFO, "write capability keys rc = %d:\n", rc);
105 static int read_capa_keys(const struct lu_env *env,
106 struct mdt_device *mdt,
107 struct lustre_capa_key *keys)
109 struct mdt_thread_info *mti;
110 struct lustre_capa_key *tmp;
114 mti = lu_context_key_get(&env->le_ctx, &mdt_thread_key);
115 tmp = &mti->mti_capa_key;
117 for (i = 0; i < 2; i++) {
118 rc = mdt_record_read(env, mdt->mdt_ck_obj,
119 mdt_buf(env, tmp, sizeof(*tmp)), &off);
123 lck_le_to_cpu(&keys[i], tmp);
124 DEBUG_CAPA_KEY(D_SEC, &keys[i], "read");
130 int mdt_capa_keys_init(const struct lu_env *env, struct mdt_device *mdt)
132 struct lustre_capa_key *keys = mdt->mdt_capa_keys;
133 struct mdt_thread_info *mti;
134 struct dt_object *obj;
141 mdsnum = mdt->mdt_md_dev.md_lu_dev.ld_site->ls_node_id;
143 mti = lu_context_key_get(&env->le_ctx, &mdt_thread_key);
144 LASSERT(mti != NULL);
145 la = &mti->mti_attr.ma_attr;
147 obj = mdt->mdt_ck_obj;
148 rc = obj->do_ops->do_attr_get(env, mdt->mdt_ck_obj, la, BYPASS_CAPA);
152 size = (unsigned long)la->la_size;
156 for (i = 0; i < 2; i++) {
157 make_capa_key(&keys[i], mdsnum, i);
158 DEBUG_CAPA_KEY(D_SEC, &keys[i], "initializing");
161 rc = write_capa_keys(env, mdt, keys);
163 CERROR("error writing MDS %s: rc %d\n", CAPA_KEYS, rc);
167 rc = read_capa_keys(env, mdt, keys);
169 CERROR("error reading MDS %s: rc %d\n", CAPA_KEYS, rc);
173 set_capa_key_expiry(mdt);
174 cfs_timer_arm(&mdt->mdt_ck_timer, mdt->mdt_ck_expiry);
175 CDEBUG(D_SEC, "mds_ck_timer %lu\n", mdt->mdt_ck_expiry);
179 void mdt_ck_timer_callback(unsigned long castmeharder)
181 struct mdt_device *mdt = (struct mdt_device *)castmeharder;
182 struct ptlrpc_thread *thread = &mdt->mdt_ck_thread;
185 thread->t_flags |= SVC_EVENT;
186 cfs_waitq_signal(&thread->t_ctl_waitq);
190 static int mdt_ck_thread_main(void *args)
192 struct mdt_device *mdt = args;
193 struct ptlrpc_thread *thread = &mdt->mdt_ck_thread;
194 struct lustre_capa_key *bkey = &mdt->mdt_capa_keys[0],
195 *rkey = &mdt->mdt_capa_keys[1];
196 struct lustre_capa_key *tmp;
198 struct mdt_thread_info *info;
199 struct md_device *next;
200 struct l_wait_info lwi = { 0 };
205 ptlrpc_daemonize("mdt_ck");
208 thread->t_flags = SVC_RUNNING;
209 cfs_waitq_signal(&thread->t_ctl_waitq);
211 rc = lu_env_init(&env, NULL, LCT_MD_THREAD);
215 thread->t_env = &env;
216 env.le_ctx.lc_thread = thread;
218 info = lu_context_key_get(&env.le_ctx, &mdt_thread_key);
219 LASSERT(info != NULL);
221 tmp = &info->mti_capa_key;
222 mdsnum = mdt->mdt_md_dev.md_lu_dev.ld_site->ls_node_id;
224 l_wait_event(thread->t_ctl_waitq,
225 thread->t_flags & (SVC_STOPPING | SVC_EVENT),
228 if (thread->t_flags & SVC_STOPPING)
230 thread->t_flags &= ~SVC_EVENT;
232 if (cfs_time_before(cfs_time_current(), mdt->mdt_ck_expiry))
236 make_capa_key(tmp, mdsnum, rkey->lk_keyid);
238 next = mdt->mdt_child;
239 rc = next->md_ops->mdo_update_capa_key(&env, next, tmp);
241 spin_lock(&capa_lock);
244 spin_unlock(&capa_lock);
246 rc = write_capa_keys(&env, mdt, mdt->mdt_capa_keys);
248 spin_lock(&capa_lock);
250 memset(bkey, 0, sizeof(*bkey));
251 spin_unlock(&capa_lock);
253 set_capa_key_expiry(mdt);
254 DEBUG_CAPA_KEY(D_SEC, rkey, "new");
258 DEBUG_CAPA_KEY(D_ERROR, rkey, "update failed for");
259 /* next retry is in 300 sec */
260 mdt->mdt_ck_expiry = jiffies + 300 * HZ;
263 cfs_timer_arm(&mdt->mdt_ck_timer, mdt->mdt_ck_expiry);
264 CDEBUG(D_SEC, "mdt_ck_timer %lu\n", mdt->mdt_ck_expiry);
268 thread->t_flags = SVC_STOPPED;
269 cfs_waitq_signal(&thread->t_ctl_waitq);
273 int mdt_ck_thread_start(struct mdt_device *mdt)
275 struct ptlrpc_thread *thread = &mdt->mdt_ck_thread;
278 cfs_waitq_init(&thread->t_ctl_waitq);
279 rc = cfs_kernel_thread(mdt_ck_thread_main, mdt,
280 (CLONE_VM | CLONE_FILES));
282 CERROR("cannot start mdt_ck thread, rc = %d\n", rc);
286 cfs_wait_event(thread->t_ctl_waitq, thread->t_flags & SVC_RUNNING);
290 void mdt_ck_thread_stop(struct mdt_device *mdt)
292 struct ptlrpc_thread *thread = &mdt->mdt_ck_thread;
294 if (!(thread->t_flags & SVC_RUNNING))
297 thread->t_flags = SVC_STOPPING;
298 cfs_waitq_signal(&thread->t_ctl_waitq);
299 cfs_wait_event(thread->t_ctl_waitq, thread->t_flags & SVC_STOPPED);