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 /* 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 spin_lock(&rs->rs_lock);
152 ptlrpc_schedule_difficult_reply(rs);
153 spin_unlock(&rs->rs_lock);
154 spin_unlock(&svc->srv_lock);
156 spin_unlock(&exp->exp_lock);
158 class_export_put(exp);
162 static int mgs_cleanup(struct obd_device *obd);
163 static int mgs_handle(struct ptlrpc_request *req);
165 static int mgs_llog_init(struct obd_device *obd, struct obd_llog_group *olg,
166 struct obd_device *tgt, int count,
167 struct llog_catid *logid, struct obd_uuid *uuid)
172 LASSERT(olg == &obd->obd_olg);
173 rc = llog_setup(obd, olg, LLOG_CONFIG_ORIG_CTXT, obd, 0, NULL,
178 static int mgs_llog_finish(struct obd_device *obd, int count)
180 struct llog_ctxt *ctxt;
184 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
186 rc = llog_cleanup(ctxt);
191 /* Start the MGS obd */
192 static int mgs_setup(struct obd_device *obd, struct lustre_cfg *lcfg)
194 struct lprocfs_static_vars lvars;
195 struct mgs_obd *mgs = &obd->u.mgs;
196 struct lustre_mount_info *lmi;
197 struct lustre_sb_info *lsi;
198 struct vfsmount *mnt;
202 CDEBUG(D_CONFIG, "Starting MGS\n");
205 lmi = server_get_mount(obd->obd_name);
207 RETURN(rc = -EINVAL);
210 lsi = s2lsi(lmi->lmi_sb);
211 obd->obd_fsops = fsfilt_get_ops(MT_STR(lsi->lsi_ldd));
212 if (IS_ERR(obd->obd_fsops))
213 GOTO(err_put, rc = PTR_ERR(obd->obd_fsops));
215 if (lvfs_check_rdonly(lvfs_sbdev(mnt->mnt_sb))) {
216 CERROR("%s: Underlying device is marked as read-only. "
217 "Setup failed\n", obd->obd_name);
218 GOTO(err_ops, rc = -EROFS);
221 /* namespace for mgs llog */
222 obd->obd_namespace = ldlm_namespace_new(obd ,"MGS", LDLM_NAMESPACE_SERVER,
223 LDLM_NAMESPACE_MODEST);
224 if (obd->obd_namespace == NULL)
225 GOTO(err_ops, rc = -ENOMEM);
228 ptlrpc_init_client(LDLM_CB_REQUEST_PORTAL, LDLM_CB_REPLY_PORTAL,
229 "mgs_ldlm_client", &obd->obd_ldlm_client);
231 rc = mgs_fs_setup(obd, mnt);
233 CERROR("%s: MGS filesystem method init failed: rc = %d\n",
238 rc = obd_llog_init(obd, &obd->obd_olg, obd, 0, NULL, NULL);
242 /* No recovery for MGC's */
243 obd->obd_replayable = 0;
245 /* Internal mgs setup */
246 mgs_init_fsdb_list(obd);
247 sema_init(&mgs->mgs_sem, 1);
249 /* Start the service threads */
251 ptlrpc_init_svc(MGS_NBUFS, MGS_BUFSIZE, MGS_MAXREQSIZE,
252 MGS_MAXREPSIZE, MGS_REQUEST_PORTAL,
254 mgs_handle, LUSTRE_MGS_NAME,
255 obd->obd_proc_entry, target_print_req,
256 MGS_THREADS_AUTO_MIN, MGS_THREADS_AUTO_MAX,
257 "ll_mgs", LCT_MD_THREAD, NULL);
259 if (!mgs->mgs_service) {
260 CERROR("failed to start service\n");
261 GOTO(err_llog, rc = -ENOMEM);
264 rc = ptlrpc_start_threads(obd, mgs->mgs_service);
266 GOTO(err_thread, rc);
269 lprocfs_mgs_init_vars(&lvars);
270 if (lprocfs_obd_setup(obd, lvars.obd_vars) == 0) {
271 lproc_mgs_setup(obd);
274 ping_evictor_start();
276 LCONSOLE_INFO("MGS %s started\n", obd->obd_name);
281 ptlrpc_unregister_service(mgs->mgs_service);
283 obd_llog_finish(obd, 0);
285 /* No extra cleanup needed for llog_init_commit_thread() */
288 ldlm_namespace_free(obd->obd_namespace, NULL, 0);
289 obd->obd_namespace = NULL;
291 fsfilt_put_ops(obd->obd_fsops);
293 server_put_mount(obd->obd_name, mnt);
298 static int mgs_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage)
304 case OBD_CLEANUP_EARLY:
305 case OBD_CLEANUP_EXPORTS:
306 rc = obd_llog_finish(obd, 0);
313 * Performs cleanup procedures for passed \a obd given it is mgs obd.
315 static int mgs_cleanup(struct obd_device *obd)
317 struct mgs_obd *mgs = &obd->u.mgs;
320 if (mgs->mgs_sb == NULL)
325 ptlrpc_unregister_service(mgs->mgs_service);
327 mgs_cleanup_fsdb_list(obd);
328 lproc_mgs_cleanup(obd);
331 server_put_mount(obd->obd_name, mgs->mgs_vfsmnt);
334 ldlm_namespace_free(obd->obd_namespace, NULL, 1);
335 obd->obd_namespace = NULL;
337 fsfilt_put_ops(obd->obd_fsops);
339 LCONSOLE_INFO("%s has stopped.\n", obd->obd_name);
343 /* similar to filter_prepare_destroy */
344 static int mgs_get_cfg_lock(struct obd_device *obd, char *fsname,
345 struct lustre_handle *lockh)
347 struct ldlm_res_id res_id;
351 rc = mgc_fsname2resid(fsname, &res_id);
353 rc = ldlm_cli_enqueue_local(obd->obd_namespace, &res_id,
354 LDLM_PLAIN, NULL, LCK_EX,
355 &flags, ldlm_blocking_ast,
356 ldlm_completion_ast, NULL,
357 fsname, 0, NULL, NULL, lockh);
359 CERROR("can't take cfg lock for %s (%d)\n", fsname, rc);
364 static int mgs_put_cfg_lock(struct lustre_handle *lockh)
367 ldlm_lock_decref(lockh, LCK_EX);
371 static void mgs_revoke_lock(struct obd_device *obd, char *fsname,
372 struct lustre_handle *lockh)
377 lockrc = mgs_get_cfg_lock(obd, fsname, lockh);
378 if (lockrc != ELDLM_OK)
379 CERROR("lock error %d for fs %s\n", lockrc,
382 mgs_put_cfg_lock(lockh);
389 static int mgs_check_target(struct obd_device *obd, struct mgs_target_info *mti)
394 rc = mgs_check_index(obd, mti);
396 LCONSOLE_ERROR_MSG(0x13b, "%s claims to have registered, but "
397 "this MGS does not know about it, preventing "
398 "registration.\n", mti->mti_svname);
400 } else if (rc == -1) {
401 LCONSOLE_ERROR_MSG(0x13c, "Client log %s-client has "
402 "disappeared! Regenerating all logs.\n",
404 mti->mti_flags |= LDD_F_WRITECONF;
407 /* Index is correctly marked as used */
409 /* If the logs don't contain the mti_nids then add
410 them as failover nids */
411 rc = mgs_check_failnid(obd, mti);
417 /* Called whenever a target starts up. Flags indicate first connect, etc. */
418 static int mgs_handle_target_reg(struct ptlrpc_request *req)
420 struct obd_device *obd = req->rq_export->exp_obd;
421 struct lustre_handle lockh;
422 struct mgs_target_info *mti, *rep_mti;
426 mgs_counter_incr(req->rq_export, LPROC_MGS_TARGET_REG);
428 mti = req_capsule_client_get(&req->rq_pill, &RMF_MGS_TARGET_INFO);
429 if (!(mti->mti_flags & (LDD_F_WRITECONF | LDD_F_UPGRADE14 |
431 /* We're just here as a startup ping. */
432 CDEBUG(D_MGS, "Server %s is running on %s\n",
433 mti->mti_svname, obd_export_nid2str(req->rq_export));
434 rc = mgs_check_target(obd, mti);
435 /* above will set appropriate mti flags */
437 /* Nothing wrong, or fatal error */
438 GOTO(out_nolock, rc);
441 /* Revoke the config lock to make sure nobody is reading. */
442 /* Although actually I think it should be alright if
443 someone was reading while we were updating the logs - if we
444 revoke at the end they will just update from where they left off. */
445 lockrc = mgs_get_cfg_lock(obd, mti->mti_fsname, &lockh);
446 if (lockrc != ELDLM_OK) {
447 LCONSOLE_ERROR_MSG(0x13d, "%s: Can't signal other nodes to "
448 "update their configuration (%d). Updating "
449 "local logs anyhow; you might have to "
450 "manually restart other nodes to get the "
451 "latest configuration.\n",
452 obd->obd_name, lockrc);
455 OBD_FAIL_TIMEOUT(OBD_FAIL_MGS_PAUSE_TARGET_REG, 10);
457 /* Log writing contention is handled by the fsdb_sem */
459 if (mti->mti_flags & LDD_F_WRITECONF) {
460 if (mti->mti_flags & LDD_F_SV_TYPE_MDT &&
461 mti->mti_stripe_index == 0) {
462 rc = mgs_erase_logs(obd, mti->mti_fsname);
463 LCONSOLE_WARN("%s: Logs for fs %s were removed by user "
464 "request. All servers must be restarted "
465 "in order to regenerate the logs."
466 "\n", obd->obd_name, mti->mti_fsname);
467 } else if (mti->mti_flags &
468 (LDD_F_SV_TYPE_OST | LDD_F_SV_TYPE_MDT)) {
469 rc = mgs_erase_log(obd, mti->mti_svname);
470 LCONSOLE_WARN("%s: Regenerating %s log by user "
472 obd->obd_name, mti->mti_svname);
474 mti->mti_flags |= LDD_F_UPDATE;
475 /* Erased logs means start from scratch. */
476 mti->mti_flags &= ~LDD_F_UPGRADE14;
480 if (mti->mti_flags & LDD_F_UPGRADE14) {
481 rc = mgs_upgrade_sv_14(obd, mti);
483 CERROR("Can't upgrade from 1.4 (%d)\n", rc);
487 /* We're good to go */
488 mti->mti_flags |= LDD_F_UPDATE;
492 if (mti->mti_flags & LDD_F_UPDATE) {
493 CDEBUG(D_MGS, "updating %s, index=%d\n", mti->mti_svname,
494 mti->mti_stripe_index);
496 /* create or update the target log
497 and update the client/mdt logs */
498 rc = mgs_write_log_target(obd, mti);
500 CERROR("Failed to write %s log (%d)\n",
501 mti->mti_svname, rc);
505 mti->mti_flags &= ~(LDD_F_VIRGIN | LDD_F_UPDATE |
506 LDD_F_NEED_INDEX | LDD_F_WRITECONF |
508 mti->mti_flags |= LDD_F_REWRITE_LDD;
512 /* done with log update */
513 if (lockrc == ELDLM_OK)
514 mgs_put_cfg_lock(&lockh);
516 CDEBUG(D_MGS, "replying with %s, index=%d, rc=%d\n", mti->mti_svname,
517 mti->mti_stripe_index, rc);
518 rc = req_capsule_server_pack(&req->rq_pill);
522 /* send back the whole mti in the reply */
523 rep_mti = req_capsule_server_get(&req->rq_pill, &RMF_MGS_TARGET_INFO);
526 /* Flush logs to disk */
527 fsfilt_sync(obd, obd->u.mgs.mgs_sb);
531 static int mgs_set_info_rpc(struct ptlrpc_request *req)
533 struct obd_device *obd = req->rq_export->exp_obd;
534 struct mgs_send_param *msp, *rep_msp;
535 struct lustre_handle lockh;
537 struct lustre_cfg_bufs bufs;
538 struct lustre_cfg *lcfg;
539 char fsname[MTI_NAME_MAXLEN];
542 msp = req_capsule_client_get(&req->rq_pill, &RMF_MGS_SEND_PARAM);
545 /* Construct lustre_cfg structure to pass to function mgs_setparam */
546 lustre_cfg_bufs_reset(&bufs, NULL);
547 lustre_cfg_bufs_set_string(&bufs, 1, msp->mgs_param);
548 lcfg = lustre_cfg_new(LCFG_PARAM, &bufs);
549 rc = mgs_setparam(obd, lcfg, fsname);
551 CERROR("Error %d in setting the parameter %s for fs %s\n",
552 rc, msp->mgs_param, fsname);
556 /* request for update */
557 mgs_revoke_lock(obd, fsname, &lockh);
559 lustre_cfg_free(lcfg);
561 rc = req_capsule_server_pack(&req->rq_pill);
563 rep_msp = req_capsule_server_get(&req->rq_pill, &RMF_MGS_SEND_PARAM);
570 * similar as in ost_connect_check_sptlrpc()
572 static int mgs_connect_check_sptlrpc(struct ptlrpc_request *req)
574 struct obd_export *exp = req->rq_export;
575 struct obd_device *obd = exp->exp_obd;
577 struct sptlrpc_flavor flvr;
580 if (exp->exp_flvr.sf_rpc == SPTLRPC_FLVR_INVALID) {
581 rc = mgs_find_or_make_fsdb(obd, MGSSELF_NAME, &fsdb);
585 down(&fsdb->fsdb_sem);
586 if (sptlrpc_rule_set_choose(&fsdb->fsdb_srpc_gen,
587 LUSTRE_SP_MGC, LUSTRE_SP_MGS,
590 /* by defualt allow any flavors */
591 flvr.sf_rpc = SPTLRPC_FLVR_ANY;
595 spin_lock(&exp->exp_lock);
597 exp->exp_sp_peer = req->rq_sp_from;
598 exp->exp_flvr = flvr;
600 if (exp->exp_flvr.sf_rpc != SPTLRPC_FLVR_ANY &&
601 exp->exp_flvr.sf_rpc != req->rq_flvr.sf_rpc) {
602 CERROR("invalid rpc flavor %x, expect %x, from %s\n",
603 req->rq_flvr.sf_rpc, exp->exp_flvr.sf_rpc,
604 libcfs_nid2str(req->rq_peer.nid));
608 spin_unlock(&exp->exp_lock);
610 if (exp->exp_sp_peer != req->rq_sp_from) {
611 CERROR("RPC source %s doesn't match %s\n",
612 sptlrpc_part2name(req->rq_sp_from),
613 sptlrpc_part2name(exp->exp_sp_peer));
616 rc = sptlrpc_target_export_check(exp, req);
623 /* Called whenever a target cleans up. */
624 /* XXX - Currently unused */
625 static int mgs_handle_target_del(struct ptlrpc_request *req)
628 mgs_counter_incr(req->rq_export, LPROC_MGS_TARGET_DEL);
632 /* XXX - Currently unused */
633 static int mgs_handle_exception(struct ptlrpc_request *req)
636 mgs_counter_incr(req->rq_export, LPROC_MGS_EXCEPTION);
640 /* TODO: handle requests in a similar way as MDT: see mdt_handle_common() */
641 int mgs_handle(struct ptlrpc_request *req)
643 int fail = OBD_FAIL_MGS_ALL_REPLY_NET;
647 req_capsule_init(&req->rq_pill, req, RCL_SERVER);
648 OBD_FAIL_TIMEOUT_MS(OBD_FAIL_MGS_PAUSE_REQ, obd_fail_val);
649 if (OBD_FAIL_CHECK(OBD_FAIL_MGS_ALL_REQUEST_NET))
652 LASSERT(current->journal_info == NULL);
653 opc = lustre_msg_get_opc(req->rq_reqmsg);
655 if (opc == SEC_CTX_INIT ||
656 opc == SEC_CTX_INIT_CONT ||
660 if (opc != MGS_CONNECT) {
661 if (req->rq_export == NULL) {
662 CERROR("lustre_mgs: operation %d on unconnected MGS\n",
664 req->rq_status = -ENOTCONN;
665 GOTO(out, rc = -ENOTCONN);
671 DEBUG_REQ(D_MGS, req, "connect");
672 /* MGS and MDS have same request format for connect */
673 req_capsule_set(&req->rq_pill, &RQF_MDS_CONNECT);
674 rc = target_handle_connect(req);
676 rc = mgs_connect_check_sptlrpc(req);
678 if (!rc && (lustre_msg_get_conn_cnt(req->rq_reqmsg) > 1))
679 /* Make clients trying to reconnect after a MGS restart
680 happy; also requires obd_replayable */
681 lustre_msg_add_op_flags(req->rq_repmsg,
682 MSG_CONNECT_RECONNECT);
685 DEBUG_REQ(D_MGS, req, "disconnect");
686 /* MGS and MDS have same request format for disconnect */
687 req_capsule_set(&req->rq_pill, &RQF_MDS_DISCONNECT);
688 rc = target_handle_disconnect(req);
689 req->rq_status = rc; /* superfluous? */
692 DEBUG_REQ(D_MGS, req, "exception");
693 rc = mgs_handle_exception(req);
696 DEBUG_REQ(D_MGS, req, "target add");
697 req_capsule_set(&req->rq_pill, &RQF_MGS_TARGET_REG);
698 rc = mgs_handle_target_reg(req);
701 DEBUG_REQ(D_MGS, req, "target del");
702 rc = mgs_handle_target_del(req);
705 DEBUG_REQ(D_MGS, req, "set_info");
706 req_capsule_set(&req->rq_pill, &RQF_MGS_SET_INFO);
707 rc = mgs_set_info_rpc(req);
711 DEBUG_REQ(D_MGS, req, "enqueue");
712 req_capsule_set(&req->rq_pill, &RQF_LDLM_ENQUEUE);
713 rc = ldlm_handle_enqueue(req, ldlm_server_completion_ast,
714 ldlm_server_blocking_ast, NULL);
716 case LDLM_BL_CALLBACK:
717 case LDLM_CP_CALLBACK:
718 DEBUG_REQ(D_MGS, req, "callback");
719 CERROR("callbacks should not happen on MGS\n");
724 DEBUG_REQ(D_INFO, req, "ping");
725 req_capsule_set(&req->rq_pill, &RQF_OBD_PING);
726 rc = target_handle_ping(req);
729 DEBUG_REQ(D_MGS, req, "log cancel");
730 rc = -ENOTSUPP; /* la la la */
733 case LLOG_ORIGIN_HANDLE_CREATE:
734 DEBUG_REQ(D_MGS, req, "llog_init");
735 req_capsule_set(&req->rq_pill, &RQF_LLOG_ORIGIN_HANDLE_CREATE);
736 rc = llog_origin_handle_create(req);
738 case LLOG_ORIGIN_HANDLE_NEXT_BLOCK:
739 DEBUG_REQ(D_MGS, req, "llog next block");
740 req_capsule_set(&req->rq_pill,
741 &RQF_LLOG_ORIGIN_HANDLE_NEXT_BLOCK);
742 rc = llog_origin_handle_next_block(req);
744 case LLOG_ORIGIN_HANDLE_READ_HEADER:
745 DEBUG_REQ(D_MGS, req, "llog read header");
746 req_capsule_set(&req->rq_pill,
747 &RQF_LLOG_ORIGIN_HANDLE_READ_HEADER);
748 rc = llog_origin_handle_read_header(req);
750 case LLOG_ORIGIN_HANDLE_CLOSE:
751 DEBUG_REQ(D_MGS, req, "llog close");
752 rc = llog_origin_handle_close(req);
755 DEBUG_REQ(D_MGS, req, "llog catinfo");
756 req_capsule_set(&req->rq_pill, &RQF_LLOG_CATINFO);
757 rc = llog_catinfo(req);
760 req->rq_status = -ENOTSUPP;
761 rc = ptlrpc_error(req);
765 LASSERT(current->journal_info == NULL);
768 CERROR("MGS handle cmd=%d rc=%d\n", opc, rc);
771 target_send_reply(req, rc, fail);
775 static inline int mgs_init_export(struct obd_export *exp)
777 spin_lock(&exp->exp_lock);
778 exp->exp_connecting = 1;
779 spin_unlock(&exp->exp_lock);
781 return ldlm_init_export(exp);
784 static inline int mgs_destroy_export(struct obd_export *exp)
788 target_destroy_export(exp);
789 mgs_client_free(exp);
790 ldlm_destroy_export(exp);
795 static int mgs_extract_fs_pool(char * arg, char *fsname, char *poolname)
800 for (ptr = arg; (*ptr != '\0') && (*ptr != '.'); ptr++ ) {
808 strcpy(poolname, ptr);
813 static int mgs_iocontrol_pool(struct obd_device *obd,
814 struct obd_ioctl_data *data)
817 struct lustre_handle lockh;
818 struct lustre_cfg *lcfg = NULL;
819 struct llog_rec_hdr rec;
821 char *poolname = NULL;
824 OBD_ALLOC(fsname, MTI_NAME_MAXLEN);
828 OBD_ALLOC(poolname, LOV_MAXPOOLNAME + 1);
829 if (poolname == NULL) {
833 rec.lrh_len = llog_data_len(data->ioc_plen1);
835 if (data->ioc_type == LUSTRE_CFG_TYPE) {
836 rec.lrh_type = OBD_CFG_REC;
838 CERROR("unknown cfg record type:%d \n", data->ioc_type);
843 if (data->ioc_plen1 > CFS_PAGE_SIZE) {
848 OBD_ALLOC(lcfg, data->ioc_plen1);
850 GOTO(out_pool, rc = -ENOMEM);
852 if (copy_from_user(lcfg, data->ioc_pbuf1, data->ioc_plen1))
853 GOTO(out_pool, rc = -EFAULT);
855 if (lcfg->lcfg_bufcount < 2) {
856 GOTO(out_pool, rc = -EFAULT);
859 /* first arg is always <fsname>.<poolname> */
860 mgs_extract_fs_pool(lustre_cfg_string(lcfg, 1), fsname,
863 switch (lcfg->lcfg_command) {
864 case LCFG_POOL_NEW: {
865 if (lcfg->lcfg_bufcount != 2)
867 rc = mgs_pool_cmd(obd, LCFG_POOL_NEW, fsname,
871 case LCFG_POOL_ADD: {
872 if (lcfg->lcfg_bufcount != 3)
874 rc = mgs_pool_cmd(obd, LCFG_POOL_ADD, fsname, poolname,
875 lustre_cfg_string(lcfg, 2));
878 case LCFG_POOL_REM: {
879 if (lcfg->lcfg_bufcount != 3)
881 rc = mgs_pool_cmd(obd, LCFG_POOL_REM, fsname, poolname,
882 lustre_cfg_string(lcfg, 2));
885 case LCFG_POOL_DEL: {
886 if (lcfg->lcfg_bufcount != 2)
888 rc = mgs_pool_cmd(obd, LCFG_POOL_DEL, fsname,
899 CERROR("OBD_IOC_POOL err %d, cmd %X for pool %s.%s\n",
900 rc, lcfg->lcfg_command, fsname, poolname);
904 /* request for update */
905 mgs_revoke_lock(obd, fsname, &lockh);
909 OBD_FREE(lcfg, data->ioc_plen1);
912 OBD_FREE(fsname, MTI_NAME_MAXLEN);
914 if (poolname != NULL)
915 OBD_FREE(poolname, LOV_MAXPOOLNAME + 1);
920 /* from mdt_iocontrol */
921 int mgs_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
922 void *karg, void *uarg)
924 struct obd_device *obd = exp->exp_obd;
925 struct obd_ioctl_data *data = karg;
926 struct lvfs_run_ctxt saved;
930 CDEBUG(D_IOCTL, "handling ioctl cmd %#x\n", cmd);
934 case OBD_IOC_PARAM: {
935 struct lustre_handle lockh;
936 struct lustre_cfg *lcfg;
937 struct llog_rec_hdr rec;
938 char fsname[MTI_NAME_MAXLEN];
940 rec.lrh_len = llog_data_len(data->ioc_plen1);
942 if (data->ioc_type == LUSTRE_CFG_TYPE) {
943 rec.lrh_type = OBD_CFG_REC;
945 CERROR("unknown cfg record type:%d \n", data->ioc_type);
949 OBD_ALLOC(lcfg, data->ioc_plen1);
952 if (copy_from_user(lcfg, data->ioc_pbuf1, data->ioc_plen1))
953 GOTO(out_free, rc = -EFAULT);
955 if (lcfg->lcfg_bufcount < 1)
956 GOTO(out_free, rc = -EINVAL);
958 rc = mgs_setparam(obd, lcfg, fsname);
960 CERROR("setparam err %d\n", rc);
964 /* Revoke lock so everyone updates. Should be alright if
965 someone was already reading while we were updating the logs,
966 so we don't really need to hold the lock while we're
968 mgs_revoke_lock(obd, fsname, &lockh);
971 OBD_FREE(lcfg, data->ioc_plen1);
976 RETURN(mgs_iocontrol_pool(obd, data));
979 case OBD_IOC_DUMP_LOG: {
980 struct llog_ctxt *ctxt;
981 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
982 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
983 rc = class_config_dump_llog(ctxt, data->ioc_inlbuf1, NULL);
984 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
990 case OBD_IOC_LLOG_CHECK:
991 case OBD_IOC_LLOG_INFO:
992 case OBD_IOC_LLOG_PRINT: {
993 struct llog_ctxt *ctxt;
994 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
996 push_ctxt(&saved, &ctxt->loc_exp->exp_obd->obd_lvfs_ctxt, NULL);
997 rc = llog_ioctl(ctxt, cmd, data);
998 pop_ctxt(&saved, &ctxt->loc_exp->exp_obd->obd_lvfs_ctxt, NULL);
1005 CDEBUG(D_INFO, "unknown command %x\n", cmd);
1011 /* use obd ops to offer management infrastructure */
1012 static struct obd_ops mgs_obd_ops = {
1013 .o_owner = THIS_MODULE,
1014 .o_connect = mgs_connect,
1015 .o_reconnect = mgs_reconnect,
1016 .o_disconnect = mgs_disconnect,
1017 .o_setup = mgs_setup,
1018 .o_precleanup = mgs_precleanup,
1019 .o_cleanup = mgs_cleanup,
1020 .o_init_export = mgs_init_export,
1021 .o_destroy_export = mgs_destroy_export,
1022 .o_iocontrol = mgs_iocontrol,
1023 .o_llog_init = mgs_llog_init,
1024 .o_llog_finish = mgs_llog_finish
1027 static int __init mgs_init(void)
1029 struct lprocfs_static_vars lvars;
1031 lprocfs_mgs_init_vars(&lvars);
1032 class_register_type(&mgs_obd_ops, NULL,
1033 lvars.module_vars, LUSTRE_MGS_NAME, NULL);
1038 static void /*__exit*/ mgs_exit(void)
1040 class_unregister_type(LUSTRE_MGS_NAME);
1043 MODULE_AUTHOR("Sun Microsystems, Inc. <http://www.lustre.org/>");
1044 MODULE_DESCRIPTION("Lustre Management Server (MGS)");
1045 MODULE_LICENSE("GPL");
1047 module_init(mgs_init);
1048 module_exit(mgs_exit);