1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * lustre/mgs/mgs_handler.c
5 * Lustre Management Server (mgs) request handler
7 * Copyright (C) 2001-2005 Cluster File Systems, Inc.
8 * Author Nathan <nathan@clusterfs.com>
9 * Author LinSongTao <lincent@clusterfs.com>
11 * This file is part of Lustre, http://www.lustre.org.
13 * Lustre is free software; you can redistribute it and/or
14 * modify it under the terms of version 2 of the GNU General Public
15 * License as published by the Free Software Foundation.
17 * Lustre is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with Lustre; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 # define EXPORT_SYMTAB
30 #define DEBUG_SUBSYSTEM S_MGS
33 # include <linux/module.h>
34 # include <linux/pagemap.h>
35 # include <linux/miscdevice.h>
36 # include <linux/init.h>
38 # include <liblustre.h>
41 #include <linux/obd_class.h>
42 #include <linux/lustre_dlm.h>
43 #include <linux/lprocfs_status.h>
44 #include <linux/lustre_fsfilt.h>
45 #include <linux/lustre_commit_confd.h>
46 #include <linux/lustre_disk.h>
47 #include "mgs_internal.h"
49 static int mgs_postsetup(struct obd_device *obd);
50 static int mgs_cleanup(struct obd_device *obd);
52 /* Establish a connection to the MGS.*/
53 static int mgs_connect(struct lustre_handle *conn, struct obd_device *obd,
54 struct obd_uuid *cluuid, struct obd_connect_data *data)
56 struct obd_export *exp;
57 int rc, abort_recovery;
60 if (!conn || !obd || !cluuid)
63 rc = class_connect(conn, obd, cluuid);
66 exp = class_conn2export(conn);
70 data->ocd_connect_flags &= MGMT_CONNECT_SUPPORTED;
71 exp->exp_connect_flags = data->ocd_connect_flags;
75 /* FIXME: recovery of connection*/
76 rc = mgs_client_add(obd, &obd->u.mgs, med, -1);
81 class_disconnect(exp);
83 class_export_put(exp);
89 static int mgs_disconnect(struct obd_export *exp)
91 unsigned long irqflags;
96 class_export_get(exp);
98 /* Disconnect early so that clients can't keep using export */
99 rc = class_disconnect(exp);
100 ldlm_cancel_locks_for_export(exp);
102 /* complete all outstanding replies */
103 spin_lock_irqsave(&exp->exp_lock, irqflags);
104 while (!list_empty(&exp->exp_outstanding_replies)) {
105 struct ptlrpc_reply_state *rs =
106 list_entry(exp->exp_outstanding_replies.next,
107 struct ptlrpc_reply_state, rs_exp_list);
108 struct ptlrpc_service *svc = rs->rs_service;
110 spin_lock(&svc->srv_lock);
111 list_del_init(&rs->rs_exp_list);
112 ptlrpc_schedule_difficult_reply(rs);
113 spin_unlock(&svc->srv_lock);
115 spin_unlock_irqrestore(&exp->exp_lock, irqflags);
117 class_export_put(exp);
121 /* Start the MGS obd */
122 static int mgs_setup(struct obd_device *obd, obd_count len, void *buf)
124 struct lprocfs_static_vars lvars;
125 char *ns_name = "MGS";
126 struct mgs_obd *mgs = &obd->u.mgs;
127 struct lustre_mount_info *lmi;
128 struct lustre_sb_info *lsi;
129 struct vfsmount *mnt;
133 CDEBUG(D_CONFIG, "Starting MGS\n");
135 lmi = server_get_mount(obd->obd_name);
137 RETURN(rc = -EINVAL);
140 lsi = s2lsi(lmi->lmi_sb);
141 obd->obd_fsops = fsfilt_get_ops(MT_STR(lsi->lsi_ldd));
142 if (IS_ERR(obd->obd_fsops))
143 GOTO(err_put, rc = PTR_ERR(obd->obd_fsops));
145 /* namespace for mgs llog */
146 obd->obd_namespace = ldlm_namespace_new(ns_name, LDLM_NAMESPACE_SERVER);
147 if (obd->obd_namespace == NULL) {
149 GOTO(err_ops, rc = -ENOMEM);
152 LASSERT(!lvfs_check_rdonly(lvfs_sbdev(mnt->mnt_sb)));
154 rc = mgs_fs_setup(obd, mnt);
156 CERROR("%s: MGS filesystem method init failed: rc = %d\n",
161 rc = llog_start_commit_thread();
165 rc = mgs_postsetup(obd);
169 lprocfs_init_vars(mgs, &lvars);
170 lprocfs_obd_setup(obd, lvars.obd_vars);
172 LCONSOLE_INFO("MGS %s started\n", obd->obd_name);
175 ping_evictor_start();
180 /* No extra cleanup needed for llog_init_commit_thread() */
183 ldlm_namespace_free(obd->obd_namespace, 0);
184 obd->obd_namespace = NULL;
186 fsfilt_put_ops(obd->obd_fsops);
188 server_put_mount(obd->obd_name, mgs->mgs_vfsmnt);
193 static int mgs_postsetup(struct obd_device *obd)
198 rc = llog_setup(obd, LLOG_CONFIG_ORIG_CTXT, obd, 0, NULL,
203 static int mgs_precleanup(struct obd_device *obd, int stage)
208 llog_cleanup(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT));
209 rc = obd_llog_finish(obd, 0);
213 static int mgs_cleanup(struct obd_device *obd)
215 struct mgs_obd *mgs = &obd->u.mgs;
216 lvfs_sbdev_type save_dev;
221 if (mgs->mgs_sb == NULL)
223 save_dev = lvfs_sbdev(mgs->mgs_sb);
225 // lprocfs_obd_cleanup(obd);
227 // mgs_update_server_data(obd, 1);
229 //mgs_fs_cleanup(obd);
231 server_put_mount(obd->obd_name, mgs->mgs_vfsmnt);
234 ldlm_namespace_free(obd->obd_namespace, obd->obd_force);
236 spin_lock_bh(&obd->obd_processing_task_lock);
237 if (obd->obd_recovering) {
238 target_cancel_recovery_timer(obd);
239 obd->obd_recovering = 0;
241 spin_unlock_bh(&obd->obd_processing_task_lock);
243 lvfs_clear_rdonly(save_dev);
245 fsfilt_put_ops(obd->obd_fsops);
247 LCONSOLE_INFO("MGS %s has stopped.\n", obd->obd_name);
252 static int mgs_handle_target_add(struct ptlrpc_request *req)
254 struct obd_device *obd = &req->rq_export->exp_obd;
255 struct mgs_obd *mgs = &obd->u.mgs;
256 struct mgmt_target_info *req_mti, *mti, *rep_mti;
257 int rep_size = sizeof(*mti);
260 OBD_ALLOC(mti, sizeof(*mti));
262 GOTO(out, rc = -ENOMEM);
263 req_mti = lustre_swab_reqbuf(req, 0, sizeof(*mti),
264 lustre_swab_mgmt_target_info);
265 memcpy(mti, req_mti, sizeof(*mti));
267 /* NEED_INDEX implies NEED_REGISTER, but not vice-versa */
268 if (mti->mti_flags & LDD_F_NEED_INDEX) {
269 rc = mgs_get_index(mti);
270 // rc = mgmt_handle_first_connect(req);
273 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
274 rc = llog_add_mds(obd, mti);
278 lustre_pack_reply(req, 1, &rep_size, NULL);
279 rep_mti = lustre_msg_buf(req->rq_repmsg, 0, sizeof(*rep_mti));
280 memcpy(rep_mti, mti, sizeof(*rep_mti));
282 rep_mti->mti_stripe_index = rc;
286 int mgs_handle(struct ptlrpc_request *req)
288 int fail = OBD_FAIL_MGMT_ALL_REPLY_NET;
292 OBD_FAIL_RETURN(OBD_FAIL_MGMT_ALL_REQUEST_NET | OBD_FAIL_ONCE, 0);
294 LASSERT(current->journal_info == NULL);
295 if (req->rq_reqmsg->opc != MGMT_CONNECT) {
296 if (req->rq_export == NULL) {
297 CERROR("lustre_mgs: operation %d on unconnected MGS\n",
298 req->rq_reqmsg->opc);
299 req->rq_status = -ENOTCONN;
300 GOTO(out, rc = -ENOTCONN);
304 switch (req->rq_reqmsg->opc) {
306 DEBUG_REQ(D_INODE, req, "connect");
307 OBD_FAIL_RETURN(OBD_FAIL_MGMT_CONNECT_NET, 0);
308 rc = target_handle_connect(req, mgs_handle);
310 case MGMT_DISCONNECT:
311 DEBUG_REQ(D_INODE, req, "disconnect");
312 OBD_FAIL_RETURN(OBD_FAIL_MGMT_DISCONNECT_NET, 0);
313 rc = target_handle_disconnect(req);
314 req->rq_status = rc; /* superfluous? */
317 case MGMT_TARGET_ADD:
318 CDEBUG(D_INODE, "target add\n");
319 rc = mgs_handle_target_add(req);
321 case MGMT_TARGET_DEL:
322 CDEBUG(D_INODE, "target del\n");
323 //rc = mgs_handle_target_del(req);
327 DEBUG_REQ(D_INODE, req, "enqueue");
328 OBD_FAIL_RETURN(OBD_FAIL_LDLM_ENQUEUE, 0);
329 rc = ldlm_handle_enqueue(req, ldlm_server_completion_ast,
330 ldlm_server_blocking_ast, NULL);
331 fail = OBD_FAIL_LDLM_REPLY;
333 case LDLM_BL_CALLBACK:
334 case LDLM_CP_CALLBACK:
335 DEBUG_REQ(D_INODE, req, "callback");
336 CERROR("callbacks should not happen on MDS\n");
338 OBD_FAIL_RETURN(OBD_FAIL_LDLM_BL_CALLBACK, 0);
342 DEBUG_REQ(D_INODE, req, "ping");
343 rc = target_handle_ping(req);
347 CDEBUG(D_INODE, "log cancel\n");
348 OBD_FAIL_RETURN(OBD_FAIL_OBD_LOG_CANCEL_NET, 0);
349 rc = -ENOTSUPP; /* la la la */
352 case LLOG_ORIGIN_HANDLE_CREATE:
353 DEBUG_REQ(D_INODE, req, "llog_init");
354 OBD_FAIL_RETURN(OBD_FAIL_OBD_LOGD_NET, 0);
355 rc = llog_origin_handle_create(req);
357 case LLOG_ORIGIN_HANDLE_NEXT_BLOCK:
358 DEBUG_REQ(D_INODE, req, "llog next block");
359 OBD_FAIL_RETURN(OBD_FAIL_OBD_LOGD_NET, 0);
360 rc = llog_origin_handle_next_block(req);
362 case LLOG_ORIGIN_HANDLE_READ_HEADER:
363 DEBUG_REQ(D_INODE, req, "llog read header");
364 OBD_FAIL_RETURN(OBD_FAIL_OBD_LOGD_NET, 0);
365 rc = llog_origin_handle_read_header(req);
367 case LLOG_ORIGIN_HANDLE_CLOSE:
368 DEBUG_REQ(D_INODE, req, "llog close");
369 OBD_FAIL_RETURN(OBD_FAIL_OBD_LOGD_NET, 0);
370 rc = llog_origin_handle_close(req);
373 DEBUG_REQ(D_INODE, req, "llog catinfo");
374 OBD_FAIL_RETURN(OBD_FAIL_OBD_LOGD_NET, 0);
375 rc = llog_catinfo(req);
378 req->rq_status = -ENOTSUPP;
379 rc = ptlrpc_error(req);
383 LASSERT(current->journal_info == NULL);
386 target_send_reply(req, rc, fail);
390 static int mgt_setup(struct obd_device *obd, obd_count len, void *buf)
392 struct mgs_obd *mgs = &obd->u.mgs;
393 struct lprocfs_static_vars lvars;
397 lprocfs_init_vars(mgt, &lvars);
398 lprocfs_obd_setup(obd, lvars.obd_vars);
401 ptlrpc_init_svc(MGS_NBUFS, MGS_BUFSIZE, MGS_MAXREQSIZE,
402 MGS_MAXREPSIZE, MGS_REQUEST_PORTAL,
403 MGC_REPLY_PORTAL, MGS_SERVICE_WATCHDOG_TIMEOUT,
404 mgs_handle, "mgs", obd->obd_proc_entry, NULL,
407 if (!mgs->mgs_service) {
408 CERROR("failed to start service\n");
409 GOTO(err_lprocfs, rc = -ENOMEM);
412 rc = ptlrpc_start_threads(obd, mgs->mgs_service, "ll_mgt");
414 GOTO(err_thread, rc);
419 ptlrpc_unregister_service(mgs->mgs_service);
421 lprocfs_obd_cleanup(obd);
426 static int mgt_cleanup(struct obd_device *obd)
428 struct mgs_obd *mgs = &obd->u.mgs;
431 ptlrpc_unregister_service(mgs->mgs_service);
433 lprocfs_obd_cleanup(obd);
438 struct lvfs_callback_ops mgs_lvfs_ops = {
439 // l_fid2dentry: mgs_lvfs_fid2dentry,
440 // l_open_llog: mgs_lvfs_open_llog,
443 /* use obd ops to offer management infrastructure */
444 static struct obd_ops mgs_obd_ops = {
445 .o_owner = THIS_MODULE,
446 .o_connect = mgs_connect,
447 .o_disconnect = mgs_disconnect,
448 .o_setup = mgs_setup,
449 .o_precleanup = mgs_precleanup,
450 .o_cleanup = mgs_cleanup,
451 .o_iocontrol = mgs_iocontrol,
454 static struct obd_ops mgt_obd_ops = {
455 .o_owner = THIS_MODULE,
456 .o_setup = mgt_setup,
457 .o_cleanup = mgt_cleanup,
460 static int __init mgs_init(void)
462 struct lprocfs_static_vars lvars;
464 lprocfs_init_vars(mgs, &lvars);
465 class_register_type(&mgs_obd_ops, lvars.module_vars, LUSTRE_MGS_NAME);
466 lprocfs_init_vars(mgt, &lvars);
467 class_register_type(&mgt_obd_ops, lvars.module_vars, LUSTRE_MGT_NAME);
472 static void /*__exit*/ mgs_exit(void)
474 class_unregister_type(LUSTRE_MGS_NAME);
475 class_unregister_type(LUSTRE_MGT_NAME);
478 MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
479 MODULE_DESCRIPTION("Lustre Management Server (MGS)");
480 MODULE_LICENSE("GPL");
482 module_init(mgs_init);
483 module_exit(mgs_exit);