obd_config.c

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

C
1,244
字号
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- * vim:expandtab:shiftwidth=8:tabstop=8: * *  Copyright (c) 2001-2006 Cluster File Systems, Inc. * *   This file is part of the Lustre file system, http://www.lustre.org *   Lustre is a trademark of Cluster File Systems, Inc. * *   You may have signed or agreed to another license before downloading *   this software.  If so, you are bound by the terms and conditions *   of that agreement, and the following does not apply to you.  See the *   LICENSE file included with this distribution for more information. * *   If you did not agree to a different license, then this copy of Lustre *   is open source 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. * *   In either case, 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 *   license text for more details. * * Config API * */#define DEBUG_SUBSYSTEM S_CLASS#ifdef __KERNEL__#include <obd_class.h>#include <linux/string.h>#else#include <liblustre.h>#include <obd_class.h>#include <obd.h>#endif#include <lustre_log.h>#include <lprocfs_status.h>#include <libcfs/list.h>#include <lustre_param.h>#include <class_hash.h>extern struct lustre_hash_operations uuid_hash_operations;extern struct lustre_hash_operations nid_hash_operations;/*********** string parsing utils *********//* returns 0 if we find this key in the buffer, else 1 */int class_find_param(char *buf, char *key, char **valp){        char *ptr;        if (!buf)                 return 1;        if ((ptr = strstr(buf, key)) == NULL)                 return 1;        if (valp)                 *valp = ptr + strlen(key);                return 0;}/* returns 0 if this is the first key in the buffer, else 1.   valp points to first char after key. */int class_match_param(char *buf, char *key, char **valp){        if (!buf)                 return 1;        if (memcmp(buf, key, strlen(key)) != 0)                 return 1;        if (valp)                 *valp = buf + strlen(key);                return 0;}/* 0 is good nid,    1 not found   < 0 error   endh is set to next separator */int class_parse_nid(char *buf, lnet_nid_t *nid, char **endh){        char tmp, *endp;        if (!buf)                 return 1;        while (*buf == ',' || *buf == ':')                 buf++;        if (*buf == ' ' || *buf == '/' || *buf == '\0')                 return 1;        /* nid separators or end of nids */        endp = strpbrk(buf, ",: /");        if (endp == NULL)                 endp = buf + strlen(buf);        tmp = *endp;        *endp = '\0';        *nid = libcfs_str2nid(buf);        if (*nid == LNET_NID_ANY) {                LCONSOLE_ERROR_MSG(0x159, "Can't parse NID '%s'\n", buf);                *endp = tmp;                return -EINVAL;        }        *endp = tmp;        if (endh)                 *endh = endp;        CDEBUG(D_INFO, "Nid %s\n", libcfs_nid2str(*nid));        return 0;}EXPORT_SYMBOL(class_find_param);EXPORT_SYMBOL(class_match_param);EXPORT_SYMBOL(class_parse_nid);/********************** class fns **********************//* Create a new device and set the type, name and uuid.  If * successful, the new device can be accessed by either name or uuid. */int class_attach(struct lustre_cfg *lcfg){        struct obd_device *obd = NULL;        char *typename, *name, *uuid;        int rc, len;        ENTRY;        if (!LUSTRE_CFG_BUFLEN(lcfg, 1)) {                CERROR("No type passed!\n");                RETURN(-EINVAL);        }        typename = lustre_cfg_string(lcfg, 1);        if (!LUSTRE_CFG_BUFLEN(lcfg, 0)) {                CERROR("No name passed!\n");                RETURN(-EINVAL);        }        name = lustre_cfg_string(lcfg, 0);        if (!LUSTRE_CFG_BUFLEN(lcfg, 2)) {                CERROR("No UUID passed!\n");                RETURN(-EINVAL);        }        uuid = lustre_cfg_string(lcfg, 2);        CDEBUG(D_IOCTL, "attach type %s name: %s uuid: %s\n",               MKSTR(typename), MKSTR(name), MKSTR(uuid));        /* Mountconf transitional hack, should go away after 1.6.           1.4.7 uses the old names, so translate back if the           mountconf flag is set.           1.6 should set this flag, and translate the other way here           if not set. */        if (lcfg->lcfg_flags & LCFG_FLG_MOUNTCONF){                char *tmp = NULL;                if (strcmp(typename, "mds") == 0)                        tmp = "mdt";                if (strcmp(typename, "mdt") == 0)                        tmp = "mds";                if (strcmp(typename, "osd") == 0)                        tmp = "obdfilter";                if (tmp) {                        LCONSOLE_WARN("Using type %s for %s %s\n", tmp,                                      MKSTR(typename), MKSTR(name));                        typename = tmp;                }        }        obd = class_newdev(typename, name);        if (IS_ERR(obd)) {                /* Already exists or out of obds */                rc = PTR_ERR(obd);                obd = NULL;                CERROR("Cannot create device %s of type %s : %d\n",                       name, typename, rc);                GOTO(out, rc);        }        LASSERTF(obd != NULL, "Cannot get obd device %s of type %s\n",                 name, typename);        LASSERTF(obd->obd_magic == OBD_DEVICE_MAGIC,                  "obd %p obd_magic %08X != %08X\n",                 obd, obd->obd_magic, OBD_DEVICE_MAGIC);        LASSERTF(strncmp(obd->obd_name, name, strlen(name)) == 0, "%p obd_name %s != %s\n",                 obd, obd->obd_name, name);        CFS_INIT_LIST_HEAD(&obd->obd_exports);        CFS_INIT_LIST_HEAD(&obd->obd_exports_timed);        CFS_INIT_LIST_HEAD(&obd->obd_nid_stats);        spin_lock_init(&obd->nid_lock);        spin_lock_init(&obd->obd_dev_lock);        sema_init(&obd->obd_dev_sem, 1);        spin_lock_init(&obd->obd_osfs_lock);        /* obd->obd_osfs_age must be set to a value in the distant         * past to guarantee a fresh statfs is fetched on mount. */        obd->obd_osfs_age = cfs_time_shift_64(-1000);        /* XXX belongs in setup not attach  */        /* recovery data */        cfs_init_timer(&obd->obd_recovery_timer);        spin_lock_init(&obd->obd_processing_task_lock);        cfs_waitq_init(&obd->obd_next_transno_waitq);        cfs_waitq_init(&obd->obd_evict_inprogress_waitq);        cfs_waitq_init(&obd->obd_llog_waitq);        CFS_INIT_LIST_HEAD(&obd->obd_recovery_queue);        CFS_INIT_LIST_HEAD(&obd->obd_delayed_reply_queue);        spin_lock_init(&obd->obd_uncommitted_replies_lock);        CFS_INIT_LIST_HEAD(&obd->obd_uncommitted_replies);        len = strlen(uuid);        if (len >= sizeof(obd->obd_uuid)) {                CERROR("uuid must be < %d bytes long\n",                       (int)sizeof(obd->obd_uuid));                GOTO(out, rc = -EINVAL);        }        memcpy(obd->obd_uuid.uuid, uuid, len);        /* do the attach */        if (OBP(obd, attach)) {                rc = OBP(obd,attach)(obd, sizeof *lcfg, lcfg);                if (rc)                        GOTO(out, rc = -EINVAL);        }        /* Detach drops this */        spin_lock(&obd->obd_dev_lock);        atomic_set(&obd->obd_refcount, 1);        spin_unlock(&obd->obd_dev_lock);        obd->obd_attached = 1;        CDEBUG(D_IOCTL, "OBD: dev %d attached type %s with refcount %d\n",               obd->obd_minor, typename, atomic_read(&obd->obd_refcount));        RETURN(0); out:        if (obd != NULL) {                class_release_dev(obd);        }        return rc;}int class_setup(struct obd_device *obd, struct lustre_cfg *lcfg){        int err = 0;        struct obd_export *exp;        ENTRY;        LASSERT(obd != NULL);        LASSERTF(obd == class_num2obd(obd->obd_minor), "obd %p != obd_devs[%d] %p\n",                  obd, obd->obd_minor, class_num2obd(obd->obd_minor));        LASSERTF(obd->obd_magic == OBD_DEVICE_MAGIC, "obd %p obd_magic %08x != %08x\n",                  obd, obd->obd_magic, OBD_DEVICE_MAGIC);        /* have we attached a type to this device? */        if (!obd->obd_attached) {                CERROR("Device %d not attached\n", obd->obd_minor);                RETURN(-ENODEV);        }        if (obd->obd_set_up) {                CERROR("Device %d already setup (type %s)\n",                       obd->obd_minor, obd->obd_type->typ_name);                RETURN(-EEXIST);        }        /* is someone else setting us up right now? (attach inits spinlock) */        spin_lock(&obd->obd_dev_lock);        if (obd->obd_starting) {                spin_unlock(&obd->obd_dev_lock);                CERROR("Device %d setup in progress (type %s)\n",                       obd->obd_minor, obd->obd_type->typ_name);                RETURN(-EEXIST);        }        /* just leave this on forever.  I can't use obd_set_up here because           other fns check that status, and we're not actually set up yet. */        obd->obd_starting = 1;        spin_unlock(&obd->obd_dev_lock);        /* create an uuid-export hash body */        err = lustre_hash_init(&obd->obd_uuid_hash_body, "UUID_HASH",                               128, &uuid_hash_operations);        if (err)                GOTO(err_hash, err);        /* create a nid-export hash body */        err = lustre_hash_init(&obd->obd_nid_hash_body, "NID_HASH",                               128, &nid_hash_operations);        if (err)                GOTO(err_hash, err);        /* create a nid-stats hash body */        err = lustre_hash_init(&obd->obd_nid_stats_hash_body, "NID_STATS",                               128, &nid_stat_hash_operations);        if (err)                GOTO(err_hash, err);        exp = class_new_export(obd, &obd->obd_uuid);        if (IS_ERR(exp))                RETURN(PTR_ERR(exp));        obd->obd_self_export = exp;        list_del_init(&exp->exp_obd_chain_timed);        class_export_put(exp);        err = obd_setup(obd, sizeof(*lcfg), lcfg);        if (err)                GOTO(err_exp, err);        obd->obd_set_up = 1;        spin_lock(&obd->obd_dev_lock);        /* cleanup drops this */        class_incref(obd);        spin_unlock(&obd->obd_dev_lock);        CDEBUG(D_IOCTL, "finished setup of obd %s (uuid %s)\n",               obd->obd_name, obd->obd_uuid.uuid);        RETURN(0);err_exp:        class_unlink_export(obd->obd_self_export);        obd->obd_self_export = NULL;err_hash:        lustre_hash_exit(&obd->obd_uuid_hash_body);        lustre_hash_exit(&obd->obd_nid_hash_body);        lustre_hash_exit(&obd->obd_nid_stats_hash_body);        obd->obd_starting = 0;        CERROR("setup %s failed (%d)\n", obd->obd_name, err);        RETURN(err);}int class_detach(struct obd_device *obd, struct lustre_cfg *lcfg){        ENTRY;        if (obd->obd_set_up) {                CERROR("OBD device %d still set up\n", obd->obd_minor);                RETURN(-EBUSY);        }        spin_lock(&obd->obd_dev_lock);        if (!obd->obd_attached) {                spin_unlock(&obd->obd_dev_lock);                CERROR("OBD device %d not attached\n", obd->obd_minor);                RETURN(-ENODEV);        }        obd->obd_attached = 0;        spin_unlock(&obd->obd_dev_lock);        CDEBUG(D_IOCTL, "detach on obd %s (uuid %s)\n",               obd->obd_name, obd->obd_uuid.uuid);        class_decref(obd);                /* not strictly necessary, but cleans up eagerly */        obd_zombie_impexp_cull();                RETURN(0);}static void dump_exports(struct obd_device *obd){        struct obd_export *exp, *n;        list_for_each_entry_safe(exp, n, &obd->obd_exports, exp_obd_chain) {                struct ptlrpc_reply_state *rs;                struct ptlrpc_reply_state *first_reply = NULL;                int                        nreplies = 0;                list_for_each_entry (rs, &exp->exp_outstanding_replies,                                     rs_exp_list) {                        if (nreplies == 0)                                first_reply = rs;                        nreplies++;                }                CDEBUG(D_IOCTL, "%s: %p %s %s %d %d %d: %p %s\n",                       obd->obd_name, exp, exp->exp_client_uuid.uuid,                       obd_export_nid2str(exp),                       atomic_read(&exp->exp_refcount),                       exp->exp_failed, nreplies, first_reply,                       nreplies > 3 ? "..." : "");        }}int class_cleanup(struct obd_device *obd, struct lustre_cfg *lcfg){        int err = 0;        char *flag;        ENTRY;        OBD_RACE(OBD_FAIL_LDLM_RECOV_CLIENTS);        if (!obd->obd_set_up) {                CERROR("Device %d not setup\n", obd->obd_minor);                RETURN(-ENODEV);        }        spin_lock(&obd->obd_dev_lock);        if (obd->obd_stopping) {                spin_unlock(&obd->obd_dev_lock);                CERROR("OBD %d already stopping\n", obd->obd_minor);                RETURN(-ENODEV);        }        /* Leave this on forever */        obd->obd_stopping = 1;        spin_unlock(&obd->obd_dev_lock);        if (lcfg->lcfg_bufcount >= 2 && LUSTRE_CFG_BUFLEN(lcfg, 1) > 0) {                for (flag = lustre_cfg_string(lcfg, 1); *flag != 0; flag++)                        switch (*flag) {

⌨️ 快捷键说明

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