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.)
30 # define EXPORT_SYMTAB
32 #define DEBUG_SUBSYSTEM S_CONFOBD
35 # include <linux/module.h>
36 # include <linux/pagemap.h>
37 # include <linux/miscdevice.h>
38 # include <linux/init.h>
40 # include <liblustre.h>
43 #include <linux/obd_class.h>
44 //#include <linux/lustre_mds.h>
45 #include <linux/lustre_dlm.h>
46 #include <linux/lustre_log.h>
47 #include <linux/lustre_fsfilt.h>
48 #include <linux/lustre_disk.h>
50 #include "mgc_internal.h"
52 static int mgc_fs_setup(struct obd_device *obd, struct super_block *sb,
55 struct lvfs_run_ctxt saved;
56 struct lustre_sb_info *sbi = s2sbi(sb);
57 struct mgc_obd *mgcobd = &obd->u.mgc;
58 struct dentry *dentry;
64 obd->obd_fsops = fsfilt_get_ops(MT_STR(sbi->lsi_ldd));
65 if (IS_ERR(obd->obd_fsops)) {
66 CERROR("No fstype %s rc=%ld\n", MT_STR(sbi->lsi_ldd),
67 PTR_ERR(obd->obd_fsops));
68 return(PTR_ERR(obd->obd_fsops));
71 mgcobd->mgc_vfsmnt = mnt;
72 mgcobd->mgc_sb = mnt->mnt_root->d_inode->i_sb;
73 // FIXME which one? - filter_common_setup also
74 CERROR("SB's: fill=%p mnt=%p root=%p\n", sb, mnt->mnt_sb, mnt->mnt_root->d_inode->i_sb);
75 fsfilt_setup(obd, mgcobd->mgc_sb);
77 OBD_SET_CTXT_MAGIC(&obd->obd_lvfs_ctxt);
78 obd->obd_lvfs_ctxt.pwdmnt = mnt;
79 obd->obd_lvfs_ctxt.pwd = mnt->mnt_root;
80 obd->obd_lvfs_ctxt.fs = get_ds();
81 //obd->obd_lvfs_ctxt.cb_ops = mds_lvfs_ops;
83 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
84 dentry = lookup_one_len(MOUNT_CONFIGS_DIR, current->fs->pwd,
85 strlen(MOUNT_CONFIGS_DIR));
86 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
88 err = PTR_ERR(dentry);
89 CERROR("cannot lookup %s directory: rc = %d\n",
90 MOUNT_CONFIGS_DIR, err);
93 mgcobd->mgc_configs_dir = dentry;
97 fsfilt_put_ops(obd->obd_fsops);
98 obd->obd_fsops = NULL;
99 mgcobd->mgc_sb = NULL;
103 static int mgc_fs_cleanup(struct obd_device *obd)
105 struct mgc_obd *mgc = &obd->u.mgc;
107 // in mgc_cleanup: llog_cleanup(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT));
109 if (mgc->mgc_configs_dir != NULL) {
110 struct lvfs_run_ctxt saved;
111 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
112 l_dput(mgc->mgc_configs_dir);
113 mgc->mgc_configs_dir = NULL;
114 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
117 mgc->mgc_vfsmnt = NULL;
121 fsfilt_put_ops(obd->obd_fsops);
125 static int mgc_cleanup(struct obd_device *obd)
127 struct mgc_obd *mgc = &obd->u.mgc;
130 rc = llog_cleanup(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT));
132 // FIXME REPL rc = obd_llog_finish(obd, 0);
134 CERROR("failed to cleanup llogging subsystems\n");
136 //lprocfs_obd_cleanup(obd);
138 //rc = mgc_obd_cleanup(obd);
140 if (mgc->mgc_vfsmnt) {
141 /* if we're a server, eg. something's mounted */
143 if ((rc = lustre_put_mount(obd->obd_name)))
144 CERROR("mount_put failed %d\n", rc);
149 OBD_FREE(mgc->mgc_rpc_lock, sizeof (*mgc->mgc_rpc_lock));
154 static int mgc_setup(struct obd_device *obd, obd_count len, void *buf)
156 struct lustre_mount_info *lmi;
157 struct mgc_obd *mgc = &obd->u.mgc;
158 //struct lprocfs_static_vars lvars;
162 OBD_ALLOC(mgc->mgc_rpc_lock, sizeof (*mgc->mgc_rpc_lock));
163 if (!mgc->mgc_rpc_lock)
165 mgc_init_rpc_lock(mgc->mgc_rpc_lock);
169 rc = obd_llog_init(obd, obd, 0, NULL);
171 CERROR("failed to setup llogging subsystems\n");
172 GOTO(err_rpc_lock, rc);
175 lmi = lustre_get_mount(obd->obd_name);
177 CERROR("mgc has local disk\n");
178 /* there's a local disk, we must get access */
179 rc = mgc_fs_setup(obd, lmi->lmi_sb, lmi->lmi_mnt);
181 CERROR("fs setup failed %d\n", rc);
184 GOTO(err_rpc_lock, rc);
187 CERROR("mgc does not have local disk (client only)\n");
188 rc = mgc_obd_setup(obd, len, buf);
190 GOTO(err_rpc_lock, rc);
197 OBD_FREE(mgc->mgc_rpc_lock, sizeof (*mgc->mgc_rpc_lock));
202 static int mgc_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
203 void *karg, void *uarg)
205 struct obd_device *obd = exp->exp_obd;
206 struct obd_ioctl_data *data = karg;
207 struct llog_ctxt *ctxt;
208 struct lvfs_run_ctxt saved;
212 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
215 if (!try_module_get(THIS_MODULE)) {
216 CERROR("Can't get module. Is it alive?");
221 /* REPLicator context */
222 case OBD_IOC_PARSE: {
223 CERROR("MGC parsing llog %s\n", data->ioc_inlbuf1);
224 ctxt = llog_get_context(exp->exp_obd, LLOG_CONFIG_REPL_CTXT);
225 rc = class_config_parse_llog(ctxt, data->ioc_inlbuf1, NULL);
229 case OBD_IOC_LLOG_INFO:
230 case OBD_IOC_LLOG_PRINT: {
231 ctxt = llog_get_context(obd, LLOG_CONFIG_REPL_CTXT);
232 rc = llog_ioctl(ctxt, cmd, data);
237 /* ORIGinator context */
238 case OBD_IOC_DUMP_LOG: {
239 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
240 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
241 rc = class_config_dump_llog(ctxt, data->ioc_inlbuf1, NULL);
242 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
248 case OBD_IOC_START: {
250 char *name = data->ioc_inlbuf1;
251 int len = strlen(name) + sizeof("-conf");
253 OBD_ALLOC(conf_prof, len);
255 CERROR("no memory\n");
258 sprintf(conf_prof, "%s-conf", name);
260 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
262 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
263 rc = class_config_parse_llog(ctxt, conf_prof, NULL);
265 CERROR("Unable to process log: %s\n", conf_prof);
267 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
268 OBD_FREE(conf_prof, len);
273 CERROR("mgc_ioctl(): unrecognised ioctl %#x\n", cmd);
274 GOTO(out, rc = -ENOTTY);
277 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
280 module_put(THIS_MODULE);
286 static int mgc_import_event(struct obd_device *obd,
287 struct obd_import *imp,
288 enum obd_import_event event)
292 LASSERT(imp->imp_obd == obd);
295 case IMP_EVENT_DISCON: {
298 case IMP_EVENT_INACTIVE: {
299 if (obd->obd_observer)
300 rc = obd_notify(obd->obd_observer, obd, 0);
303 case IMP_EVENT_ACTIVE: {
304 if (obd->obd_observer)
305 rc = obd_notify(obd->obd_observer, obd, 1);
309 CERROR("Unknown import event %d\n", event);
315 static int mgc_llog_init(struct obd_device *obd, struct obd_device *tgt,
316 int count, struct llog_catid *logid)
318 struct llog_ctxt *ctxt;
322 rc = llog_setup(obd, LLOG_CONFIG_ORIG_CTXT, tgt, 0, NULL,
327 rc = llog_setup(obd, LLOG_CONFIG_REPL_CTXT, tgt, 0, NULL,
330 ctxt = llog_get_context(obd, LLOG_CONFIG_REPL_CTXT);
331 ctxt->loc_imp = obd->u.mgc.mgc_import;
337 static int mgc_llog_finish(struct obd_device *obd, int count)
342 rc = llog_cleanup(llog_get_context(obd, LLOG_CONFIG_REPL_CTXT));
346 /*mgc_obd_setup for mount-conf*/
347 int mgc_obd_setup(struct obd_device *obddev, obd_count len, void *buf)
349 struct lustre_cfg* lcfg = buf;
350 struct mgc_obd *mgc = &obddev->u.mgc;
351 struct obd_import *imp;
352 struct obd_uuid server_uuid;
353 int rq_portal, rp_portal, connect_op;
354 char *name = obddev->obd_type->typ_name;
358 LASSERT(!strcmp(name, LUSTRE_MGC_NAME));
360 rq_portal = MGS_REQUEST_PORTAL;
361 rp_portal = MGC_REPLY_PORTAL;
362 connect_op = MGS_CONNECT;
364 if (LUSTRE_CFG_BUFLEN(lcfg, 1) < 1) {
365 CERROR("requires a TARGET UUID\n");
369 if (LUSTRE_CFG_BUFLEN(lcfg, 1) > 37) {
370 CERROR("client UUID must be less than 38 characters\n");
374 if (LUSTRE_CFG_BUFLEN(lcfg, 2) < 1) {
375 CERROR("setup requires a SERVER UUID\n");
379 if (LUSTRE_CFG_BUFLEN(lcfg, 2) > 37) {
380 CERROR("target UUID must be less than 38 characters\n");
384 sema_init(&mgc->mgc_sem, 1);
385 mgc->mgc_conn_count = 0;
386 memcpy(server_uuid.uuid, lustre_cfg_buf(lcfg, 2),
387 min_t(unsigned int, LUSTRE_CFG_BUFLEN(lcfg, 2),
388 sizeof(server_uuid)));
392 CERROR("ldlm_get_ref failed: %d\n", rc);
396 ptlrpc_init_client(rq_portal, rp_portal, name,
397 &obddev->obd_ldlm_client);
399 imp = class_new_import();
401 GOTO(err_ldlm, rc = -ENOENT);
402 imp->imp_client = &obddev->obd_ldlm_client;
403 imp->imp_obd = obddev;
404 imp->imp_connect_op = connect_op;
405 imp->imp_generation = 0;
406 imp->imp_initial_recov = 1;
407 INIT_LIST_HEAD(&imp->imp_pinger_chain);
408 memcpy(imp->imp_target_uuid.uuid, lustre_cfg_buf(lcfg, 1),
409 LUSTRE_CFG_BUFLEN(lcfg, 1));
410 class_import_put(imp);
412 rc = client_import_add_conn(imp, &server_uuid, 1);
414 CERROR("can't add initial connection\n");
415 GOTO(err_import, rc);
418 mgc->mgc_import = imp;
423 class_destroy_import(imp);
430 /*mgc_obd_cleaup for mount-conf*/
431 int mgc_obd_cleanup(struct obd_device *obddev)
433 struct mgc_obd *mgc = &obddev->u.mgc;
435 if (!mgc->mgc_import)
438 class_destroy_import(mgc->mgc_import);
439 mgc->mgc_import = NULL;
441 ldlm_put_ref(obddev->obd_force);
446 /* mgc_connect_import for mount-conf*/
447 int mgc_connect_import(struct lustre_handle *dlm_handle,
448 struct obd_device *obd, struct obd_uuid *cluuid,
449 struct obd_connect_data *data)
451 struct mgc_obd *mgc = &obd->u.mgc;
452 struct obd_import *imp = mgc->mgc_import;
453 struct obd_export *exp;
458 rc = class_connect(dlm_handle, obd, cluuid);
462 mgc->mgc_conn_count++;
463 if (mgc->mgc_conn_count > 1)
465 exp = class_conn2export(dlm_handle);
467 imp->imp_dlm_handle = *dlm_handle;
468 rc = ptlrpc_init_import(imp);
473 memcpy(&imp->imp_connect_data, data, sizeof(*data));
474 rc = ptlrpc_connect_import(imp, NULL);
476 LASSERT (imp->imp_state == LUSTRE_IMP_DISCON);
479 LASSERT(exp->exp_connection);
481 ptlrpc_pinger_add_import(imp);
486 mgc->mgc_conn_count--;
487 class_disconnect(exp);
489 class_export_put(exp);
496 /* mgc_disconnect_export for mount-conf*/
497 int mgc_disconnect_export(struct obd_export *exp)
499 struct obd_device *obd = class_exp2obd(exp);
500 struct mgc_obd *mgc = &obd->u.mgc;
501 struct obd_import *imp = mgc->mgc_import;
506 CERROR("invalid export for disconnect: exp %p cookie "LPX64"\n",
507 exp, exp ? exp->exp_handle.h_cookie : -1);
512 if (!mgc->mgc_conn_count) {
513 CERROR("disconnecting disconnected device (%s)\n",
515 GOTO(out_sem, rc = -EINVAL);
518 mgc->mgc_conn_count--;
519 if (mgc->mgc_conn_count)
520 GOTO(out_no_disconnect, rc = 0);
522 /* Some non-replayable imports (MDS's OSCs) are pinged, so just
523 * delete it regardless. (It's safe to delete an import that was
525 (void)ptlrpc_pinger_del_import(imp);
527 /* Yeah, obd_no_recov also (mainly) means "forced shutdown". */
528 if (obd->obd_no_recov)
529 ptlrpc_invalidate_import(imp);
531 rc = ptlrpc_disconnect_import(imp);
535 err = class_disconnect(exp);
543 /* reuse the client_import_[add/del]_conn*/
544 struct obd_ops mgc_obd_ops = {
545 .o_owner = THIS_MODULE,
546 .o_setup = mgc_setup,
547 .o_cleanup = mgc_cleanup,
548 .o_add_conn = client_import_add_conn,
549 .o_del_conn = client_import_del_conn,
550 .o_connect = mgc_connect_import,
551 .o_disconnect = mgc_disconnect_export,
552 .o_iocontrol = mgc_iocontrol,
553 .o_import_event = mgc_import_event,
554 .o_llog_init = mgc_llog_init,
555 .o_llog_finish = mgc_llog_finish,
558 int __init mgc_init(void)
560 return class_register_type(&mgc_obd_ops, NULL, LUSTRE_MGC_NAME);
564 static void /*__exit*/ mgc_exit(void)
566 class_unregister_type(LUSTRE_MGC_NAME);
569 MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
570 MODULE_DESCRIPTION("Lustre Management Client");
571 MODULE_LICENSE("GPL");
573 module_init(mgc_init);
574 module_exit(mgc_exit);