mgs_llog.c

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

C
1,680
字号
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- * vim:expandtab:shiftwidth=8:tabstop=8: * *  lustre/mgs/mgs_llog.c *  Lustre Management Server (mgs) config llog creation * *  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/fs.h>#endif#include <obd.h>#include <obd_lov.h>#include <obd_class.h>#include <lustre_log.h>#include <obd_ost.h>#include <libcfs/list.h>#include <linux/lvfs.h>#include <lustre_fsfilt.h>#include <lustre_disk.h>#include <lustre_param.h>#include "mgs_internal.h"/******************** Class functions *********************//* Caller must list_del and OBD_FREE each dentry from the list */int class_dentry_readdir(struct obd_device *obd, struct dentry *dir,                         struct vfsmount *inmnt,                          struct list_head *dentry_list){        /* see mds_cleanup_pending */        struct lvfs_run_ctxt saved;        struct file *file;        struct dentry *dentry;        struct vfsmount *mnt;        int rc = 0;        ENTRY;        push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);        dentry = dget(dir);        if (IS_ERR(dentry))                GOTO(out_pop, rc = PTR_ERR(dentry));        mnt = mntget(inmnt);        if (IS_ERR(mnt)) {                l_dput(dentry);                GOTO(out_pop, rc = PTR_ERR(mnt));        }        file = dentry_open(dentry, mnt, O_RDONLY);        if (IS_ERR(file))                /* dentry_open_it() drops the dentry, mnt refs */                GOTO(out_pop, rc = PTR_ERR(file));        INIT_LIST_HEAD(dentry_list);        rc = l_readdir(file, dentry_list);        filp_close(file, 0);        /*  filp_close->fput() drops the dentry, mnt refs */out_pop:        pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);        RETURN(rc);}/******************** DB functions *********************/static inline int name_create(char **newname, char *prefix, char *suffix){        LASSERT(newname);        OBD_ALLOC(*newname, strlen(prefix) + strlen(suffix) + 1);        if (!*newname)                 return -ENOMEM;        sprintf(*newname, "%s%s", prefix, suffix);        return 0;}static inline void name_destroy(char **name){                if (*name)                OBD_FREE(*name, strlen(*name) + 1);        *name = NULL;}/* from the (client) config log, figure out:        1. which ost's/mdt's are configured (by index)        2. what the last config step is        3. COMPAT_146 lov name        4. COMPAT_146 mdt lov name        5. COMPAT_146 mdc name *//* It might be better to have a separate db file, instead of parsing the info   out of the client log.  This is slow and potentially error-prone. */static int mgs_fsdb_handler(struct llog_handle *llh, struct llog_rec_hdr *rec,                             void *data){        struct fs_db *fsdb = (struct fs_db *)data;        int cfg_len = rec->lrh_len;        char *cfg_buf = (char*) (rec + 1);        struct lustre_cfg *lcfg;        __u32 index;        int rc = 0;        ENTRY;        if (rec->lrh_type != OBD_CFG_REC) {                CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);                RETURN(-EINVAL);        }        rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);        if (rc) {                CERROR("Insane cfg\n");                RETURN(rc);        }        lcfg = (struct lustre_cfg *)cfg_buf;        CDEBUG(D_INFO, "cmd %x %s %s\n", lcfg->lcfg_command,                lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));        /* Figure out ost indicies */         /* lov_modify_tgts add 0:lov1  1:ost1_UUID  2(index):0  3(gen):1 */        if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD ||            lcfg->lcfg_command == LCFG_LOV_DEL_OBD) {                index = simple_strtoul(lustre_cfg_string(lcfg, 2),                                       NULL, 10);                CDEBUG(D_MGS, "OST index for %s is %u (%s)\n",                       lustre_cfg_string(lcfg, 1), index,                        lustre_cfg_string(lcfg, 2));                set_bit(index, fsdb->fsdb_ost_index_map);        }                /* Figure out mdt indicies */        /* attach   0:MDC_uml1_mdsA_MNT_client  1:mdc  2:1d834_MNT_client_03f */        if ((lcfg->lcfg_command == LCFG_ATTACH) &&            (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_MDC_NAME) == 0)) {                rc = server_name2index(lustre_cfg_string(lcfg, 0),                                       &index, NULL);                if (rc != LDD_F_SV_TYPE_MDT) {                        CWARN("Unparsable MDC name %s, assuming index 0\n",                              lustre_cfg_string(lcfg, 0));                        index = 0;                }                rc = 0;                CDEBUG(D_MGS, "MDT index is %u\n", index);                set_bit(index, fsdb->fsdb_mdt_index_map);        }        /* COMPAT_146 */        /* figure out the old LOV name. fsdb_gen = 0 means old log */        /* #01 L attach 0:lov_mdsA 1:lov 2:cdbe9_lov_mdsA_dc8cf7f3bb */        if ((fsdb->fsdb_gen == 0) && (lcfg->lcfg_command == LCFG_ATTACH) &&            (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_LOV_NAME) == 0)) {                fsdb->fsdb_flags |= FSDB_OLDLOG14;                name_destroy(&fsdb->fsdb_clilov);                rc = name_create(&fsdb->fsdb_clilov,                                  lustre_cfg_string(lcfg, 0), "");                if (rc)                         RETURN(rc);                CDEBUG(D_MGS, "client lov name is %s\n", fsdb->fsdb_clilov);        }        /* figure out the old MDT lov name from the MDT uuid */        if ((fsdb->fsdb_gen == 0) && (lcfg->lcfg_command == LCFG_SETUP) &&            (strncmp(lustre_cfg_string(lcfg, 0), "MDC_", 4) == 0)) {                char *ptr;                fsdb->fsdb_flags |= FSDB_OLDLOG14;                ptr = strstr(lustre_cfg_string(lcfg, 1), "_UUID");                if (!ptr) {                        CERROR("Can't parse MDT uuid %s\n",                                lustre_cfg_string(lcfg, 1));                        RETURN(-EINVAL);                }                *ptr = '\0';                name_destroy(&fsdb->fsdb_mdtlov);                rc = name_create(&fsdb->fsdb_mdtlov,                                  "lov_", lustre_cfg_string(lcfg, 1));                if (rc)                         RETURN(rc);                name_destroy(&fsdb->fsdb_mdc);                rc = name_create(&fsdb->fsdb_mdc,                                  lustre_cfg_string(lcfg, 0), "");                if (rc)                         RETURN(rc);                CDEBUG(D_MGS, "MDT lov name is %s\n", fsdb->fsdb_mdtlov);        }        /* end COMPAT_146 */        /* Keep track of the latest marker step */        if (lcfg->lcfg_command == LCFG_MARKER) {                struct cfg_marker *marker;                marker = lustre_cfg_buf(lcfg, 1);                fsdb->fsdb_gen = max(fsdb->fsdb_gen, marker->cm_step);        }        RETURN(rc);}static int mgs_get_fsdb_from_llog(struct obd_device *obd, struct fs_db *fsdb){        char *logname;        struct llog_handle *loghandle;        struct lvfs_run_ctxt saved;        struct llog_ctxt *ctxt;        int rc, rc2;        ENTRY;        ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);        LASSERT(ctxt != NULL);        name_create(&logname, fsdb->fsdb_name, "-client");        down(&fsdb->fsdb_sem);        push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);        rc = llog_create(ctxt, &loghandle, NULL, logname);        if (rc)                GOTO(out_pop, rc);        rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);        if (rc)                GOTO(out_close, rc);        if (llog_get_size(loghandle) <= 1)                fsdb->fsdb_flags |= FSDB_LOG_EMPTY;        rc = llog_process(loghandle, mgs_fsdb_handler, (void *)fsdb, NULL);        CDEBUG(D_INFO, "get_db = %d\n", rc);out_close:        rc2 = llog_close(loghandle);        if (!rc)                rc = rc2;out_pop:        llog_ctxt_put(ctxt);        pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);        up(&fsdb->fsdb_sem);        name_destroy(&logname);        RETURN(rc);}static struct fs_db *mgs_find_fsdb(struct obd_device *obd, char *fsname){        struct mgs_obd *mgs = &obd->u.mgs;        struct fs_db *fsdb;        struct list_head *tmp;        list_for_each(tmp, &mgs->mgs_fs_db_list) {                fsdb = list_entry(tmp, struct fs_db, fsdb_list);                if (strcmp(fsdb->fsdb_name, fsname) == 0)                        return fsdb;        }        return NULL;}/* caller must hold the mgs->mgs_fs_db_lock */static struct fs_db *mgs_new_fsdb(struct obd_device *obd, char *fsname){        struct mgs_obd *mgs = &obd->u.mgs;        struct fs_db *fsdb;        int rc;        ENTRY;                OBD_ALLOC_PTR(fsdb);        if (!fsdb)                 RETURN(NULL);        OBD_ALLOC(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);        OBD_ALLOC(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);        if (!fsdb->fsdb_ost_index_map || !fsdb->fsdb_mdt_index_map) {                CERROR("No memory for index maps\n");                GOTO(err, 0);        }                strncpy(fsdb->fsdb_name, fsname, sizeof(fsdb->fsdb_name));        fsdb->fsdb_name[sizeof(fsdb->fsdb_name) - 1] = 0;        rc = name_create(&fsdb->fsdb_mdtlov, fsname, "-mdtlov");        if (rc)                 GOTO(err, rc);        rc = name_create(&fsdb->fsdb_clilov, fsname, "-clilov");        if (rc)                 GOTO(err, rc);        sema_init(&fsdb->fsdb_sem, 1);        list_add(&fsdb->fsdb_list, &mgs->mgs_fs_db_list);        lproc_mgs_add_live(obd, fsdb);        RETURN(fsdb);err:        if (fsdb->fsdb_ost_index_map)                 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);        if (fsdb->fsdb_mdt_index_map)                 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);        name_destroy(&fsdb->fsdb_clilov);         name_destroy(&fsdb->fsdb_mdtlov);         OBD_FREE_PTR(fsdb);        RETURN(NULL);}static void mgs_free_fsdb(struct obd_device *obd, struct fs_db *fsdb){        /* wait for anyone with the sem */        down(&fsdb->fsdb_sem);        lproc_mgs_del_live(obd, fsdb);        list_del(&fsdb->fsdb_list);        OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);        OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);        name_destroy(&fsdb->fsdb_clilov);         name_destroy(&fsdb->fsdb_mdtlov);         name_destroy(&fsdb->fsdb_mdc);         OBD_FREE_PTR(fsdb);}int mgs_init_fsdb_list(struct obd_device *obd){        struct mgs_obd *mgs = &obd->u.mgs;

⌨️ 快捷键说明

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