linux/drivers/staging/lustre/lustre/lmv/lproc_lmv.c
<<
>>
Prefs
   1/*
   2 * GPL HEADER START
   3 *
   4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License version 2 only,
   8 * as published by the Free Software Foundation.
   9 *
  10 * This program is distributed in the hope that it will be useful, but
  11 * WITHOUT ANY WARRANTY; without even the implied warranty of
  12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13 * General Public License version 2 for more details (a copy is included
  14 * in the LICENSE file that accompanied this code).
  15 *
  16 * You should have received a copy of the GNU General Public License
  17 * version 2 along with this program; If not, see
  18 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
  19 *
  20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  21 * CA 95054 USA or visit www.sun.com if you need additional information or
  22 * have any questions.
  23 *
  24 * GPL HEADER END
  25 */
  26/*
  27 * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
  28 * Use is subject to license terms.
  29 *
  30 * Copyright (c) 2012, Intel Corporation.
  31 */
  32/*
  33 * This file is part of Lustre, http://www.lustre.org/
  34 * Lustre is a trademark of Sun Microsystems, Inc.
  35 */
  36
  37#define DEBUG_SUBSYSTEM S_CLASS
  38
  39#include <linux/seq_file.h>
  40#include <linux/statfs.h>
  41#include "../include/lprocfs_status.h"
  42#include "../include/obd_class.h"
  43#include "lmv_internal.h"
  44
  45static ssize_t numobd_show(struct kobject *kobj, struct attribute *attr,
  46                           char *buf)
  47{
  48        struct obd_device *dev = container_of(kobj, struct obd_device,
  49                                              obd_kobj);
  50        struct lmv_desc *desc;
  51
  52        desc = &dev->u.lmv.desc;
  53        return sprintf(buf, "%u\n", desc->ld_tgt_count);
  54}
  55LUSTRE_RO_ATTR(numobd);
  56
  57static const char *placement_name[] = {
  58        [PLACEMENT_CHAR_POLICY] = "CHAR",
  59        [PLACEMENT_NID_POLICY]  = "NID",
  60        [PLACEMENT_INVAL_POLICY]  = "INVAL"
  61};
  62
  63static enum placement_policy placement_name2policy(char *name, int len)
  64{
  65        int                  i;
  66
  67        for (i = 0; i < PLACEMENT_MAX_POLICY; i++) {
  68                if (!strncmp(placement_name[i], name, len))
  69                        return i;
  70        }
  71        return PLACEMENT_INVAL_POLICY;
  72}
  73
  74static const char *placement_policy2name(enum placement_policy placement)
  75{
  76        LASSERT(placement < PLACEMENT_MAX_POLICY);
  77        return placement_name[placement];
  78}
  79
  80static ssize_t placement_show(struct kobject *kobj, struct attribute *attr,
  81                              char *buf)
  82{
  83        struct obd_device *dev = container_of(kobj, struct obd_device,
  84                                              obd_kobj);
  85        struct lmv_obd *lmv;
  86
  87        lmv = &dev->u.lmv;
  88        return sprintf(buf, "%s\n", placement_policy2name(lmv->lmv_placement));
  89}
  90
  91#define MAX_POLICY_STRING_SIZE 64
  92
  93static ssize_t placement_store(struct kobject *kobj, struct attribute *attr,
  94                               const char *buffer,
  95                               size_t count)
  96{
  97        struct obd_device *dev = container_of(kobj, struct obd_device,
  98                                              obd_kobj);
  99        char dummy[MAX_POLICY_STRING_SIZE + 1];
 100        enum placement_policy policy;
 101        struct lmv_obd *lmv = &dev->u.lmv;
 102
 103        memcpy(dummy, buffer, MAX_POLICY_STRING_SIZE);
 104
 105        if (count > MAX_POLICY_STRING_SIZE)
 106                count = MAX_POLICY_STRING_SIZE;
 107
 108        if (dummy[count - 1] == '\n')
 109                count--;
 110        dummy[count] = '\0';
 111
 112        policy = placement_name2policy(dummy, count);
 113        if (policy != PLACEMENT_INVAL_POLICY) {
 114                spin_lock(&lmv->lmv_lock);
 115                lmv->lmv_placement = policy;
 116                spin_unlock(&lmv->lmv_lock);
 117        } else {
 118                return -EINVAL;
 119        }
 120        return count;
 121}
 122LUSTRE_RW_ATTR(placement);
 123
 124static ssize_t activeobd_show(struct kobject *kobj, struct attribute *attr,
 125                              char *buf)
 126{
 127        struct obd_device *dev = container_of(kobj, struct obd_device,
 128                                              obd_kobj);
 129        struct lmv_desc *desc;
 130
 131        desc = &dev->u.lmv.desc;
 132        return sprintf(buf, "%u\n", desc->ld_active_tgt_count);
 133}
 134LUSTRE_RO_ATTR(activeobd);
 135
 136static int lmv_desc_uuid_seq_show(struct seq_file *m, void *v)
 137{
 138        struct obd_device *dev = (struct obd_device *)m->private;
 139        struct lmv_obd    *lmv;
 140
 141        LASSERT(dev);
 142        lmv = &dev->u.lmv;
 143        seq_printf(m, "%s\n", lmv->desc.ld_uuid.uuid);
 144        return 0;
 145}
 146
 147LPROC_SEQ_FOPS_RO(lmv_desc_uuid);
 148
 149static void *lmv_tgt_seq_start(struct seq_file *p, loff_t *pos)
 150{
 151        struct obd_device       *dev = p->private;
 152        struct lmv_obd    *lmv = &dev->u.lmv;
 153
 154        return (*pos >= lmv->desc.ld_tgt_count) ? NULL : lmv->tgts[*pos];
 155}
 156
 157static void lmv_tgt_seq_stop(struct seq_file *p, void *v)
 158{
 159        return;
 160}
 161
 162static void *lmv_tgt_seq_next(struct seq_file *p, void *v, loff_t *pos)
 163{
 164        struct obd_device       *dev = p->private;
 165        struct lmv_obd    *lmv = &dev->u.lmv;
 166        ++*pos;
 167        return (*pos >= lmv->desc.ld_tgt_count) ? NULL : lmv->tgts[*pos];
 168}
 169
 170static int lmv_tgt_seq_show(struct seq_file *p, void *v)
 171{
 172        struct lmv_tgt_desc     *tgt = v;
 173
 174        if (!tgt)
 175                return 0;
 176        seq_printf(p, "%d: %s %sACTIVE\n",
 177                   tgt->ltd_idx, tgt->ltd_uuid.uuid,
 178                   tgt->ltd_active ? "" : "IN");
 179        return 0;
 180}
 181
 182static const struct seq_operations lmv_tgt_sops = {
 183        .start           = lmv_tgt_seq_start,
 184        .stop             = lmv_tgt_seq_stop,
 185        .next             = lmv_tgt_seq_next,
 186        .show             = lmv_tgt_seq_show,
 187};
 188
 189static int lmv_target_seq_open(struct inode *inode, struct file *file)
 190{
 191        struct seq_file  *seq;
 192        int                  rc;
 193
 194        rc = seq_open(file, &lmv_tgt_sops);
 195        if (rc)
 196                return rc;
 197
 198        seq = file->private_data;
 199        seq->private = inode->i_private;
 200
 201        return 0;
 202}
 203
 204static struct lprocfs_vars lprocfs_lmv_obd_vars[] = {
 205        { "desc_uuid",    &lmv_desc_uuid_fops,    NULL, 0 },
 206        { NULL }
 207};
 208
 209struct file_operations lmv_proc_target_fops = {
 210        .owner          = THIS_MODULE,
 211        .open            = lmv_target_seq_open,
 212        .read            = seq_read,
 213        .llseek        = seq_lseek,
 214        .release              = seq_release,
 215};
 216
 217static struct attribute *lmv_attrs[] = {
 218        &lustre_attr_activeobd.attr,
 219        &lustre_attr_numobd.attr,
 220        &lustre_attr_placement.attr,
 221        NULL,
 222};
 223
 224static struct attribute_group lmv_attr_group = {
 225        .attrs = lmv_attrs,
 226};
 227
 228void lprocfs_lmv_init_vars(struct lprocfs_static_vars *lvars)
 229{
 230        lvars->sysfs_vars     = &lmv_attr_group;
 231        lvars->obd_vars       = lprocfs_lmv_obd_vars;
 232}
 233