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/mgs/mgs_handler.c
38 * Author: Nathan Rutman <nathan@clusterfs.com>
42 # define EXPORT_SYMTAB
44 #define DEBUG_SUBSYSTEM S_MGS
45 #define D_MGS D_CONFIG/*|D_WARNING*/
48 # include <linux/module.h>
49 # include <linux/pagemap.h>
50 # include <linux/miscdevice.h>
51 # include <linux/init.h>
53 # include <liblustre.h>
56 #include <obd_class.h>
57 #include <lustre_dlm.h>
58 #include <lprocfs_status.h>
59 #include <lustre_fsfilt.h>
60 #include <lustre_disk.h>
61 #include "mgs_internal.h"
64 /* Establish a connection to the MGS.*/
65 static int mgs_connect(const struct lu_env *env,
66 struct lustre_handle *conn, struct obd_device *obd,
67 struct obd_uuid *cluuid, struct obd_connect_data *data,
70 struct obd_export *exp;
74 if (!conn || !obd || !cluuid)
77 rc = class_connect(conn, obd, cluuid);
80 exp = class_conn2export(conn);
83 exp->exp_flvr.sf_rpc = SPTLRPC_FLVR_NULL;
85 mgs_counter_incr(exp, LPROC_MGS_CONNECT);
88 data->ocd_connect_flags &= MGS_CONNECT_SUPPORTED;
89 exp->exp_connect_flags = data->ocd_connect_flags;
90 data->ocd_version = LUSTRE_VERSION_CODE;
93 rc = mgs_client_add(obd, exp, localdata);
96 class_disconnect(exp);
98 class_export_put(exp);
104 static int mgs_reconnect(const struct lu_env *env,
105 struct obd_export *exp, struct obd_device *obd,
106 struct obd_uuid *cluuid, struct obd_connect_data *data,
111 if (exp == NULL || obd == NULL || cluuid == NULL)
114 mgs_counter_incr(exp, LPROC_MGS_CONNECT);
117 data->ocd_connect_flags &= MGS_CONNECT_SUPPORTED;
118 exp->exp_connect_flags = data->ocd_connect_flags;
119 data->ocd_version = LUSTRE_VERSION_CODE;
125 static int mgs_disconnect(struct obd_export *exp)
132 class_export_get(exp);
133 mgs_counter_incr(exp, LPROC_MGS_DISCONNECT);
135 /* Disconnect early so that clients can't keep using export */
136 rc = class_disconnect(exp);
137 ldlm_cancel_locks_for_export(exp);
139 lprocfs_exp_cleanup(exp);
141 /* complete all outstanding replies */
142 spin_lock(&exp->exp_lock);
143 while (!list_empty(&exp->exp_outstanding_replies)) {
144 struct ptlrpc_reply_state *rs =
145 list_entry(exp->exp_outstanding_replies.next,
146 struct ptlrpc_reply_state, rs_exp_list);
147 struct ptlrpc_service *svc = rs->rs_service;
149 spin_lock(&svc->srv_lock);
150 list_del_init(&rs->rs_exp_list);
151 ptlrpc_schedule_difficult_reply(rs);
152 spin_unlock(&svc->srv_lock);
154 spin_unlock(&exp->exp_lock);
156 class_export_put(exp);
160 static int mgs_cleanup(struct obd_device *obd);
161 static int mgs_handle(struct ptlrpc_request *req);
163 static int mgs_llog_init(struct obd_device *obd, struct obd_llog_group *olg,
164 struct obd_device *tgt, int count,
165 struct llog_catid *logid, struct obd_uuid *uuid)
170 LASSERT(olg == &obd->obd_olg);
171 rc = llog_setup(obd, olg, LLOG_CONFIG_ORIG_CTXT, obd, 0, NULL,
176 static int mgs_llog_finish(struct obd_device *obd, int count)
178 struct llog_ctxt *ctxt;
182 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
184 rc = llog_cleanup(ctxt);
189 /* Start the MGS obd */
190 static int mgs_setup(struct obd_device *obd, struct lustre_cfg *lcfg)
192 struct lprocfs_static_vars lvars;
193 struct mgs_obd *mgs = &obd->u.mgs;
194 struct lustre_mount_info *lmi;
195 struct lustre_sb_info *lsi;
196 struct vfsmount *mnt;
200 CDEBUG(D_CONFIG, "Starting MGS\n");
203 lmi = server_get_mount(obd->obd_name);
205 RETURN(rc = -EINVAL);
208 lsi = s2lsi(lmi->lmi_sb);
209 obd->obd_fsops = fsfilt_get_ops(MT_STR(lsi->lsi_ldd));
210 if (IS_ERR(obd->obd_fsops))
211 GOTO(err_put, rc = PTR_ERR(obd->obd_fsops));
213 /* namespace for mgs llog */
214 obd->obd_namespace = ldlm_namespace_new(obd ,"MGS", LDLM_NAMESPACE_SERVER,
215 LDLM_NAMESPACE_MODEST);
216 if (obd->obd_namespace == NULL)
217 GOTO(err_ops, rc = -ENOMEM);
220 ptlrpc_init_client(LDLM_CB_REQUEST_PORTAL, LDLM_CB_REPLY_PORTAL,
221 "mgs_ldlm_client", &obd->obd_ldlm_client);
223 LASSERT(!lvfs_check_rdonly(lvfs_sbdev(mnt->mnt_sb)));
225 rc = mgs_fs_setup(obd, mnt);
227 CERROR("%s: MGS filesystem method init failed: rc = %d\n",
232 rc = obd_llog_init(obd, &obd->obd_olg, obd, 0, NULL, NULL);
236 /* No recovery for MGC's */
237 obd->obd_replayable = 0;
239 /* Internal mgs setup */
240 mgs_init_fsdb_list(obd);
241 sema_init(&mgs->mgs_sem, 1);
243 /* Start the service threads */
245 ptlrpc_init_svc(MGS_NBUFS, MGS_BUFSIZE, MGS_MAXREQSIZE,
246 MGS_MAXREPSIZE, MGS_REQUEST_PORTAL,
247 MGC_REPLY_PORTAL, 2000,
248 mgs_handle, LUSTRE_MGS_NAME,
249 obd->obd_proc_entry, target_print_req,
250 MGS_THREADS_AUTO_MIN, MGS_THREADS_AUTO_MAX,
251 "ll_mgs", LCT_MD_THREAD);
253 if (!mgs->mgs_service) {
254 CERROR("failed to start service\n");
255 GOTO(err_llog, rc = -ENOMEM);
258 rc = ptlrpc_start_threads(obd, mgs->mgs_service);
260 GOTO(err_thread, rc);
263 lprocfs_mgs_init_vars(&lvars);
264 if (lprocfs_obd_setup(obd, lvars.obd_vars) == 0) {
265 lproc_mgs_setup(obd);
268 ping_evictor_start();
270 LCONSOLE_INFO("MGS %s started\n", obd->obd_name);
275 ptlrpc_unregister_service(mgs->mgs_service);
277 obd_llog_finish(obd, 0);
279 /* No extra cleanup needed for llog_init_commit_thread() */
282 ldlm_namespace_free(obd->obd_namespace, NULL, 0);
283 obd->obd_namespace = NULL;
285 fsfilt_put_ops(obd->obd_fsops);
287 server_put_mount(obd->obd_name, mnt);
292 static int mgs_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage)
298 case OBD_CLEANUP_EARLY:
299 case OBD_CLEANUP_EXPORTS:
300 rc = obd_llog_finish(obd, 0);
307 * Performs cleanup procedures for passed \a obd given it is mgs obd.
309 static int mgs_cleanup(struct obd_device *obd)
311 struct mgs_obd *mgs = &obd->u.mgs;
314 if (mgs->mgs_sb == NULL)
319 ptlrpc_unregister_service(mgs->mgs_service);
321 mgs_cleanup_fsdb_list(obd);
322 lproc_mgs_cleanup(obd);
325 server_put_mount(obd->obd_name, mgs->mgs_vfsmnt);
328 ldlm_namespace_free(obd->obd_namespace, NULL, 1);
329 obd->obd_namespace = NULL;
331 fsfilt_put_ops(obd->obd_fsops);
333 LCONSOLE_INFO("%s has stopped.\n", obd->obd_name);
337 /* similar to filter_prepare_destroy */
338 static int mgs_get_cfg_lock(struct obd_device *obd, char *fsname,
339 struct lustre_handle *lockh)
341 struct ldlm_res_id res_id;
345 rc = mgc_fsname2resid(fsname, &res_id);
347 rc = ldlm_cli_enqueue_local(obd->obd_namespace, &res_id,
348 LDLM_PLAIN, NULL, LCK_EX,
349 &flags, ldlm_blocking_ast,
350 ldlm_completion_ast, NULL,
351 fsname, 0, NULL, lockh);
353 CERROR("can't take cfg lock for %s (%d)\n", fsname, rc);
358 static int mgs_put_cfg_lock(struct lustre_handle *lockh)
361 ldlm_lock_decref(lockh, LCK_EX);
365 static void mgs_revoke_lock(struct obd_device *obd, char *fsname,
366 struct lustre_handle *lockh)
371 lockrc = mgs_get_cfg_lock(obd, fsname, lockh);
372 if (lockrc != ELDLM_OK)
373 CERROR("lock error %d for fs %s\n", lockrc,
376 mgs_put_cfg_lock(lockh);
383 static int mgs_check_target(struct obd_device *obd, struct mgs_target_info *mti)
388 rc = mgs_check_index(obd, mti);
390 LCONSOLE_ERROR_MSG(0x13b, "%s claims to have registered, but "
391 "this MGS does not know about it. Assuming"
392 " writeconf.\n", mti->mti_svname);
393 mti->mti_flags |= LDD_F_WRITECONF;
395 } else if (rc == -1) {
396 LCONSOLE_ERROR_MSG(0x13c, "Client log %s-client has "
397 "disappeared! Regenerating all logs.\n",
399 mti->mti_flags |= LDD_F_WRITECONF;
402 /* Index is correctly marked as used */
404 /* If the logs don't contain the mti_nids then add
405 them as failover nids */
406 rc = mgs_check_failnid(obd, mti);
412 /* Called whenever a target starts up. Flags indicate first connect, etc. */
413 static int mgs_handle_target_reg(struct ptlrpc_request *req)
415 struct obd_device *obd = req->rq_export->exp_obd;
416 struct lustre_handle lockh;
417 struct mgs_target_info *mti, *rep_mti;
421 mgs_counter_incr(req->rq_export, LPROC_MGS_TARGET_REG);
423 mti = req_capsule_client_get(&req->rq_pill, &RMF_MGS_TARGET_INFO);
424 if (!(mti->mti_flags & (LDD_F_WRITECONF | LDD_F_UPGRADE14 |
426 /* We're just here as a startup ping. */
427 CDEBUG(D_MGS, "Server %s is running on %s\n",
428 mti->mti_svname, obd_export_nid2str(req->rq_export));
429 rc = mgs_check_target(obd, mti);
430 /* above will set appropriate mti flags */
432 /* Nothing wrong, or fatal error */
433 GOTO(out_nolock, rc);
436 /* Revoke the config lock to make sure nobody is reading. */
437 /* Although actually I think it should be alright if
438 someone was reading while we were updating the logs - if we
439 revoke at the end they will just update from where they left off. */
440 lockrc = mgs_get_cfg_lock(obd, mti->mti_fsname, &lockh);
441 if (lockrc != ELDLM_OK) {
442 LCONSOLE_ERROR_MSG(0x13d, "%s: Can't signal other nodes to "
443 "update their configuration (%d). Updating "
444 "local logs anyhow; you might have to "
445 "manually restart other nodes to get the "
446 "latest configuration.\n",
447 obd->obd_name, lockrc);
450 OBD_FAIL_TIMEOUT(OBD_FAIL_MGS_PAUSE_TARGET_REG, 10);
452 /* Log writing contention is handled by the fsdb_sem */
454 if (mti->mti_flags & LDD_F_WRITECONF) {
455 if (mti->mti_flags & LDD_F_SV_TYPE_MDT &&
456 mti->mti_stripe_index == 0) {
457 rc = mgs_erase_logs(obd, mti->mti_fsname);
458 LCONSOLE_WARN("%s: Logs for fs %s were removed by user "
459 "request. All servers must be restarted "
460 "in order to regenerate the logs."
461 "\n", obd->obd_name, mti->mti_fsname);
462 } else if (mti->mti_flags &
463 (LDD_F_SV_TYPE_OST | LDD_F_SV_TYPE_MDT)) {
464 rc = mgs_erase_log(obd, mti->mti_svname);
465 LCONSOLE_WARN("%s: Regenerating %s log by user "
467 obd->obd_name, mti->mti_svname);
469 mti->mti_flags |= LDD_F_UPDATE;
470 /* Erased logs means start from scratch. */
471 mti->mti_flags &= ~LDD_F_UPGRADE14;
475 if (mti->mti_flags & LDD_F_UPGRADE14) {
476 rc = mgs_upgrade_sv_14(obd, mti);
478 CERROR("Can't upgrade from 1.4 (%d)\n", rc);
482 /* We're good to go */
483 mti->mti_flags |= LDD_F_UPDATE;
487 if (mti->mti_flags & LDD_F_UPDATE) {
488 CDEBUG(D_MGS, "updating %s, index=%d\n", mti->mti_svname,
489 mti->mti_stripe_index);
491 /* create or update the target log
492 and update the client/mdt logs */
493 rc = mgs_write_log_target(obd, mti);
495 CERROR("Failed to write %s log (%d)\n",
496 mti->mti_svname, rc);
500 mti->mti_flags &= ~(LDD_F_VIRGIN | LDD_F_UPDATE |
501 LDD_F_NEED_INDEX | LDD_F_WRITECONF |
503 mti->mti_flags |= LDD_F_REWRITE_LDD;
507 /* done with log update */
508 if (lockrc == ELDLM_OK)
509 mgs_put_cfg_lock(&lockh);
511 CDEBUG(D_MGS, "replying with %s, index=%d, rc=%d\n", mti->mti_svname,
512 mti->mti_stripe_index, rc);
513 rc = req_capsule_server_pack(&req->rq_pill);
517 /* send back the whole mti in the reply */
518 rep_mti = req_capsule_server_get(&req->rq_pill, &RMF_MGS_TARGET_INFO);
521 /* Flush logs to disk */
522 fsfilt_sync(obd, obd->u.mgs.mgs_sb);
526 static int mgs_set_info_rpc(struct ptlrpc_request *req)
528 struct obd_device *obd = req->rq_export->exp_obd;
529 struct mgs_send_param *msp, *rep_msp;
530 struct lustre_handle lockh;
532 struct lustre_cfg_bufs bufs;
533 struct lustre_cfg *lcfg;
534 char fsname[MTI_NAME_MAXLEN];
537 msp = req_capsule_client_get(&req->rq_pill, &RMF_MGS_SEND_PARAM);
540 /* Construct lustre_cfg structure to pass to function mgs_setparam */
541 lustre_cfg_bufs_reset(&bufs, NULL);
542 lustre_cfg_bufs_set_string(&bufs, 1, msp->mgs_param);
543 lcfg = lustre_cfg_new(LCFG_PARAM, &bufs);
544 rc = mgs_setparam(obd, lcfg, fsname);
546 CERROR("Error %d in setting the parameter %s for fs %s\n",
547 rc, msp->mgs_param, fsname);
551 /* request for update */
552 mgs_revoke_lock(obd, fsname, &lockh);
554 lustre_cfg_free(lcfg);
556 rc = req_capsule_server_pack(&req->rq_pill);
558 rep_msp = req_capsule_server_get(&req->rq_pill, &RMF_MGS_SEND_PARAM);
564 /* Called whenever a target cleans up. */
565 /* XXX - Currently unused */
566 static int mgs_handle_target_del(struct ptlrpc_request *req)
569 mgs_counter_incr(req->rq_export, LPROC_MGS_TARGET_DEL);
573 /* XXX - Currently unused */
574 static int mgs_handle_exception(struct ptlrpc_request *req)
577 mgs_counter_incr(req->rq_export, LPROC_MGS_EXCEPTION);
581 /* TODO: handle requests in a similar way as MDT: see mdt_handle_common() */
582 int mgs_handle(struct ptlrpc_request *req)
584 int fail = OBD_FAIL_MGS_ALL_REPLY_NET;
588 req_capsule_init(&req->rq_pill, req, RCL_SERVER);
589 OBD_FAIL_TIMEOUT_MS(OBD_FAIL_MGS_PAUSE_REQ, obd_fail_val);
590 if (OBD_FAIL_CHECK(OBD_FAIL_MGS_ALL_REQUEST_NET))
593 LASSERT(current->journal_info == NULL);
594 opc = lustre_msg_get_opc(req->rq_reqmsg);
595 if (opc != MGS_CONNECT) {
596 if (req->rq_export == NULL) {
597 CERROR("lustre_mgs: operation %d on unconnected MGS\n",
599 req->rq_status = -ENOTCONN;
600 GOTO(out, rc = -ENOTCONN);
606 DEBUG_REQ(D_MGS, req, "connect");
607 /* MGS and MDS have same request format for connect */
608 req_capsule_set(&req->rq_pill, &RQF_MDS_CONNECT);
609 rc = target_handle_connect(req);
610 if (!rc && (lustre_msg_get_conn_cnt(req->rq_reqmsg) > 1))
611 /* Make clients trying to reconnect after a MGS restart
612 happy; also requires obd_replayable */
613 lustre_msg_add_op_flags(req->rq_repmsg,
614 MSG_CONNECT_RECONNECT);
617 DEBUG_REQ(D_MGS, req, "disconnect");
618 /* MGS and MDS have same request format for disconnect */
619 req_capsule_set(&req->rq_pill, &RQF_MDS_DISCONNECT);
620 rc = target_handle_disconnect(req);
621 req->rq_status = rc; /* superfluous? */
624 DEBUG_REQ(D_MGS, req, "exception");
625 rc = mgs_handle_exception(req);
628 DEBUG_REQ(D_MGS, req, "target add");
629 req_capsule_set(&req->rq_pill, &RQF_MGS_TARGET_REG);
630 rc = mgs_handle_target_reg(req);
633 DEBUG_REQ(D_MGS, req, "target del");
634 rc = mgs_handle_target_del(req);
637 DEBUG_REQ(D_MGS, req, "set_info");
638 req_capsule_set(&req->rq_pill, &RQF_MGS_SET_INFO);
639 rc = mgs_set_info_rpc(req);
643 DEBUG_REQ(D_MGS, req, "enqueue");
644 req_capsule_set(&req->rq_pill, &RQF_LDLM_ENQUEUE);
645 rc = ldlm_handle_enqueue(req, ldlm_server_completion_ast,
646 ldlm_server_blocking_ast, NULL);
648 case LDLM_BL_CALLBACK:
649 case LDLM_CP_CALLBACK:
650 DEBUG_REQ(D_MGS, req, "callback");
651 CERROR("callbacks should not happen on MGS\n");
656 DEBUG_REQ(D_INFO, req, "ping");
657 req_capsule_set(&req->rq_pill, &RQF_OBD_PING);
658 rc = target_handle_ping(req);
661 DEBUG_REQ(D_MGS, req, "log cancel");
662 rc = -ENOTSUPP; /* la la la */
665 case LLOG_ORIGIN_HANDLE_CREATE:
666 DEBUG_REQ(D_MGS, req, "llog_init");
667 req_capsule_set(&req->rq_pill, &RQF_LLOG_ORIGIN_HANDLE_CREATE);
668 rc = llog_origin_handle_create(req);
670 case LLOG_ORIGIN_HANDLE_NEXT_BLOCK:
671 DEBUG_REQ(D_MGS, req, "llog next block");
672 req_capsule_set(&req->rq_pill,
673 &RQF_LLOG_ORIGIN_HANDLE_NEXT_BLOCK);
674 rc = llog_origin_handle_next_block(req);
676 case LLOG_ORIGIN_HANDLE_READ_HEADER:
677 DEBUG_REQ(D_MGS, req, "llog read header");
678 req_capsule_set(&req->rq_pill,
679 &RQF_LLOG_ORIGIN_HANDLE_READ_HEADER);
680 rc = llog_origin_handle_read_header(req);
682 case LLOG_ORIGIN_HANDLE_CLOSE:
683 DEBUG_REQ(D_MGS, req, "llog close");
684 rc = llog_origin_handle_close(req);
687 DEBUG_REQ(D_MGS, req, "llog catinfo");
688 req_capsule_set(&req->rq_pill, &RQF_LLOG_CATINFO);
689 rc = llog_catinfo(req);
692 req->rq_status = -ENOTSUPP;
693 rc = ptlrpc_error(req);
697 LASSERT(current->journal_info == NULL);
700 CERROR("MGS handle cmd=%d rc=%d\n", opc, rc);
703 target_send_reply(req, rc, fail);
707 static inline int mgs_init_export(struct obd_export *exp)
709 return ldlm_init_export(exp);
712 static inline int mgs_destroy_export(struct obd_export *exp)
716 target_destroy_export(exp);
717 mgs_client_free(exp);
718 ldlm_destroy_export(exp);
723 static int mgs_extract_fs_pool(char * arg, char *fsname, char *poolname)
728 for (ptr = arg; (*ptr != '\0') && (*ptr != '.'); ptr++ ) {
736 strcpy(poolname, ptr);
741 static int mgs_iocontrol_pool(struct obd_device *obd,
742 struct obd_ioctl_data *data)
745 struct lustre_handle lockh;
746 struct lustre_cfg *lcfg = NULL;
747 struct llog_rec_hdr rec;
749 char *poolname = NULL;
752 OBD_ALLOC(fsname, MTI_NAME_MAXLEN);
756 OBD_ALLOC(poolname, LOV_MAXPOOLNAME + 1);
757 if (poolname == NULL) {
761 rec.lrh_len = llog_data_len(data->ioc_plen1);
763 if (data->ioc_type == LUSTRE_CFG_TYPE) {
764 rec.lrh_type = OBD_CFG_REC;
766 CERROR("unknown cfg record type:%d \n", data->ioc_type);
771 if (data->ioc_plen1 > CFS_PAGE_SIZE) {
776 OBD_ALLOC(lcfg, data->ioc_plen1);
778 GOTO(out_pool, rc = -ENOMEM);
780 if (copy_from_user(lcfg, data->ioc_pbuf1, data->ioc_plen1))
781 GOTO(out_pool, rc = -EFAULT);
783 if (lcfg->lcfg_bufcount < 2) {
784 GOTO(out_pool, rc = -EFAULT);
787 /* first arg is always <fsname>.<poolname> */
788 mgs_extract_fs_pool(lustre_cfg_string(lcfg, 1), fsname,
791 switch (lcfg->lcfg_command) {
792 case LCFG_POOL_NEW: {
793 if (lcfg->lcfg_bufcount != 2)
795 rc = mgs_pool_cmd(obd, LCFG_POOL_NEW, fsname,
799 case LCFG_POOL_ADD: {
800 if (lcfg->lcfg_bufcount != 3)
802 rc = mgs_pool_cmd(obd, LCFG_POOL_ADD, fsname, poolname,
803 lustre_cfg_string(lcfg, 2));
806 case LCFG_POOL_REM: {
807 if (lcfg->lcfg_bufcount != 3)
809 rc = mgs_pool_cmd(obd, LCFG_POOL_REM, fsname, poolname,
810 lustre_cfg_string(lcfg, 2));
813 case LCFG_POOL_DEL: {
814 if (lcfg->lcfg_bufcount != 2)
816 rc = mgs_pool_cmd(obd, LCFG_POOL_DEL, fsname,
827 CERROR("OBD_IOC_POOL err %d, cmd %X for pool %s.%s\n",
828 rc, lcfg->lcfg_command, fsname, poolname);
832 /* request for update */
833 mgs_revoke_lock(obd, fsname, &lockh);
837 OBD_FREE(lcfg, data->ioc_plen1);
840 OBD_FREE(fsname, MTI_NAME_MAXLEN);
842 if (poolname != NULL)
843 OBD_FREE(poolname, LOV_MAXPOOLNAME + 1);
848 /* from mdt_iocontrol */
849 int mgs_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
850 void *karg, void *uarg)
852 struct obd_device *obd = exp->exp_obd;
853 struct obd_ioctl_data *data = karg;
854 struct lvfs_run_ctxt saved;
858 CDEBUG(D_IOCTL, "handling ioctl cmd %#x\n", cmd);
862 case OBD_IOC_PARAM: {
863 struct lustre_handle lockh;
864 struct lustre_cfg *lcfg;
865 struct llog_rec_hdr rec;
866 char fsname[MTI_NAME_MAXLEN];
868 rec.lrh_len = llog_data_len(data->ioc_plen1);
870 if (data->ioc_type == LUSTRE_CFG_TYPE) {
871 rec.lrh_type = OBD_CFG_REC;
873 CERROR("unknown cfg record type:%d \n", data->ioc_type);
877 OBD_ALLOC(lcfg, data->ioc_plen1);
880 if (copy_from_user(lcfg, data->ioc_pbuf1, data->ioc_plen1))
881 GOTO(out_free, rc = -EFAULT);
883 if (lcfg->lcfg_bufcount < 1)
884 GOTO(out_free, rc = -EINVAL);
886 rc = mgs_setparam(obd, lcfg, fsname);
888 CERROR("setparam err %d\n", rc);
892 /* Revoke lock so everyone updates. Should be alright if
893 someone was already reading while we were updating the logs,
894 so we don't really need to hold the lock while we're
896 mgs_revoke_lock(obd, fsname, &lockh);
899 OBD_FREE(lcfg, data->ioc_plen1);
904 RETURN(mgs_iocontrol_pool(obd, data));
907 case OBD_IOC_DUMP_LOG: {
908 struct llog_ctxt *ctxt;
909 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
910 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
911 rc = class_config_dump_llog(ctxt, data->ioc_inlbuf1, NULL);
912 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
918 case OBD_IOC_LLOG_CHECK:
919 case OBD_IOC_LLOG_INFO:
920 case OBD_IOC_LLOG_PRINT: {
921 struct llog_ctxt *ctxt;
922 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
924 push_ctxt(&saved, &ctxt->loc_exp->exp_obd->obd_lvfs_ctxt, NULL);
925 rc = llog_ioctl(ctxt, cmd, data);
926 pop_ctxt(&saved, &ctxt->loc_exp->exp_obd->obd_lvfs_ctxt, NULL);
933 CDEBUG(D_INFO, "unknown command %x\n", cmd);
939 /* use obd ops to offer management infrastructure */
940 static struct obd_ops mgs_obd_ops = {
941 .o_owner = THIS_MODULE,
942 .o_connect = mgs_connect,
943 .o_reconnect = mgs_reconnect,
944 .o_disconnect = mgs_disconnect,
945 .o_setup = mgs_setup,
946 .o_precleanup = mgs_precleanup,
947 .o_cleanup = mgs_cleanup,
948 .o_init_export = mgs_init_export,
949 .o_destroy_export = mgs_destroy_export,
950 .o_iocontrol = mgs_iocontrol,
951 .o_llog_init = mgs_llog_init,
952 .o_llog_finish = mgs_llog_finish
955 static int __init mgs_init(void)
957 struct lprocfs_static_vars lvars;
959 lprocfs_mgs_init_vars(&lvars);
960 class_register_type(&mgs_obd_ops, NULL,
961 lvars.module_vars, LUSTRE_MGS_NAME, NULL);
966 static void /*__exit*/ mgs_exit(void)
968 class_unregister_type(LUSTRE_MGS_NAME);
971 MODULE_AUTHOR("Sun Microsystems, Inc. <http://www.lustre.org/>");
972 MODULE_DESCRIPTION("Lustre Management Server (MGS)");
973 MODULE_LICENSE("GPL");
975 module_init(mgs_init);
976 module_exit(mgs_exit);