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 obd_export **exp, struct obd_device *obd,
67 struct obd_uuid *cluuid, struct obd_connect_data *data,
70 struct obd_export *lexp;
71 struct lustre_handle conn = { 0 };
75 if (!exp || !obd || !cluuid)
78 rc = class_connect(&conn, obd, cluuid);
82 lexp = class_conn2export(&conn);
85 mgs_counter_incr(lexp, LPROC_MGS_CONNECT);
88 data->ocd_connect_flags &= MGS_CONNECT_SUPPORTED;
89 lexp->exp_connect_flags = data->ocd_connect_flags;
90 data->ocd_version = LUSTRE_VERSION_CODE;
93 rc = mgs_client_add(obd, lexp, localdata);
96 class_disconnect(lexp);
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 rc = server_disconnect_export(exp);
137 class_export_put(exp);
141 static int mgs_cleanup(struct obd_device *obd);
142 static int mgs_handle(struct ptlrpc_request *req);
144 static int mgs_llog_init(struct obd_device *obd, struct obd_llog_group *olg,
145 struct obd_device *tgt, int *index)
150 LASSERT(olg == &obd->obd_olg);
151 rc = llog_setup(obd, olg, LLOG_CONFIG_ORIG_CTXT, obd, 0, NULL,
156 static int mgs_llog_finish(struct obd_device *obd, int count)
158 struct llog_ctxt *ctxt;
162 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
164 rc = llog_cleanup(ctxt);
169 /* Start the MGS obd */
170 static int mgs_setup(struct obd_device *obd, struct lustre_cfg *lcfg)
172 struct lprocfs_static_vars lvars;
173 struct mgs_obd *mgs = &obd->u.mgs;
174 struct lustre_mount_info *lmi;
175 struct lustre_sb_info *lsi;
176 struct vfsmount *mnt;
180 CDEBUG(D_CONFIG, "Starting MGS\n");
183 lmi = server_get_mount(obd->obd_name);
185 RETURN(rc = -EINVAL);
188 lsi = s2lsi(lmi->lmi_sb);
189 obd->obd_fsops = fsfilt_get_ops(MT_STR(lsi->lsi_ldd));
190 if (IS_ERR(obd->obd_fsops))
191 GOTO(err_put, rc = PTR_ERR(obd->obd_fsops));
193 if (lvfs_check_rdonly(lvfs_sbdev(mnt->mnt_sb))) {
194 CERROR("%s: Underlying device is marked as read-only. "
195 "Setup failed\n", obd->obd_name);
196 GOTO(err_ops, rc = -EROFS);
199 /* namespace for mgs llog */
200 obd->obd_namespace = ldlm_namespace_new(obd ,"MGS", LDLM_NAMESPACE_SERVER,
201 LDLM_NAMESPACE_MODEST);
202 if (obd->obd_namespace == NULL)
203 GOTO(err_ops, rc = -ENOMEM);
206 ptlrpc_init_client(LDLM_CB_REQUEST_PORTAL, LDLM_CB_REPLY_PORTAL,
207 "mgs_ldlm_client", &obd->obd_ldlm_client);
209 rc = mgs_fs_setup(obd, mnt);
211 CERROR("%s: MGS filesystem method init failed: rc = %d\n",
216 rc = obd_llog_init(obd, &obd->obd_olg, obd, NULL);
220 /* No recovery for MGC's */
221 obd->obd_replayable = 0;
223 /* Internal mgs setup */
224 mgs_init_fsdb_list(obd);
225 sema_init(&mgs->mgs_sem, 1);
228 lprocfs_mgs_init_vars(&lvars);
229 if (lprocfs_obd_setup(obd, lvars.obd_vars) == 0)
230 lproc_mgs_setup(obd);
232 /* Start the service threads */
234 ptlrpc_init_svc(MGS_NBUFS, MGS_BUFSIZE, MGS_MAXREQSIZE,
235 MGS_MAXREPSIZE, MGS_REQUEST_PORTAL,
237 mgs_handle, LUSTRE_MGS_NAME,
238 obd->obd_proc_entry, target_print_req,
239 MGS_THREADS_AUTO_MIN, MGS_THREADS_AUTO_MAX,
240 "ll_mgs", LCT_MD_THREAD, NULL);
242 if (!mgs->mgs_service) {
243 CERROR("failed to start service\n");
244 GOTO(err_llog, rc = -ENOMEM);
247 rc = ptlrpc_start_threads(obd, mgs->mgs_service);
249 GOTO(err_thread, rc);
251 ping_evictor_start();
253 LCONSOLE_INFO("MGS %s started\n", obd->obd_name);
258 ptlrpc_unregister_service(mgs->mgs_service);
260 lproc_mgs_cleanup(obd);
261 obd_llog_finish(obd, 0);
263 /* No extra cleanup needed for llog_init_commit_thread() */
266 ldlm_namespace_free(obd->obd_namespace, NULL, 0);
267 obd->obd_namespace = NULL;
269 fsfilt_put_ops(obd->obd_fsops);
271 server_put_mount(obd->obd_name, mnt);
276 static int mgs_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage)
282 case OBD_CLEANUP_EARLY:
283 case OBD_CLEANUP_EXPORTS:
284 rc = obd_llog_finish(obd, 0);
291 * Performs cleanup procedures for passed \a obd given it is mgs obd.
293 static int mgs_cleanup(struct obd_device *obd)
295 struct mgs_obd *mgs = &obd->u.mgs;
298 if (mgs->mgs_sb == NULL)
303 ptlrpc_unregister_service(mgs->mgs_service);
305 mgs_cleanup_fsdb_list(obd);
306 lproc_mgs_cleanup(obd);
309 server_put_mount(obd->obd_name, mgs->mgs_vfsmnt);
312 ldlm_namespace_free(obd->obd_namespace, NULL, 1);
313 obd->obd_namespace = NULL;
315 fsfilt_put_ops(obd->obd_fsops);
317 LCONSOLE_INFO("%s has stopped.\n", obd->obd_name);
321 /* similar to filter_prepare_destroy */
322 static int mgs_get_cfg_lock(struct obd_device *obd, char *fsname,
323 struct lustre_handle *lockh)
325 struct ldlm_res_id res_id;
329 rc = mgc_fsname2resid(fsname, &res_id);
331 rc = ldlm_cli_enqueue_local(obd->obd_namespace, &res_id,
332 LDLM_PLAIN, NULL, LCK_EX,
333 &flags, ldlm_blocking_ast,
334 ldlm_completion_ast, NULL,
335 fsname, 0, NULL, lockh);
337 CERROR("can't take cfg lock for %s (%d)\n", fsname, rc);
342 static int mgs_put_cfg_lock(struct lustre_handle *lockh)
345 ldlm_lock_decref(lockh, LCK_EX);
349 static void mgs_revoke_lock(struct obd_device *obd, char *fsname,
350 struct lustre_handle *lockh)
355 lockrc = mgs_get_cfg_lock(obd, fsname, lockh);
356 if (lockrc != ELDLM_OK)
357 CERROR("lock error %d for fs %s\n", lockrc,
360 mgs_put_cfg_lock(lockh);
367 static int mgs_check_target(struct obd_device *obd, struct mgs_target_info *mti)
372 rc = mgs_check_index(obd, mti);
374 LCONSOLE_ERROR_MSG(0x13b, "%s claims to have registered, but "
375 "this MGS does not know about it, preventing "
376 "registration.\n", mti->mti_svname);
378 } else if (rc == -1) {
379 LCONSOLE_ERROR_MSG(0x13c, "Client log %s-client has "
380 "disappeared! Regenerating all logs.\n",
382 mti->mti_flags |= LDD_F_WRITECONF;
385 /* Index is correctly marked as used */
387 /* If the logs don't contain the mti_nids then add
388 them as failover nids */
389 rc = mgs_check_failnid(obd, mti);
395 /* Called whenever a target starts up. Flags indicate first connect, etc. */
396 static int mgs_handle_target_reg(struct ptlrpc_request *req)
398 struct obd_device *obd = req->rq_export->exp_obd;
399 struct lustre_handle lockh;
400 struct mgs_target_info *mti, *rep_mti;
404 mgs_counter_incr(req->rq_export, LPROC_MGS_TARGET_REG);
406 mti = req_capsule_client_get(&req->rq_pill, &RMF_MGS_TARGET_INFO);
407 if (!(mti->mti_flags & (LDD_F_WRITECONF | LDD_F_UPGRADE14 |
409 /* We're just here as a startup ping. */
410 CDEBUG(D_MGS, "Server %s is running on %s\n",
411 mti->mti_svname, obd_export_nid2str(req->rq_export));
412 rc = mgs_check_target(obd, mti);
413 /* above will set appropriate mti flags */
415 /* Nothing wrong, or fatal error */
416 GOTO(out_nolock, rc);
419 /* Revoke the config lock to make sure nobody is reading. */
420 /* Although actually I think it should be alright if
421 someone was reading while we were updating the logs - if we
422 revoke at the end they will just update from where they left off. */
423 lockrc = mgs_get_cfg_lock(obd, mti->mti_fsname, &lockh);
424 if (lockrc != ELDLM_OK) {
425 LCONSOLE_ERROR_MSG(0x13d, "%s: Can't signal other nodes to "
426 "update their configuration (%d). Updating "
427 "local logs anyhow; you might have to "
428 "manually restart other nodes to get the "
429 "latest configuration.\n",
430 obd->obd_name, lockrc);
433 OBD_FAIL_TIMEOUT(OBD_FAIL_MGS_PAUSE_TARGET_REG, 10);
435 /* Log writing contention is handled by the fsdb_sem */
437 if (mti->mti_flags & LDD_F_WRITECONF) {
438 if (mti->mti_flags & LDD_F_SV_TYPE_MDT &&
439 mti->mti_stripe_index == 0) {
440 rc = mgs_erase_logs(obd, mti->mti_fsname);
441 LCONSOLE_WARN("%s: Logs for fs %s were removed by user "
442 "request. All servers must be restarted "
443 "in order to regenerate the logs."
444 "\n", obd->obd_name, mti->mti_fsname);
445 } else if (mti->mti_flags &
446 (LDD_F_SV_TYPE_OST | LDD_F_SV_TYPE_MDT)) {
447 rc = mgs_erase_log(obd, mti->mti_svname);
448 LCONSOLE_WARN("%s: Regenerating %s log by user "
450 obd->obd_name, mti->mti_svname);
452 mti->mti_flags |= LDD_F_UPDATE;
453 /* Erased logs means start from scratch. */
454 mti->mti_flags &= ~LDD_F_UPGRADE14;
458 if (mti->mti_flags & LDD_F_UPGRADE14) {
459 rc = mgs_upgrade_sv_14(obd, mti);
461 CERROR("Can't upgrade from 1.4 (%d)\n", rc);
465 /* We're good to go */
466 mti->mti_flags |= LDD_F_UPDATE;
470 if (mti->mti_flags & LDD_F_UPDATE) {
471 CDEBUG(D_MGS, "updating %s, index=%d\n", mti->mti_svname,
472 mti->mti_stripe_index);
474 /* create or update the target log
475 and update the client/mdt logs */
476 rc = mgs_write_log_target(obd, mti);
478 CERROR("Failed to write %s log (%d)\n",
479 mti->mti_svname, rc);
483 mti->mti_flags &= ~(LDD_F_VIRGIN | LDD_F_UPDATE |
484 LDD_F_NEED_INDEX | LDD_F_WRITECONF |
486 mti->mti_flags |= LDD_F_REWRITE_LDD;
490 /* done with log update */
491 if (lockrc == ELDLM_OK)
492 mgs_put_cfg_lock(&lockh);
494 CDEBUG(D_MGS, "replying with %s, index=%d, rc=%d\n", mti->mti_svname,
495 mti->mti_stripe_index, rc);
496 rc = req_capsule_server_pack(&req->rq_pill);
500 /* send back the whole mti in the reply */
501 rep_mti = req_capsule_server_get(&req->rq_pill, &RMF_MGS_TARGET_INFO);
504 /* Flush logs to disk */
505 fsfilt_sync(obd, obd->u.mgs.mgs_sb);
509 static int mgs_set_info_rpc(struct ptlrpc_request *req)
511 struct obd_device *obd = req->rq_export->exp_obd;
512 struct mgs_send_param *msp, *rep_msp;
513 struct lustre_handle lockh;
515 struct lustre_cfg_bufs bufs;
516 struct lustre_cfg *lcfg;
517 char fsname[MTI_NAME_MAXLEN];
520 msp = req_capsule_client_get(&req->rq_pill, &RMF_MGS_SEND_PARAM);
523 /* Construct lustre_cfg structure to pass to function mgs_setparam */
524 lustre_cfg_bufs_reset(&bufs, NULL);
525 lustre_cfg_bufs_set_string(&bufs, 1, msp->mgs_param);
526 lcfg = lustre_cfg_new(LCFG_PARAM, &bufs);
527 rc = mgs_setparam(obd, lcfg, fsname);
529 CERROR("Error %d in setting the parameter %s for fs %s\n",
530 rc, msp->mgs_param, fsname);
534 /* request for update */
535 mgs_revoke_lock(obd, fsname, &lockh);
537 lustre_cfg_free(lcfg);
539 rc = req_capsule_server_pack(&req->rq_pill);
541 rep_msp = req_capsule_server_get(&req->rq_pill, &RMF_MGS_SEND_PARAM);
548 * similar as in ost_connect_check_sptlrpc()
550 static int mgs_connect_check_sptlrpc(struct ptlrpc_request *req)
552 struct obd_export *exp = req->rq_export;
553 struct obd_device *obd = exp->exp_obd;
555 struct sptlrpc_flavor flvr;
558 if (exp->exp_flvr.sf_rpc == SPTLRPC_FLVR_INVALID) {
559 rc = mgs_find_or_make_fsdb(obd, MGSSELF_NAME, &fsdb);
563 down(&fsdb->fsdb_sem);
564 if (sptlrpc_rule_set_choose(&fsdb->fsdb_srpc_gen,
565 LUSTRE_SP_MGC, LUSTRE_SP_MGS,
568 /* by defualt allow any flavors */
569 flvr.sf_rpc = SPTLRPC_FLVR_ANY;
573 spin_lock(&exp->exp_lock);
575 exp->exp_sp_peer = req->rq_sp_from;
576 exp->exp_flvr = flvr;
578 if (exp->exp_flvr.sf_rpc != SPTLRPC_FLVR_ANY &&
579 exp->exp_flvr.sf_rpc != req->rq_flvr.sf_rpc) {
580 CERROR("invalid rpc flavor %x, expect %x, from %s\n",
581 req->rq_flvr.sf_rpc, exp->exp_flvr.sf_rpc,
582 libcfs_nid2str(req->rq_peer.nid));
586 spin_unlock(&exp->exp_lock);
588 if (exp->exp_sp_peer != req->rq_sp_from) {
589 CERROR("RPC source %s doesn't match %s\n",
590 sptlrpc_part2name(req->rq_sp_from),
591 sptlrpc_part2name(exp->exp_sp_peer));
594 rc = sptlrpc_target_export_check(exp, req);
601 /* Called whenever a target cleans up. */
602 /* XXX - Currently unused */
603 static int mgs_handle_target_del(struct ptlrpc_request *req)
606 mgs_counter_incr(req->rq_export, LPROC_MGS_TARGET_DEL);
610 /* XXX - Currently unused */
611 static int mgs_handle_exception(struct ptlrpc_request *req)
614 mgs_counter_incr(req->rq_export, LPROC_MGS_EXCEPTION);
618 /* TODO: handle requests in a similar way as MDT: see mdt_handle_common() */
619 int mgs_handle(struct ptlrpc_request *req)
621 int fail = OBD_FAIL_MGS_ALL_REPLY_NET;
625 req_capsule_init(&req->rq_pill, req, RCL_SERVER);
626 OBD_FAIL_TIMEOUT_MS(OBD_FAIL_MGS_PAUSE_REQ, obd_fail_val);
627 if (OBD_FAIL_CHECK(OBD_FAIL_MGS_ALL_REQUEST_NET))
630 LASSERT(current->journal_info == NULL);
631 opc = lustre_msg_get_opc(req->rq_reqmsg);
633 if (opc == SEC_CTX_INIT ||
634 opc == SEC_CTX_INIT_CONT ||
638 if (opc != MGS_CONNECT) {
639 if (req->rq_export == NULL) {
640 CERROR("lustre_mgs: operation %d on unconnected MGS\n",
642 req->rq_status = -ENOTCONN;
643 GOTO(out, rc = -ENOTCONN);
649 DEBUG_REQ(D_MGS, req, "connect");
650 /* MGS and MDS have same request format for connect */
651 req_capsule_set(&req->rq_pill, &RQF_MDS_CONNECT);
652 rc = target_handle_connect(req);
654 rc = mgs_connect_check_sptlrpc(req);
656 if (!rc && (lustre_msg_get_conn_cnt(req->rq_reqmsg) > 1))
657 /* Make clients trying to reconnect after a MGS restart
658 happy; also requires obd_replayable */
659 lustre_msg_add_op_flags(req->rq_repmsg,
660 MSG_CONNECT_RECONNECT);
663 DEBUG_REQ(D_MGS, req, "disconnect");
664 /* MGS and MDS have same request format for disconnect */
665 req_capsule_set(&req->rq_pill, &RQF_MDS_DISCONNECT);
666 rc = target_handle_disconnect(req);
667 req->rq_status = rc; /* superfluous? */
670 DEBUG_REQ(D_MGS, req, "exception");
671 rc = mgs_handle_exception(req);
674 DEBUG_REQ(D_MGS, req, "target add");
675 req_capsule_set(&req->rq_pill, &RQF_MGS_TARGET_REG);
676 rc = mgs_handle_target_reg(req);
679 DEBUG_REQ(D_MGS, req, "target del");
680 rc = mgs_handle_target_del(req);
683 DEBUG_REQ(D_MGS, req, "set_info");
684 req_capsule_set(&req->rq_pill, &RQF_MGS_SET_INFO);
685 rc = mgs_set_info_rpc(req);
689 DEBUG_REQ(D_MGS, req, "enqueue");
690 req_capsule_set(&req->rq_pill, &RQF_LDLM_ENQUEUE);
691 rc = ldlm_handle_enqueue(req, ldlm_server_completion_ast,
692 ldlm_server_blocking_ast, NULL);
694 case LDLM_BL_CALLBACK:
695 case LDLM_CP_CALLBACK:
696 DEBUG_REQ(D_MGS, req, "callback");
697 CERROR("callbacks should not happen on MGS\n");
702 DEBUG_REQ(D_INFO, req, "ping");
703 req_capsule_set(&req->rq_pill, &RQF_OBD_PING);
704 rc = target_handle_ping(req);
707 DEBUG_REQ(D_MGS, req, "log cancel");
708 rc = -ENOTSUPP; /* la la la */
711 case LLOG_ORIGIN_HANDLE_CREATE:
712 DEBUG_REQ(D_MGS, req, "llog_init");
713 req_capsule_set(&req->rq_pill, &RQF_LLOG_ORIGIN_HANDLE_CREATE);
714 rc = llog_origin_handle_create(req);
716 case LLOG_ORIGIN_HANDLE_NEXT_BLOCK:
717 DEBUG_REQ(D_MGS, req, "llog next block");
718 req_capsule_set(&req->rq_pill,
719 &RQF_LLOG_ORIGIN_HANDLE_NEXT_BLOCK);
720 rc = llog_origin_handle_next_block(req);
722 case LLOG_ORIGIN_HANDLE_READ_HEADER:
723 DEBUG_REQ(D_MGS, req, "llog read header");
724 req_capsule_set(&req->rq_pill,
725 &RQF_LLOG_ORIGIN_HANDLE_READ_HEADER);
726 rc = llog_origin_handle_read_header(req);
728 case LLOG_ORIGIN_HANDLE_CLOSE:
729 DEBUG_REQ(D_MGS, req, "llog close");
730 rc = llog_origin_handle_close(req);
733 DEBUG_REQ(D_MGS, req, "llog catinfo");
734 req_capsule_set(&req->rq_pill, &RQF_LLOG_CATINFO);
735 rc = llog_catinfo(req);
738 req->rq_status = -ENOTSUPP;
739 rc = ptlrpc_error(req);
743 LASSERT(current->journal_info == NULL);
746 CERROR("MGS handle cmd=%d rc=%d\n", opc, rc);
749 target_send_reply(req, rc, fail);
753 static inline int mgs_init_export(struct obd_export *exp)
755 spin_lock(&exp->exp_lock);
756 exp->exp_connecting = 1;
757 spin_unlock(&exp->exp_lock);
759 return ldlm_init_export(exp);
762 static inline int mgs_destroy_export(struct obd_export *exp)
766 target_destroy_export(exp);
767 mgs_client_free(exp);
768 ldlm_destroy_export(exp);
773 static int mgs_extract_fs_pool(char * arg, char *fsname, char *poolname)
778 for (ptr = arg; (*ptr != '\0') && (*ptr != '.'); ptr++ ) {
786 strcpy(poolname, ptr);
791 static int mgs_iocontrol_pool(struct obd_device *obd,
792 struct obd_ioctl_data *data)
795 struct lustre_handle lockh;
796 struct lustre_cfg *lcfg = NULL;
797 struct llog_rec_hdr rec;
799 char *poolname = NULL;
802 OBD_ALLOC(fsname, MTI_NAME_MAXLEN);
806 OBD_ALLOC(poolname, LOV_MAXPOOLNAME + 1);
807 if (poolname == NULL) {
811 rec.lrh_len = llog_data_len(data->ioc_plen1);
813 if (data->ioc_type == LUSTRE_CFG_TYPE) {
814 rec.lrh_type = OBD_CFG_REC;
816 CERROR("unknown cfg record type:%d \n", data->ioc_type);
821 if (data->ioc_plen1 > CFS_PAGE_SIZE) {
826 OBD_ALLOC(lcfg, data->ioc_plen1);
828 GOTO(out_pool, rc = -ENOMEM);
830 if (copy_from_user(lcfg, data->ioc_pbuf1, data->ioc_plen1))
831 GOTO(out_pool, rc = -EFAULT);
833 if (lcfg->lcfg_bufcount < 2) {
834 GOTO(out_pool, rc = -EFAULT);
837 /* first arg is always <fsname>.<poolname> */
838 mgs_extract_fs_pool(lustre_cfg_string(lcfg, 1), fsname,
841 switch (lcfg->lcfg_command) {
842 case LCFG_POOL_NEW: {
843 if (lcfg->lcfg_bufcount != 2)
845 rc = mgs_pool_cmd(obd, LCFG_POOL_NEW, fsname,
849 case LCFG_POOL_ADD: {
850 if (lcfg->lcfg_bufcount != 3)
852 rc = mgs_pool_cmd(obd, LCFG_POOL_ADD, fsname, poolname,
853 lustre_cfg_string(lcfg, 2));
856 case LCFG_POOL_REM: {
857 if (lcfg->lcfg_bufcount != 3)
859 rc = mgs_pool_cmd(obd, LCFG_POOL_REM, fsname, poolname,
860 lustre_cfg_string(lcfg, 2));
863 case LCFG_POOL_DEL: {
864 if (lcfg->lcfg_bufcount != 2)
866 rc = mgs_pool_cmd(obd, LCFG_POOL_DEL, fsname,
877 CERROR("OBD_IOC_POOL err %d, cmd %X for pool %s.%s\n",
878 rc, lcfg->lcfg_command, fsname, poolname);
882 /* request for update */
883 mgs_revoke_lock(obd, fsname, &lockh);
887 OBD_FREE(lcfg, data->ioc_plen1);
890 OBD_FREE(fsname, MTI_NAME_MAXLEN);
892 if (poolname != NULL)
893 OBD_FREE(poolname, LOV_MAXPOOLNAME + 1);
898 /* from mdt_iocontrol */
899 int mgs_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
900 void *karg, void *uarg)
902 struct obd_device *obd = exp->exp_obd;
903 struct obd_ioctl_data *data = karg;
904 struct lvfs_run_ctxt saved;
908 CDEBUG(D_IOCTL, "handling ioctl cmd %#x\n", cmd);
912 case OBD_IOC_PARAM: {
913 struct lustre_handle lockh;
914 struct lustre_cfg *lcfg;
915 struct llog_rec_hdr rec;
916 char fsname[MTI_NAME_MAXLEN];
918 rec.lrh_len = llog_data_len(data->ioc_plen1);
920 if (data->ioc_type == LUSTRE_CFG_TYPE) {
921 rec.lrh_type = OBD_CFG_REC;
923 CERROR("unknown cfg record type:%d \n", data->ioc_type);
927 OBD_ALLOC(lcfg, data->ioc_plen1);
930 if (copy_from_user(lcfg, data->ioc_pbuf1, data->ioc_plen1))
931 GOTO(out_free, rc = -EFAULT);
933 if (lcfg->lcfg_bufcount < 1)
934 GOTO(out_free, rc = -EINVAL);
936 rc = mgs_setparam(obd, lcfg, fsname);
938 CERROR("setparam err %d\n", rc);
942 /* Revoke lock so everyone updates. Should be alright if
943 someone was already reading while we were updating the logs,
944 so we don't really need to hold the lock while we're
946 mgs_revoke_lock(obd, fsname, &lockh);
949 OBD_FREE(lcfg, data->ioc_plen1);
954 RETURN(mgs_iocontrol_pool(obd, data));
957 case OBD_IOC_DUMP_LOG: {
958 struct llog_ctxt *ctxt;
959 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
960 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
961 rc = class_config_dump_llog(ctxt, data->ioc_inlbuf1, NULL);
962 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
968 case OBD_IOC_LLOG_CHECK:
969 case OBD_IOC_LLOG_INFO:
970 case OBD_IOC_LLOG_PRINT: {
971 struct llog_ctxt *ctxt;
972 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
974 push_ctxt(&saved, &ctxt->loc_exp->exp_obd->obd_lvfs_ctxt, NULL);
975 rc = llog_ioctl(ctxt, cmd, data);
976 pop_ctxt(&saved, &ctxt->loc_exp->exp_obd->obd_lvfs_ctxt, NULL);
983 CDEBUG(D_INFO, "unknown command %x\n", cmd);
989 /* use obd ops to offer management infrastructure */
990 static struct obd_ops mgs_obd_ops = {
991 .o_owner = THIS_MODULE,
992 .o_connect = mgs_connect,
993 .o_reconnect = mgs_reconnect,
994 .o_disconnect = mgs_disconnect,
995 .o_setup = mgs_setup,
996 .o_precleanup = mgs_precleanup,
997 .o_cleanup = mgs_cleanup,
998 .o_init_export = mgs_init_export,
999 .o_destroy_export = mgs_destroy_export,
1000 .o_iocontrol = mgs_iocontrol,
1001 .o_llog_init = mgs_llog_init,
1002 .o_llog_finish = mgs_llog_finish
1005 static int __init mgs_init(void)
1007 struct lprocfs_static_vars lvars;
1009 lprocfs_mgs_init_vars(&lvars);
1010 class_register_type(&mgs_obd_ops, NULL,
1011 lvars.module_vars, LUSTRE_MGS_NAME, NULL);
1016 static void /*__exit*/ mgs_exit(void)
1018 class_unregister_type(LUSTRE_MGS_NAME);
1021 MODULE_AUTHOR("Sun Microsystems, Inc. <http://www.lustre.org/>");
1022 MODULE_DESCRIPTION("Lustre Management Server (MGS)");
1023 MODULE_LICENSE("GPL");
1025 module_init(mgs_init);
1026 module_exit(mgs_exit);