1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (C) 2001-2005 Cluster File Systems, Inc.
5 * Author Nathan <nathan@clusterfs.com>
6 * Author LinSongTao <lincent@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.
23 * For testing and management it is treated as an obd_device,
24 * although * it does not export a full OBD method table (the
25 * requests are coming * in over the wire, so object target modules
26 * do not have a full * method table.)
29 # define EXPORT_SYMTAB
31 #define DEBUG_SUBSYSTEM S_MGC
34 # include <linux/module.h>
35 # include <linux/pagemap.h>
36 # include <linux/miscdevice.h>
37 # include <linux/init.h>
39 # include <liblustre.h>
42 #include <linux/obd_class.h>
43 #include <linux/lustre_dlm.h>
44 #include <linux/lustre_log.h>
45 #include <linux/lustre_fsfilt.h>
46 #include <linux/lustre_disk.h>
47 #include <linux/lustre_mgs.h>
49 #include "mgc_internal.h"
52 /* Get index and add to config llog, depending on flags */
53 int mgc_target_add(struct obd_export *exp, struct mgmt_ost_info *moi)
55 struct ptlrpc_request *req;
56 struct mgmt_ost_info *req_moi, *rep_moi;
57 int size = sizeof(*req_moi);
58 int rep_size = sizeof(*moi);
62 req = ptlrpc_prep_req(class_exp2cliimp(exp), MGMT_TARGET_ADD,
67 req_moi = lustre_msg_buf(req->rq_reqmsg, 0, sizeof(*req_moi));
68 memcpy(req_moi, moi, sizeof(*req_moi));
70 req->rq_replen = lustre_msg_size(1, &rep_size);
72 rc = ptlrpc_queue_wait(req);
75 rep_moi = lustre_swab_repbuf(req, 0, sizeof(*rep_moi),
76 lustre_swab_mgmt_ost_info);
77 index = rep_moi->moi_stripe_index;
78 if (index != moi->moi_stripe_index) {
79 CERROR ("OST ADD failed. rc=%d\n", index);
80 GOTO (out, rc = -EINVAL);
82 CERROR("OST ADD OK.(index = %d)\n", index);
85 ptlrpc_req_finished(req);
89 EXPORT_SYMBOL(mgc_target_add);
91 /* Remove from config llog */
92 int mgc_target_del(struct obd_export *exp, struct mgmt_ost_info *moi)
94 struct ptlrpc_request *req;
95 struct mgmt_ost_info *req_moi, *rep_moi;
96 int size = sizeof(*req_moi);
100 req = ptlrpc_prep_req(class_exp2cliimp(exp), MGMT_TARGET_DEL,
103 RETURN(rc = -ENOMEM);
105 req_moi = lustre_msg_buf(req->rq_reqmsg, 0, sizeof(*req_moi));
106 memcpy(req_moi, moi, sizeof(*req_moi));
108 rc = ptlrpc_queue_wait(req);
111 rep_moi = lustre_swab_repbuf(req, 0, sizeof(*rep_moi),
112 lustre_swab_mgmt_ost_info);
113 index = rep_moi->moi_stripe_index;
114 if (index != moi->moi_stripe_index) {
115 CERROR ("OST DEL failed. rc=%d\n", index);
116 GOTO (out, rc = -EINVAL);
118 CERROR("OST DEL OK.(old index = %d)\n", index);
121 ptlrpc_req_finished(req);
125 EXPORT_SYMBOL(mgc_target_del);
127 static int mgc_fs_setup(struct obd_device *obd, struct super_block *sb,
128 struct vfsmount *mnt)
130 struct lvfs_run_ctxt saved;
131 struct lustre_sb_info *lsi = s2lsi(sb);
132 struct client_obd *cli = &obd->u.cli;
133 struct dentry *dentry;
138 obd->obd_fsops = fsfilt_get_ops(MT_STR(lsi->lsi_ldd));
139 if (IS_ERR(obd->obd_fsops)) {
140 CERROR("No fstype %s rc=%ld\n", MT_STR(lsi->lsi_ldd),
141 PTR_ERR(obd->obd_fsops));
142 return(PTR_ERR(obd->obd_fsops));
145 cli->cl_mgc_vfsmnt = mnt;
146 cli->cl_mgc_sb = mnt->mnt_root->d_inode->i_sb;
147 // FIXME which is the right SB? - filter_common_setup also
148 CERROR("SB's: fill=%p mnt=%p root=%p\n", sb, mnt->mnt_sb, mnt->mnt_root->d_inode->i_sb);
149 fsfilt_setup(obd, cli->cl_mgc_sb);
151 OBD_SET_CTXT_MAGIC(&obd->obd_lvfs_ctxt);
152 obd->obd_lvfs_ctxt.pwdmnt = mnt;
153 obd->obd_lvfs_ctxt.pwd = mnt->mnt_root;
154 obd->obd_lvfs_ctxt.fs = get_ds();
155 //obd->obd_lvfs_ctxt.cb_ops = mds_lvfs_ops;
157 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
158 dentry = lookup_one_len(MOUNT_CONFIGS_DIR, current->fs->pwd,
159 strlen(MOUNT_CONFIGS_DIR));
160 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
161 if (IS_ERR(dentry)) {
162 err = PTR_ERR(dentry);
163 CERROR("cannot lookup %s directory: rc = %d\n",
164 MOUNT_CONFIGS_DIR, err);
167 cli->cl_mgc_configs_dir = dentry;
171 fsfilt_put_ops(obd->obd_fsops);
172 obd->obd_fsops = NULL;
173 cli->cl_mgc_sb = NULL;
177 static int mgc_fs_cleanup(struct obd_device *obd)
179 struct client_obd *cli = &obd->u.cli;
182 if (cli->cl_mgc_configs_dir != NULL) {
183 struct lvfs_run_ctxt saved;
184 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
185 l_dput(cli->cl_mgc_configs_dir);
186 cli->cl_mgc_configs_dir = NULL;
187 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
190 rc = lustre_put_mount(obd->obd_name, cli->cl_mgc_vfsmnt);
192 CERROR("mount_put failed %d\n", rc);
194 cli->cl_mgc_vfsmnt = NULL;
195 cli->cl_mgc_sb = NULL;
198 fsfilt_put_ops(obd->obd_fsops);
202 static int mgc_cleanup(struct obd_device *obd)
204 struct client_obd *cli = &obd->u.cli;
207 //lprocfs_obd_cleanup(obd);
209 if (cli->cl_mgc_vfsmnt) {
210 /* if we're a server, eg. something's mounted */
214 rc = obd_llog_finish(obd, 0);
216 CERROR("failed to cleanup llogging subsystems\n");
220 OBD_FREE(cli->cl_mgc_rpc_lock, sizeof (*cli->cl_mgc_rpc_lock));
222 return client_obd_cleanup(obd);
225 /* the same as mdc_setup */
226 static int mgc_setup(struct obd_device *obd, obd_count len, void *buf)
228 struct client_obd *cli = &obd->u.cli;
232 OBD_ALLOC(cli->cl_mgc_rpc_lock, sizeof (*cli->cl_mgc_rpc_lock));
233 if (!cli->cl_mgc_rpc_lock)
235 mgc_init_rpc_lock(cli->cl_mgc_rpc_lock);
239 rc = client_obd_setup(obd, len, buf);
241 GOTO(err_rpc_lock, rc);
243 rc = obd_llog_init(obd, obd, 0, NULL);
245 CERROR("failed to setup llogging subsystems\n");
246 GOTO(err_rpc_lock, rc);
250 struct lustre_mount_info *lmi;
251 /* FIXME There's only one mgc for all local servers. Must mgc_fs_setup
252 on demand only when reading a local log file, then cleanup.
253 Make sure there's a lock so nobody else can mgc_fs_setup in the
255 lmi = lustre_get_mount(obd->obd_name);
257 CERROR("mgc has local disk\n");
258 /* there's a local disk, we must get access */
259 rc = mgc_fs_setup(obd, lmi->lmi_sb, lmi->lmi_mnt);
261 CERROR("fs setup failed %d\n", rc);
267 CERROR("mgc does not have local disk (client only)\n");
270 INIT_LIST_HEAD(&cli->cl_mgc_open_llogs);
276 OBD_FREE(cli->cl_mgc_rpc_lock, sizeof (*cli->cl_mgc_rpc_lock));
280 static int mgc_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
281 void *karg, void *uarg)
283 struct obd_device *obd = exp->exp_obd;
284 struct obd_ioctl_data *data = karg;
285 struct llog_ctxt *ctxt;
286 struct lvfs_run_ctxt saved;
290 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
293 if (!try_module_get(THIS_MODULE)) {
294 CERROR("Can't get module. Is it alive?");
299 /* REPLicator context */
300 case OBD_IOC_PARSE: {
301 CERROR("MGC parsing llog %s\n", data->ioc_inlbuf1);
302 ctxt = llog_get_context(exp->exp_obd, LLOG_CONFIG_REPL_CTXT);
303 rc = class_config_parse_llog(ctxt, data->ioc_inlbuf1, NULL);
307 case OBD_IOC_LLOG_INFO:
308 case OBD_IOC_LLOG_PRINT: {
309 ctxt = llog_get_context(obd, LLOG_CONFIG_REPL_CTXT);
310 rc = llog_ioctl(ctxt, cmd, data);
315 /* ORIGinator context */
316 case OBD_IOC_DUMP_LOG: {
317 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
318 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
319 rc = class_config_dump_llog(ctxt, data->ioc_inlbuf1, NULL);
320 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
326 case OBD_IOC_START: {
327 char *name = data->ioc_inlbuf1;
328 CERROR("getting config log %s\n", name);
329 /* FIXME Get llog from MGS */
331 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
332 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
333 rc = class_config_parse_llog(ctxt, name, NULL);
335 CERROR("Unable to process log: %s\n", name);
336 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
341 CERROR("mgc_ioctl(): unrecognised ioctl %#x\n", cmd);
342 GOTO(out, rc = -ENOTTY);
345 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
348 module_put(THIS_MODULE);
354 #define INIT_RECOV_BACKUP "init_recov_bk"
355 int mgc_set_info(struct obd_export *exp, obd_count keylen,
356 void *key, obd_count vallen, void *val)
358 struct obd_import *imp = class_exp2cliimp(exp);
362 /* Try to "recover" the initial connection; i.e. retry */
363 if (keylen == strlen("initial_recov") &&
364 memcmp(key, "initial_recov", keylen) == 0) {
365 if (vallen != sizeof(int))
367 imp->imp_initial_recov = *(int *)val;
368 CDEBUG(D_HA, "%s: set imp_initial_recov = %d\n",
369 exp->exp_obd->obd_name, imp->imp_initial_recov);
372 /* Turn off initial_recov after we try all backup servers once */
373 if (keylen == strlen(INIT_RECOV_BACKUP) &&
374 memcmp(key, INIT_RECOV_BACKUP, keylen) == 0) {
375 if (vallen != sizeof(int))
377 imp->imp_initial_recov_bk = *(int *)val;
378 CDEBUG(D_HA, "%s: set imp_initial_recov_bk = %d\n",
379 exp->exp_obd->obd_name, imp->imp_initial_recov_bk);
383 if (keylen == strlen("register") &&
384 memcmp(key, "register", keylen) == 0) {
385 struct mgmt_ost_info *moi;
386 if (vallen != sizeof(struct mgmt_ost_info))
388 moi = (struct mgmt_ost_info *)val;
389 CERROR("register %s %#x\n", moi->moi_ostname, moi->moi_flags);
390 rc = mgc_target_add(exp, moi);
396 static int mgc_import_event(struct obd_device *obd,
397 struct obd_import *imp,
398 enum obd_import_event event)
402 LASSERT(imp->imp_obd == obd);
405 case IMP_EVENT_DISCON: {
408 case IMP_EVENT_INVALIDATE: {
409 struct ldlm_namespace *ns = obd->obd_namespace;
411 ldlm_namespace_cleanup(ns, LDLM_FL_LOCAL_ONLY);
415 case IMP_EVENT_INACTIVE: {
418 case IMP_EVENT_ACTIVE: {
422 CERROR("Unknown import event %d\n", event);
428 static int mgc_llog_init(struct obd_device *obd, struct obd_device *tgt,
429 int count, struct llog_catid *logid)
431 struct llog_ctxt *ctxt;
435 rc = llog_setup(obd, LLOG_CONFIG_ORIG_CTXT, tgt, 0, NULL,
440 rc = llog_setup(obd, LLOG_CONFIG_REPL_CTXT, tgt, 0, NULL,
443 ctxt = llog_get_context(obd, LLOG_CONFIG_REPL_CTXT);
444 ctxt->loc_imp = obd->u.cli.cl_import;
450 static int mgc_llog_finish(struct obd_device *obd, int count)
455 rc = llog_cleanup(llog_get_context(obd, LLOG_CONFIG_REPL_CTXT));
456 rc = llog_cleanup(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT));
461 /* reuse the client_import_[add/del]_conn*/
462 struct obd_ops mgc_obd_ops = {
463 .o_owner = THIS_MODULE,
464 .o_setup = mgc_setup,
465 .o_cleanup = mgc_cleanup,
466 .o_add_conn = client_import_add_conn,
467 .o_del_conn = client_import_del_conn,
468 .o_connect = client_connect_import,
469 .o_disconnect = client_disconnect_export,
470 .o_iocontrol = mgc_iocontrol,
471 .o_set_info = mgc_set_info,
472 .o_import_event = mgc_import_event,
473 .o_llog_init = mgc_llog_init,
474 .o_llog_finish = mgc_llog_finish,
477 int __init mgc_init(void)
479 return class_register_type(&mgc_obd_ops, NULL, LUSTRE_MGC_NAME);
483 static void /*__exit*/ mgc_exit(void)
485 class_unregister_type(LUSTRE_MGC_NAME);
488 MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
489 MODULE_DESCRIPTION("Lustre Management Client");
490 MODULE_LICENSE("GPL");
492 module_init(mgc_init);
493 module_exit(mgc_exit);