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 + -
显示快捷键?