mgs_handler.c

来自「lustre 1.6.5 source code」· C语言 代码 · 共 773 行 · 第 1/2 页

C
773
字号
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- * vim:expandtab:shiftwidth=8:tabstop=8: * *  lustre/mgs/mgs_handler.c *  Lustre Management Server (mgs) request handler * *  Copyright (C) 2006 Cluster File Systems, Inc. *   Author: Nathan Rutman <nathan@clusterfs.com> * *   This file is part of Lustre, http://www.lustre.org. * *   Lustre is free software; you can redistribute it and/or *   modify it under the terms of version 2 of the GNU General Public *   License as published by the Free Software Foundation. * *   Lustre is distributed in the hope that it will be useful, *   but WITHOUT ANY WARRANTY; without even the implied warranty of *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *   GNU General Public License for more details. * *   You should have received a copy of the GNU General Public License *   along with Lustre; if not, write to the Free Software *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#ifndef EXPORT_SYMTAB# define EXPORT_SYMTAB#endif#define DEBUG_SUBSYSTEM S_MGS#define D_MGS D_CONFIG/*|D_WARNING*/#ifdef __KERNEL__# include <linux/module.h># include <linux/pagemap.h># include <linux/miscdevice.h># include <linux/init.h>#else# include <liblustre.h>#endif#include <obd_class.h>#include <lustre_dlm.h>#include <lprocfs_status.h>#include <lustre_fsfilt.h>#include <lustre_commit_confd.h>#include <lustre_disk.h>#include "mgs_internal.h"/* Establish a connection to the MGS.*/static int mgs_connect(struct lustre_handle *conn, struct obd_device *obd,                       struct obd_uuid *cluuid, struct obd_connect_data *data,                       void *localdata){        struct obd_export *exp;        int rc;        ENTRY;        if (!conn || !obd || !cluuid)                RETURN(-EINVAL);        rc = class_connect(conn, obd, cluuid);        if (rc)                RETURN(rc);        exp = class_conn2export(conn);        LASSERT(exp);        mgs_counter_incr(exp, LPROC_MGS_CONNECT);        if (data != NULL) {                data->ocd_connect_flags &= MGS_CONNECT_SUPPORTED;                exp->exp_connect_flags = data->ocd_connect_flags;                data->ocd_version = LUSTRE_VERSION_CODE;        }        rc = mgs_client_add(obd, exp);        if (rc) {                class_disconnect(exp);        } else {                class_export_put(exp);        }        RETURN(rc);}static int mgs_disconnect(struct obd_export *exp){        int rc;        ENTRY;        LASSERT(exp);        class_export_get(exp);        mgs_counter_incr(exp, LPROC_MGS_DISCONNECT);        /* Disconnect early so that clients can't keep using export */        rc = class_disconnect(exp);        ldlm_cancel_locks_for_export(exp);        /* complete all outstanding replies */        spin_lock(&exp->exp_lock);        while (!list_empty(&exp->exp_outstanding_replies)) {                struct ptlrpc_reply_state *rs =                        list_entry(exp->exp_outstanding_replies.next,                                   struct ptlrpc_reply_state, rs_exp_list);                struct ptlrpc_service *svc = rs->rs_service;                spin_lock(&svc->srv_lock);                list_del_init(&rs->rs_exp_list);                ptlrpc_schedule_difficult_reply(rs);                spin_unlock(&svc->srv_lock);        }        spin_unlock(&exp->exp_lock);        class_export_put(exp);        RETURN(rc);}static int mgs_cleanup(struct obd_device *obd);static int mgs_handle(struct ptlrpc_request *req);/* Start the MGS obd */static int mgs_setup(struct obd_device *obd, obd_count len, void *buf){        struct lprocfs_static_vars lvars;        struct mgs_obd *mgs = &obd->u.mgs;        struct lustre_mount_info *lmi;        struct lustre_sb_info *lsi;        struct vfsmount *mnt;        int rc = 0;        ENTRY;        CDEBUG(D_CONFIG, "Starting MGS\n");        /* Find our disk */        lmi = server_get_mount(obd->obd_name);        if (!lmi)                 RETURN(rc = -EINVAL);        mnt = lmi->lmi_mnt;        lsi = s2lsi(lmi->lmi_sb);        obd->obd_fsops = fsfilt_get_ops(MT_STR(lsi->lsi_ldd));        if (IS_ERR(obd->obd_fsops))                GOTO(err_put, rc = PTR_ERR(obd->obd_fsops));        /* namespace for mgs llog */        obd->obd_namespace = ldlm_namespace_new("MGS", LDLM_NAMESPACE_SERVER,                                                 LDLM_NAMESPACE_MODEST);        if (obd->obd_namespace == NULL)                GOTO(err_ops, rc = -ENOMEM);        /* ldlm setup */        ptlrpc_init_client(LDLM_CB_REQUEST_PORTAL, LDLM_CB_REPLY_PORTAL,                           "mgs_ldlm_client", &obd->obd_ldlm_client);        LASSERT(!lvfs_check_rdonly(lvfs_sbdev(mnt->mnt_sb)));        rc = mgs_fs_setup(obd, mnt);        if (rc) {                CERROR("%s: MGS filesystem method init failed: rc = %d\n",                       obd->obd_name, rc);                GOTO(err_ns, rc);        }        rc = llog_setup(obd, LLOG_CONFIG_ORIG_CTXT, obd, 0, NULL,                        &llog_lvfs_ops);        if (rc)                GOTO(err_fs, rc);        /* No recovery for MGC's */        obd->obd_replayable = 0;        /* Internal mgs setup */        mgs_init_fsdb_list(obd);        sema_init(&mgs->mgs_sem, 1);        /* Start the service threads */        mgs->mgs_service =                ptlrpc_init_svc(MGS_NBUFS, MGS_BUFSIZE, MGS_MAXREQSIZE,                                MGS_MAXREPSIZE, MGS_REQUEST_PORTAL,                                MGC_REPLY_PORTAL, 2000,                                mgs_handle, LUSTRE_MGS_NAME,                                obd->obd_proc_entry, NULL,                                MGS_THREADS_AUTO_MIN, MGS_THREADS_AUTO_MAX,                                "ll_mgs");        if (!mgs->mgs_service) {                CERROR("failed to start service\n");                GOTO(err_fs, rc = -ENOMEM);        }        rc = ptlrpc_start_threads(obd, mgs->mgs_service);        if (rc)                GOTO(err_thread, rc);        /* Setup proc */        lprocfs_mgs_init_vars(&lvars);        if (lprocfs_obd_setup(obd, lvars.obd_vars) == 0) {                lproc_mgs_setup(obd);        }        ping_evictor_start();        LCONSOLE_INFO("MGS %s started\n", obd->obd_name);        RETURN(0);err_thread:        ptlrpc_unregister_service(mgs->mgs_service);err_fs:        /* No extra cleanup needed for llog_init_commit_thread() */        mgs_fs_cleanup(obd);err_ns:        ldlm_namespace_free(obd->obd_namespace, 0);        obd->obd_namespace = NULL;err_ops:        fsfilt_put_ops(obd->obd_fsops);err_put:        server_put_mount(obd->obd_name, mnt);        mgs->mgs_sb = 0;        return rc;}static int mgs_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage){        int rc = 0;        ENTRY;        switch (stage) {        case OBD_CLEANUP_EARLY:        case OBD_CLEANUP_EXPORTS:                break;        case OBD_CLEANUP_SELF_EXP:                llog_cleanup(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT));                rc = obd_llog_finish(obd, 0);                break;        case OBD_CLEANUP_OBD:                break;        }        RETURN(rc);}static int mgs_ldlm_nsfree(void *data){        struct ldlm_namespace *ns = (struct ldlm_namespace *)data;        int rc;        ENTRY;        ptlrpc_daemonize("ll_mgs_nsfree");        rc = ldlm_namespace_free(ns, 1 /* obd_force should always be on */);        RETURN(rc);}static int mgs_cleanup(struct obd_device *obd){        struct mgs_obd *mgs = &obd->u.mgs;        ENTRY;        if (mgs->mgs_sb == NULL)                RETURN(0);                ping_evictor_stop();        ptlrpc_unregister_service(mgs->mgs_service);        mgs_cleanup_fsdb_list(obd);        lproc_mgs_cleanup(obd);        mgs_fs_cleanup(obd);        server_put_mount(obd->obd_name, mgs->mgs_vfsmnt);        mgs->mgs_sb = NULL;        /* Free the namespace in it's own thread, so that if the            ldlm_cancel_handler put the last mgs obd ref, we won't            deadlock here. */        cfs_kernel_thread(mgs_ldlm_nsfree, obd->obd_namespace,                           CLONE_VM | CLONE_FILES);        fsfilt_put_ops(obd->obd_fsops);        LCONSOLE_INFO("%s has stopped.\n", obd->obd_name);        RETURN(0);}/* similar to filter_prepare_destroy */static int mgs_get_cfg_lock(struct obd_device *obd, char *fsname,                            struct lustre_handle *lockh){        struct ldlm_res_id res_id;        int rc, flags = 0;        ENTRY;        rc = mgc_fsname2resid(fsname, &res_id);        if (!rc)                 rc = ldlm_cli_enqueue_local(obd->obd_namespace, &res_id,                                            LDLM_PLAIN, NULL, LCK_EX,                                            &flags, ldlm_blocking_ast,                                            ldlm_completion_ast, NULL,                                            fsname, 0, NULL, lockh);        if (rc)                 CERROR("can't take cfg lock for %s (%d)\n", fsname, rc);                RETURN(rc);}static int mgs_put_cfg_lock(struct lustre_handle *lockh){        ENTRY;        ldlm_lock_decref(lockh, LCK_EX);        RETURN(0);}/* rc=0 means ok      1 means update     <0 means error */static int mgs_check_target(struct obd_device *obd, struct mgs_target_info *mti){        int rc;        ENTRY;        rc = mgs_check_index(obd, mti);        if (rc == 0) {                LCONSOLE_ERROR_MSG(0x13b, "%s claims to have registered, but "                                  "this MGS does not know about it.  Assuming "                                  "writeconf.\n", mti->mti_svname);                mti->mti_flags |= LDD_F_WRITECONF;                rc = 1;        } else if (rc == -1) {                LCONSOLE_ERROR_MSG(0x13c, "Client log %s-client has "                                   "disappeared! Regenerating all logs.\n",                                   mti->mti_fsname);                mti->mti_flags |= LDD_F_WRITECONF;                rc = 1;        } else {                /* Index is correctly marked as used */                /* If the logs don't contain the mti_nids then add                    them as failover nids */                rc = mgs_check_failnid(obd, mti);        }        RETURN(rc);}/* Called whenever a target starts up.  Flags indicate first connect, etc. */static int mgs_handle_target_reg(struct ptlrpc_request *req){            struct obd_device *obd = req->rq_export->exp_obd;        struct lustre_handle lockh;        struct mgs_target_info *mti, *rep_mti;        int rep_size[] = { sizeof(struct ptlrpc_body), sizeof(*mti) };        int rc = 0, lockrc;        ENTRY;        mgs_counter_incr(req->rq_export, LPROC_MGS_TARGET_REG);        mti = lustre_swab_reqbuf(req, REQ_REC_OFF, sizeof(*mti),                                 lustre_swab_mgs_target_info);                if (!(mti->mti_flags & (LDD_F_WRITECONF | LDD_F_UPGRADE14 |                                LDD_F_UPDATE))) {                /* We're just here as a startup ping. */                CDEBUG(D_MGS, "Server %s is running on %s\n",                       mti->mti_svname, obd_export_nid2str(req->rq_export));                rc = mgs_check_target(obd, mti);                /* above will set appropriate mti flags */                if (rc <= 0)                         /* Nothing wrong, or fatal error */                        GOTO(out_nolock, rc);        }        /* Revoke the config lock to make sure nobody is reading. */        /* Although actually I think it should be alright if           someone was reading while we were updating the logs - if we            revoke at the end they will just update from where they left off. */        lockrc = mgs_get_cfg_lock(obd, mti->mti_fsname, &lockh);        if (lockrc != ELDLM_OK) {                LCONSOLE_ERROR_MSG(0x13d, "%s: Can't signal other nodes to "                                   "update their configuration (%d). Updating "                                   "local logs anyhow; you might have to "                                   "manually restart other nodes to get the "                                   "latest configuration.\n",                                   obd->obd_name, lockrc);        }        OBD_FAIL_TIMEOUT(OBD_FAIL_MGS_PAUSE_TARGET_REG, 10);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?