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 (c) 2005, 2010, Oracle and/or its affiliates. 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
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"
62 #include <lustre_param.h>
64 /* Establish a connection to the MGS.*/
65 static int mgs_connect(struct lustre_handle *conn, struct obd_device *obd,
66 struct obd_uuid *cluuid, struct obd_connect_data *data,
69 struct obd_export *exp;
73 if (!conn || !obd || !cluuid)
76 rc = class_connect(conn, obd, cluuid);
79 exp = class_conn2export(conn);
82 mgs_counter_incr(exp, LPROC_MGS_CONNECT);
85 data->ocd_connect_flags &= MGS_CONNECT_SUPPORTED;
86 exp->exp_connect_flags = data->ocd_connect_flags;
87 data->ocd_version = LUSTRE_VERSION_CODE;
90 rc = mgs_export_stats_init(obd, exp, 0, localdata);
92 class_disconnect(exp);
94 class_export_put(exp);
100 static int mgs_reconnect(struct obd_export *exp, struct obd_device *obd,
101 struct obd_uuid *cluuid, struct obd_connect_data *data,
106 if (exp == NULL || obd == NULL || cluuid == NULL)
109 mgs_counter_incr(exp, LPROC_MGS_CONNECT);
112 data->ocd_connect_flags &= MGS_CONNECT_SUPPORTED;
113 exp->exp_connect_flags = data->ocd_connect_flags;
114 data->ocd_version = LUSTRE_VERSION_CODE;
117 RETURN(mgs_export_stats_init(obd, exp, 1, localdata));
120 static int mgs_disconnect(struct obd_export *exp)
127 class_export_get(exp);
128 mgs_counter_incr(exp, LPROC_MGS_DISCONNECT);
130 rc = server_disconnect_export(exp);
132 class_export_put(exp);
136 static int mgs_cleanup(struct obd_device *obd);
137 static int mgs_handle(struct ptlrpc_request *req);
139 /* Start the MGS obd */
140 static int mgs_setup(struct obd_device *obd, obd_count len, void *buf)
142 struct lprocfs_static_vars lvars;
143 struct mgs_obd *mgs = &obd->u.mgs;
144 struct lustre_mount_info *lmi;
145 struct lustre_sb_info *lsi;
146 struct llog_ctxt *ctxt;
147 struct vfsmount *mnt;
151 CDEBUG(D_CONFIG, "Starting MGS\n");
154 lmi = server_get_mount(obd->obd_name);
156 RETURN(rc = -EINVAL);
159 lsi = s2lsi(lmi->lmi_sb);
160 obd->obd_fsops = fsfilt_get_ops(MT_STR(lsi->lsi_ldd));
161 if (IS_ERR(obd->obd_fsops))
162 GOTO(err_put, rc = PTR_ERR(obd->obd_fsops));
164 if (lvfs_check_rdonly(lvfs_sbdev(mnt->mnt_sb))) {
165 CERROR("%s: Underlying device is marked as read-only. "
166 "Setup failed\n", obd->obd_name);
167 GOTO(err_ops, rc = -EROFS);
170 /* namespace for mgs llog */
171 obd->obd_namespace = ldlm_namespace_new(obd, "MGS", LDLM_NAMESPACE_SERVER,
172 LDLM_NAMESPACE_MODEST);
173 if (obd->obd_namespace == NULL)
174 GOTO(err_ops, rc = -ENOMEM);
177 ptlrpc_init_client(LDLM_CB_REQUEST_PORTAL, LDLM_CB_REPLY_PORTAL,
178 "mgs_ldlm_client", &obd->obd_ldlm_client);
180 rc = mgs_fs_setup(obd, mnt);
182 CERROR("%s: MGS filesystem method init failed: rc = %d\n",
187 rc = llog_setup(obd, LLOG_CONFIG_ORIG_CTXT, obd, 0, NULL,
192 /* No recovery for MGC's */
193 obd->obd_replayable = 0;
195 /* Internal mgs setup */
196 mgs_init_fsdb_list(obd);
197 sema_init(&mgs->mgs_sem, 1);
200 lprocfs_mgs_init_vars(&lvars);
201 if (lprocfs_obd_setup(obd, lvars.obd_vars) == 0)
202 lproc_mgs_setup(obd);
204 /* Start the service threads */
206 ptlrpc_init_svc(MGS_NBUFS, MGS_BUFSIZE, MGS_MAXREQSIZE,
207 MGS_MAXREPSIZE, MGS_REQUEST_PORTAL,
209 mgs_handle, LUSTRE_MGS_NAME,
210 obd->obd_proc_entry, NULL,
211 MGS_THREADS_AUTO_MIN, MGS_THREADS_AUTO_MAX,
214 if (!mgs->mgs_service) {
215 CERROR("failed to start service\n");
216 GOTO(err_llog, rc = -ENOMEM);
219 rc = ptlrpc_start_threads(obd, mgs->mgs_service);
221 GOTO(err_thread, rc);
223 ping_evictor_start();
225 LCONSOLE_INFO("MGS %s started\n", obd->obd_name);
230 ptlrpc_unregister_service(mgs->mgs_service);
232 lproc_mgs_cleanup(obd);
233 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
237 /* No extra cleanup needed for llog_init_commit_thread() */
240 ldlm_namespace_free(obd->obd_namespace, NULL, 0);
241 obd->obd_namespace = NULL;
243 fsfilt_put_ops(obd->obd_fsops);
245 server_put_mount(obd->obd_name, mnt);
250 static int mgs_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage)
256 case OBD_CLEANUP_EARLY:
257 case OBD_CLEANUP_EXPORTS:
259 case OBD_CLEANUP_SELF_EXP:
260 llog_cleanup(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT));
261 rc = obd_llog_finish(obd, 0);
263 case OBD_CLEANUP_OBD:
269 static int mgs_cleanup(struct obd_device *obd)
271 struct mgs_obd *mgs = &obd->u.mgs;
274 if (mgs->mgs_sb == NULL)
279 ptlrpc_unregister_service(mgs->mgs_service);
281 mgs_cleanup_fsdb_list(obd);
282 lproc_mgs_cleanup(obd);
285 server_put_mount(obd->obd_name, mgs->mgs_vfsmnt);
288 ldlm_namespace_free(obd->obd_namespace, NULL, 1);
289 obd->obd_namespace = NULL;
290 fsfilt_put_ops(obd->obd_fsops);
292 LCONSOLE_INFO("%s has stopped.\n", obd->obd_name);
296 /* similar to filter_prepare_destroy */
297 static int mgs_get_cfg_lock(struct obd_device *obd, char *fsname,
298 struct lustre_handle *lockh)
300 struct ldlm_res_id res_id;
304 rc = mgc_fsname2resid(fsname, &res_id);
306 rc = ldlm_cli_enqueue_local(obd->obd_namespace, &res_id,
307 LDLM_PLAIN, NULL, LCK_EX,
308 &flags, ldlm_blocking_ast,
309 ldlm_completion_ast, NULL,
310 fsname, 0, NULL, lockh);
312 CERROR("can't take cfg lock for %s (%d)\n", fsname, rc);
317 static int mgs_put_cfg_lock(struct lustre_handle *lockh)
320 ldlm_lock_decref(lockh, LCK_EX);
324 static void mgs_revoke_lock(struct obd_device *obd, char *fsname,
325 struct lustre_handle *lockh)
330 lockrc = mgs_get_cfg_lock(obd, fsname, lockh);
331 if (lockrc != ELDLM_OK)
332 CERROR("lock error %d for fs %s\n", lockrc,
335 mgs_put_cfg_lock(lockh);
342 static int mgs_check_target(struct obd_device *obd, struct mgs_target_info *mti)
347 rc = mgs_check_index(obd, mti);
349 LCONSOLE_ERROR_MSG(0x13b, "%s claims to have registered, but "
350 "this MGS does not know about it, preventing "
351 "registration.\n", mti->mti_svname);
353 } else if (rc == -1) {
354 LCONSOLE_ERROR_MSG(0x13c, "Client log %s-client has "
355 "disappeared! Regenerating all logs.\n",
357 mti->mti_flags |= LDD_F_WRITECONF;
360 /* Index is correctly marked as used */
362 /* If the logs don't contain the mti_nids then add
363 them as failover nids */
364 rc = mgs_check_failnid(obd, mti);
370 /* Ensure this is not a failover node that is connecting first*/
371 static int mgs_check_failover_reg(struct mgs_target_info *mti)
377 ptr = mti->mti_params;
378 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
379 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
380 for (i = 0; i < mti->mti_nid_count; i++) {
381 if (nid == mti->mti_nids[i]) {
382 LCONSOLE_WARN("Denying initial registra"
383 "tion attempt from nid %s"
384 ", specified as failover"
385 "\n",libcfs_nid2str(nid));
386 return -EADDRNOTAVAIL;
394 /* Called whenever a target starts up. Flags indicate first connect, etc. */
395 static int mgs_handle_target_reg(struct ptlrpc_request *req)
397 struct obd_device *obd = req->rq_export->exp_obd;
398 struct lustre_handle lockh;
399 struct mgs_target_info *mti, *rep_mti;
400 int rep_size[] = { sizeof(struct ptlrpc_body), sizeof(*mti) };
404 mgs_counter_incr(req->rq_export, LPROC_MGS_TARGET_REG);
406 mti = lustre_swab_reqbuf(req, REQ_REC_OFF, sizeof(*mti),
407 lustre_swab_mgs_target_info);
410 if (mti->mti_flags & LDD_F_NEED_INDEX)
411 mti->mti_flags |= LDD_F_WRITECONF;
413 if (!(mti->mti_flags & (LDD_F_WRITECONF | LDD_F_UPGRADE14 |
415 /* We're just here as a startup ping. */
416 CDEBUG(D_MGS, "Server %s is running on %s\n",
417 mti->mti_svname, obd_export_nid2str(req->rq_export));
418 rc = mgs_check_target(obd, mti);
420 /* above will set appropriate mti flags */
422 /* Nothing wrong, or fatal error */
423 GOTO(out_nolock, rc);
425 if ((rc = mgs_check_failover_reg(mti)))
426 GOTO(out_nolock, rc);
429 /* Revoke the config lock to make sure nobody is reading. */
430 /* Although actually I think it should be alright if
431 someone was reading while we were updating the logs - if we
432 revoke at the end they will just update from where they left off. */
433 lockrc = mgs_get_cfg_lock(obd, mti->mti_fsname, &lockh);
434 if (lockrc != ELDLM_OK) {
435 LCONSOLE_ERROR_MSG(0x13d, "%s: Can't signal other nodes to "
436 "update their configuration (%d). Updating "
437 "local logs anyhow; you might have to "
438 "manually restart other nodes to get the "
439 "latest configuration.\n",
440 obd->obd_name, lockrc);
443 OBD_FAIL_TIMEOUT(OBD_FAIL_MGS_PAUSE_TARGET_REG, 10);
445 /* Log writing contention is handled by the fsdb_sem */
447 if (mti->mti_flags & LDD_F_WRITECONF) {
448 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
449 rc = mgs_erase_logs(obd, mti->mti_fsname);
450 LCONSOLE_WARN("%s: Logs for fs %s were removed by user "
451 "request. All servers must be restarted "
452 "in order to regenerate the logs."
453 "\n", obd->obd_name, mti->mti_fsname);
454 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
455 rc = mgs_erase_log(obd, mti->mti_svname);
456 LCONSOLE_WARN("%s: Regenerating %s log by user "
458 obd->obd_name, mti->mti_svname);
460 mti->mti_flags |= LDD_F_UPDATE;
461 /* Erased logs means start from scratch. */
462 mti->mti_flags &= ~LDD_F_UPGRADE14;
466 if (mti->mti_flags & LDD_F_UPGRADE14) {
467 rc = mgs_upgrade_sv_14(obd, mti);
469 CERROR("Can't upgrade from 1.4 (%d)\n", rc);
473 /* We're good to go */
474 mti->mti_flags |= LDD_F_UPDATE;
478 if (mti->mti_flags & LDD_F_UPDATE) {
479 CDEBUG(D_MGS, "updating %s, index=%d\n", mti->mti_svname,
480 mti->mti_stripe_index);
482 /* create or update the target log
483 and update the client/mdt logs */
484 rc = mgs_write_log_target(obd, mti);
486 CERROR("Failed to write %s log (%d)\n",
487 mti->mti_svname, rc);
491 mti->mti_flags &= ~(LDD_F_VIRGIN | LDD_F_UPDATE |
492 LDD_F_NEED_INDEX | LDD_F_WRITECONF |
494 mti->mti_flags |= LDD_F_REWRITE_LDD;
498 /* done with log update */
499 if (lockrc == ELDLM_OK)
500 mgs_put_cfg_lock(&lockh);
502 CDEBUG(D_MGS, "replying with %s, index=%d, rc=%d\n", mti->mti_svname,
503 mti->mti_stripe_index, rc);
505 rc = lustre_pack_reply(req, 2, rep_size, NULL);
506 /* send back the whole mti in the reply */
507 rep_mti = lustre_msg_buf(req->rq_repmsg, REPLY_REC_OFF,
509 memcpy(rep_mti, mti, sizeof(*rep_mti));
511 /* Flush logs to disk */
512 fsfilt_sync(obd, obd->u.mgs.mgs_sb);
516 static int mgs_set_info_rpc(struct ptlrpc_request *req)
518 struct obd_device *obd = req->rq_export->exp_obd;
519 struct mgs_send_param *msp, *rep_msp;
520 struct lustre_handle lockh;
521 int rep_size[] = { sizeof(struct ptlrpc_body), sizeof(*msp) };
523 struct lustre_cfg_bufs bufs;
524 struct lustre_cfg *lcfg;
525 char fsname[MTI_NAME_MAXLEN];
528 msp = lustre_swab_reqbuf(req, REQ_REC_OFF, sizeof(*msp), NULL);
530 /* Construct lustre_cfg structure to pass to function mgs_setparam */
531 lustre_cfg_bufs_reset(&bufs, NULL);
532 lustre_cfg_bufs_set_string(&bufs, 1, msp->mgs_param);
533 lcfg = lustre_cfg_new(LCFG_PARAM, &bufs);
534 rc = mgs_setparam(obd, lcfg, fsname);
536 CERROR("Error %d in setting the parameter %s for fs %s\n",
537 rc, msp->mgs_param, fsname);
541 /* request for update */
542 mgs_revoke_lock(obd, fsname, &lockh);
544 lustre_cfg_free(lcfg);
546 lustre_pack_reply(req, 2, rep_size, NULL);
547 rep_msp = lustre_msg_buf(req->rq_repmsg, REPLY_REC_OFF,
549 memcpy(rep_msp, msp, sizeof(*rep_msp));
554 /* Called whenever a target cleans up. */
555 /* XXX - Currently unused */
556 static int mgs_handle_target_del(struct ptlrpc_request *req)
559 mgs_counter_incr(req->rq_export, LPROC_MGS_TARGET_DEL);
563 /* XXX - Currently unused */
564 static int mgs_handle_exception(struct ptlrpc_request *req)
567 mgs_counter_incr(req->rq_export, LPROC_MGS_EXCEPTION);
571 int mgs_handle(struct ptlrpc_request *req)
573 int fail = OBD_FAIL_MGS_ALL_REPLY_NET;
577 OBD_FAIL_TIMEOUT_MS(OBD_FAIL_MGS_PAUSE_REQ, obd_fail_val);
578 OBD_FAIL_RETURN(OBD_FAIL_MGS_ALL_REQUEST_NET, 0);
580 LASSERT(current->journal_info == NULL);
581 opc = lustre_msg_get_opc(req->rq_reqmsg);
582 if (opc != MGS_CONNECT) {
583 if (!class_connected_export(req->rq_export)) {
584 CERROR("lustre_mgs: operation %d on unconnected MGS\n",
586 req->rq_status = -ENOTCONN;
587 GOTO(out, rc = -ENOTCONN);
593 DEBUG_REQ(D_MGS, req, "connect");
594 rc = target_handle_connect(req, mgs_handle);
595 if (!rc && (lustre_msg_get_conn_cnt(req->rq_reqmsg) > 1))
596 /* Make clients trying to reconnect after a MGS restart
597 happy; also requires obd_replayable */
598 lustre_msg_add_op_flags(req->rq_repmsg,
599 MSG_CONNECT_RECONNECT);
602 DEBUG_REQ(D_MGS, req, "disconnect");
603 rc = target_handle_disconnect(req);
604 req->rq_status = rc; /* superfluous? */
607 DEBUG_REQ(D_MGS, req, "exception");
608 rc = mgs_handle_exception(req);
611 DEBUG_REQ(D_MGS, req, "target add");
612 rc = mgs_handle_target_reg(req);
615 DEBUG_REQ(D_MGS, req, "target del");
616 rc = mgs_handle_target_del(req);
619 rc = mgs_set_info_rpc(req);
623 DEBUG_REQ(D_MGS, req, "enqueue");
624 rc = ldlm_handle_enqueue(req, ldlm_server_completion_ast,
625 ldlm_server_blocking_ast, NULL);
627 case LDLM_BL_CALLBACK:
628 case LDLM_CP_CALLBACK:
629 DEBUG_REQ(D_MGS, req, "callback");
630 CERROR("callbacks should not happen on MGS\n");
635 DEBUG_REQ(D_INFO, req, "ping");
636 rc = target_handle_ping(req);
639 DEBUG_REQ(D_MGS, req, "log cancel");
640 rc = -ENOTSUPP; /* la la la */
643 case LLOG_ORIGIN_HANDLE_CREATE:
644 DEBUG_REQ(D_MGS, req, "llog_init");
645 rc = llog_origin_handle_create(req);
647 case LLOG_ORIGIN_HANDLE_NEXT_BLOCK:
648 DEBUG_REQ(D_MGS, req, "llog next block");
649 rc = llog_origin_handle_next_block(req);
651 case LLOG_ORIGIN_HANDLE_READ_HEADER:
652 DEBUG_REQ(D_MGS, req, "llog read header");
653 rc = llog_origin_handle_read_header(req);
655 case LLOG_ORIGIN_HANDLE_CLOSE:
656 DEBUG_REQ(D_MGS, req, "llog close");
657 rc = llog_origin_handle_close(req);
660 DEBUG_REQ(D_MGS, req, "llog catinfo");
661 rc = llog_catinfo(req);
664 req->rq_status = -ENOTSUPP;
665 rc = ptlrpc_error(req);
669 LASSERT(current->journal_info == NULL);
672 CERROR("MGS handle cmd=%d rc=%d\n", opc, rc);
675 target_send_reply(req, rc, fail);
679 static inline int mgs_init_export(struct obd_export *exp)
681 spin_lock(&exp->exp_lock);
682 exp->exp_connecting = 1;
683 spin_unlock(&exp->exp_lock);
685 return ldlm_init_export(exp);
688 static inline int mgs_destroy_export(struct obd_export *exp)
692 target_destroy_export(exp);
693 ldlm_destroy_export(exp);
694 mgs_client_free(exp);
699 static int mgs_extract_fs_pool(char * arg, char *fsname, char *poolname)
704 for (ptr = arg; (*ptr != '\0') && (*ptr != '.'); ptr++ ) {
712 strcpy(poolname, ptr);
717 static int mgs_iocontrol_pool(struct obd_device *obd,
718 struct obd_ioctl_data *data)
721 struct lustre_handle lockh;
722 struct lustre_cfg *lcfg = NULL;
723 struct llog_rec_hdr rec;
725 char *poolname = NULL;
728 OBD_ALLOC(fsname, MTI_NAME_MAXLEN);
732 OBD_ALLOC(poolname, LOV_MAXPOOLNAME + 1);
733 if (poolname == NULL) {
737 rec.lrh_len = llog_data_len(data->ioc_plen1);
739 if (data->ioc_type == LUSTRE_CFG_TYPE) {
740 rec.lrh_type = OBD_CFG_REC;
742 CERROR("unknown cfg record type:%d \n", data->ioc_type);
747 if (data->ioc_plen1 > CFS_PAGE_SIZE) {
752 OBD_ALLOC(lcfg, data->ioc_plen1);
757 rc = copy_from_user(lcfg, data->ioc_pbuf1, data->ioc_plen1);
761 if (lcfg->lcfg_bufcount < 2) {
766 /* first arg is always <fsname>.<poolname> */
767 mgs_extract_fs_pool(lustre_cfg_string(lcfg, 1), fsname,
770 switch (lcfg->lcfg_command) {
771 case LCFG_POOL_NEW: {
772 if (lcfg->lcfg_bufcount != 2)
774 rc = mgs_pool_cmd(obd, LCFG_POOL_NEW, fsname,
778 case LCFG_POOL_ADD: {
779 if (lcfg->lcfg_bufcount != 3)
781 rc = mgs_pool_cmd(obd, LCFG_POOL_ADD, fsname, poolname,
782 lustre_cfg_string(lcfg, 2));
785 case LCFG_POOL_REM: {
786 if (lcfg->lcfg_bufcount != 3)
788 rc = mgs_pool_cmd(obd, LCFG_POOL_REM, fsname, poolname,
789 lustre_cfg_string(lcfg, 2));
792 case LCFG_POOL_DEL: {
793 if (lcfg->lcfg_bufcount != 2)
795 rc = mgs_pool_cmd(obd, LCFG_POOL_DEL, fsname,
806 CERROR("OBD_IOC_POOL err %d, cmd %X for pool %s.%s\n",
807 rc, lcfg->lcfg_command, fsname, poolname);
811 /* request for update */
812 mgs_revoke_lock(obd, fsname, &lockh);
816 OBD_FREE(lcfg, data->ioc_plen1);
819 OBD_FREE(fsname, MTI_NAME_MAXLEN);
821 if (poolname != NULL)
822 OBD_FREE(poolname, LOV_MAXPOOLNAME + 1);
827 /* from mdt_iocontrol */
828 int mgs_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
829 void *karg, void *uarg)
831 struct obd_device *obd = exp->exp_obd;
832 struct obd_ioctl_data *data = karg;
833 struct lvfs_run_ctxt saved;
837 CDEBUG(D_IOCTL, "handling ioctl cmd %#x\n", cmd);
841 case OBD_IOC_PARAM: {
842 struct lustre_handle lockh;
843 struct lustre_cfg *lcfg;
844 struct llog_rec_hdr rec;
845 char fsname[MTI_NAME_MAXLEN];
847 rec.lrh_len = llog_data_len(data->ioc_plen1);
849 if (data->ioc_type == LUSTRE_CFG_TYPE) {
850 rec.lrh_type = OBD_CFG_REC;
852 CERROR("unknown cfg record type:%d \n", data->ioc_type);
856 OBD_ALLOC(lcfg, data->ioc_plen1);
859 rc = copy_from_user(lcfg, data->ioc_pbuf1, data->ioc_plen1);
863 if (lcfg->lcfg_bufcount < 1)
864 GOTO(out_free, rc = -EINVAL);
866 rc = mgs_setparam(obd, lcfg, fsname);
868 CERROR("setparam err %d\n", rc);
872 /* Revoke lock so everyone updates. Should be alright if
873 someone was already reading while we were updating the logs,
874 so we don't really need to hold the lock while we're
876 mgs_revoke_lock(obd, fsname, &lockh);
879 OBD_FREE(lcfg, data->ioc_plen1);
884 RETURN(mgs_iocontrol_pool(obd, data));
887 case OBD_IOC_DUMP_LOG: {
888 struct llog_ctxt *ctxt =
889 llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
890 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
891 rc = class_config_dump_llog(ctxt, data->ioc_inlbuf1, NULL);
892 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
900 case OBD_IOC_LLOG_CHECK:
901 case OBD_IOC_LLOG_INFO:
902 case OBD_IOC_LLOG_PRINT: {
903 struct llog_ctxt *ctxt =
904 llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
906 push_ctxt(&saved, &ctxt->loc_exp->exp_obd->obd_lvfs_ctxt, NULL);
907 rc = llog_ioctl(ctxt, cmd, data);
908 pop_ctxt(&saved, &ctxt->loc_exp->exp_obd->obd_lvfs_ctxt, NULL);
915 CDEBUG(D_INFO, "unknown command %x\n", cmd);
921 /* use obd ops to offer management infrastructure */
922 static struct obd_ops mgs_obd_ops = {
923 .o_owner = THIS_MODULE,
924 .o_connect = mgs_connect,
925 .o_reconnect = mgs_reconnect,
926 .o_disconnect = mgs_disconnect,
927 .o_setup = mgs_setup,
928 .o_precleanup = mgs_precleanup,
929 .o_cleanup = mgs_cleanup,
930 .o_init_export = mgs_init_export,
931 .o_destroy_export = mgs_destroy_export,
932 .o_iocontrol = mgs_iocontrol,
935 static int __init mgs_init(void)
937 struct lprocfs_static_vars lvars;
939 lprocfs_mgs_init_vars(&lvars);
940 class_register_type(&mgs_obd_ops, lvars.module_vars, LUSTRE_MGS_NAME);
945 static void /*__exit*/ mgs_exit(void)
947 class_unregister_type(LUSTRE_MGS_NAME);
950 MODULE_AUTHOR("Sun Microsystems, Inc. <http://www.lustre.org/>");
951 MODULE_DESCRIPTION("Lustre Management Server (MGS)");
952 MODULE_LICENSE("GPL");
954 module_init(mgs_init);
955 module_exit(mgs_exit);