blob: 20bbdfc21d15d4ddbb217d8b5d1de4648272ad1c [file] [log] [blame]
Peng Taod7e09d02013-05-02 16:46:55 +08001/*
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
Oleg Drokin6a5b99a2016-06-14 23:33:40 -040018 * http://www.gnu.org/licenses/gpl-2.0.html
Peng Taod7e09d02013-05-02 16:46:55 +080019 *
Peng Taod7e09d02013-05-02 16:46:55 +080020 * GPL HEADER END
21 */
22/*
23 * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Use is subject to license terms.
25 *
26 * Copyright (c) 2012, Intel Corporation.
27 */
28/*
29 * This file is part of Lustre, http://www.lustre.org/
30 * Lustre is a trademark of Sun Microsystems, Inc.
31 */
32
33#define DEBUG_SUBSYSTEM S_CLASS
34
Peng Taod7e09d02013-05-02 16:46:55 +080035#include <linux/seq_file.h>
Filipe Gonçalves588a12d2014-09-05 05:09:46 +010036#include <linux/statfs.h>
Greg Kroah-Hartmana8c495a2014-07-11 21:57:32 -070037#include "../include/lprocfs_status.h"
38#include "../include/obd_class.h"
Darshana Padmadas80e17732015-03-28 23:13:53 +053039#include "lmv_internal.h"
Peng Taod7e09d02013-05-02 16:46:55 +080040
Oleg Drokinb5fa70d2015-05-21 15:32:23 -040041static ssize_t numobd_show(struct kobject *kobj, struct attribute *attr,
42 char *buf)
Peng Taod7e09d02013-05-02 16:46:55 +080043{
Oleg Drokinb5fa70d2015-05-21 15:32:23 -040044 struct obd_device *dev = container_of(kobj, struct obd_device,
45 obd_kobj);
46 struct lmv_desc *desc;
Peng Taod7e09d02013-05-02 16:46:55 +080047
Peng Taod7e09d02013-05-02 16:46:55 +080048 desc = &dev->u.lmv.desc;
Oleg Drokinb5fa70d2015-05-21 15:32:23 -040049 return sprintf(buf, "%u\n", desc->ld_tgt_count);
Peng Taod7e09d02013-05-02 16:46:55 +080050}
Oleg Drokinb5fa70d2015-05-21 15:32:23 -040051LUSTRE_RO_ATTR(numobd);
Peng Taod7e09d02013-05-02 16:46:55 +080052
53static const char *placement_name[] = {
54 [PLACEMENT_CHAR_POLICY] = "CHAR",
55 [PLACEMENT_NID_POLICY] = "NID",
56 [PLACEMENT_INVAL_POLICY] = "INVAL"
57};
58
Hugues Morissetfe672992014-09-09 16:36:26 +020059static enum placement_policy placement_name2policy(char *name, int len)
Peng Taod7e09d02013-05-02 16:46:55 +080060{
61 int i;
62
63 for (i = 0; i < PLACEMENT_MAX_POLICY; i++) {
64 if (!strncmp(placement_name[i], name, len))
65 return i;
66 }
67 return PLACEMENT_INVAL_POLICY;
68}
69
Hugues Morissetfe672992014-09-09 16:36:26 +020070static const char *placement_policy2name(enum placement_policy placement)
Peng Taod7e09d02013-05-02 16:46:55 +080071{
72 LASSERT(placement < PLACEMENT_MAX_POLICY);
73 return placement_name[placement];
74}
75
Oleg Drokinb5fa70d2015-05-21 15:32:23 -040076static ssize_t placement_show(struct kobject *kobj, struct attribute *attr,
77 char *buf)
Peng Taod7e09d02013-05-02 16:46:55 +080078{
Oleg Drokinb5fa70d2015-05-21 15:32:23 -040079 struct obd_device *dev = container_of(kobj, struct obd_device,
80 obd_kobj);
81 struct lmv_obd *lmv;
Peng Taod7e09d02013-05-02 16:46:55 +080082
Peng Taod7e09d02013-05-02 16:46:55 +080083 lmv = &dev->u.lmv;
Oleg Drokinb5fa70d2015-05-21 15:32:23 -040084 return sprintf(buf, "%s\n", placement_policy2name(lmv->lmv_placement));
Peng Taod7e09d02013-05-02 16:46:55 +080085}
86
87#define MAX_POLICY_STRING_SIZE 64
88
Oleg Drokinb5fa70d2015-05-21 15:32:23 -040089static ssize_t placement_store(struct kobject *kobj, struct attribute *attr,
90 const char *buffer,
91 size_t count)
Peng Taod7e09d02013-05-02 16:46:55 +080092{
Oleg Drokinb5fa70d2015-05-21 15:32:23 -040093 struct obd_device *dev = container_of(kobj, struct obd_device,
94 obd_kobj);
95 char dummy[MAX_POLICY_STRING_SIZE + 1];
96 enum placement_policy policy;
97 struct lmv_obd *lmv = &dev->u.lmv;
Peng Taod7e09d02013-05-02 16:46:55 +080098
Oleg Drokinb5fa70d2015-05-21 15:32:23 -040099 memcpy(dummy, buffer, MAX_POLICY_STRING_SIZE);
Peng Taod7e09d02013-05-02 16:46:55 +0800100
Oleg Drokinb5fa70d2015-05-21 15:32:23 -0400101 if (count > MAX_POLICY_STRING_SIZE)
102 count = MAX_POLICY_STRING_SIZE;
Peng Taod7e09d02013-05-02 16:46:55 +0800103
Oleg Drokinb5fa70d2015-05-21 15:32:23 -0400104 if (dummy[count - 1] == '\n')
105 count--;
106 dummy[count] = '\0';
Peng Taod7e09d02013-05-02 16:46:55 +0800107
Oleg Drokinb5fa70d2015-05-21 15:32:23 -0400108 policy = placement_name2policy(dummy, count);
Peng Taod7e09d02013-05-02 16:46:55 +0800109 if (policy != PLACEMENT_INVAL_POLICY) {
110 spin_lock(&lmv->lmv_lock);
111 lmv->lmv_placement = policy;
112 spin_unlock(&lmv->lmv_lock);
113 } else {
Peng Taod7e09d02013-05-02 16:46:55 +0800114 return -EINVAL;
115 }
116 return count;
117}
Oleg Drokinb5fa70d2015-05-21 15:32:23 -0400118LUSTRE_RW_ATTR(placement);
Peng Taod7e09d02013-05-02 16:46:55 +0800119
Oleg Drokinb5fa70d2015-05-21 15:32:23 -0400120static ssize_t activeobd_show(struct kobject *kobj, struct attribute *attr,
121 char *buf)
Peng Taod7e09d02013-05-02 16:46:55 +0800122{
Oleg Drokinb5fa70d2015-05-21 15:32:23 -0400123 struct obd_device *dev = container_of(kobj, struct obd_device,
124 obd_kobj);
125 struct lmv_desc *desc;
Peng Taod7e09d02013-05-02 16:46:55 +0800126
Peng Taod7e09d02013-05-02 16:46:55 +0800127 desc = &dev->u.lmv.desc;
Oleg Drokinb5fa70d2015-05-21 15:32:23 -0400128 return sprintf(buf, "%u\n", desc->ld_active_tgt_count);
Peng Taod7e09d02013-05-02 16:46:55 +0800129}
Oleg Drokinb5fa70d2015-05-21 15:32:23 -0400130LUSTRE_RO_ATTR(activeobd);
Peng Taod7e09d02013-05-02 16:46:55 +0800131
Peng Tao73bb1da2013-05-29 21:40:55 +0800132static int lmv_desc_uuid_seq_show(struct seq_file *m, void *v)
Peng Taod7e09d02013-05-02 16:46:55 +0800133{
Peng Tao73bb1da2013-05-29 21:40:55 +0800134 struct obd_device *dev = (struct obd_device *)m->private;
Peng Taod7e09d02013-05-02 16:46:55 +0800135 struct lmv_obd *lmv;
136
Oleg Drokin2cbdaa42016-02-16 00:46:48 -0500137 LASSERT(dev);
Peng Taod7e09d02013-05-02 16:46:55 +0800138 lmv = &dev->u.lmv;
Joe Perches8faeebd2015-02-21 18:53:28 -0800139 seq_printf(m, "%s\n", lmv->desc.ld_uuid.uuid);
140 return 0;
Peng Taod7e09d02013-05-02 16:46:55 +0800141}
Mike Rapoportc9f6bb92015-10-13 16:03:42 +0300142
Peng Tao73bb1da2013-05-29 21:40:55 +0800143LPROC_SEQ_FOPS_RO(lmv_desc_uuid);
Peng Taod7e09d02013-05-02 16:46:55 +0800144
145static void *lmv_tgt_seq_start(struct seq_file *p, loff_t *pos)
146{
147 struct obd_device *dev = p->private;
148 struct lmv_obd *lmv = &dev->u.lmv;
Mike Rapoport50ffcb72015-10-13 16:03:40 +0300149
Peng Taod7e09d02013-05-02 16:46:55 +0800150 return (*pos >= lmv->desc.ld_tgt_count) ? NULL : lmv->tgts[*pos];
151}
152
153static void lmv_tgt_seq_stop(struct seq_file *p, void *v)
154{
155 return;
156}
157
158static void *lmv_tgt_seq_next(struct seq_file *p, void *v, loff_t *pos)
159{
160 struct obd_device *dev = p->private;
161 struct lmv_obd *lmv = &dev->u.lmv;
162 ++*pos;
163 return (*pos >= lmv->desc.ld_tgt_count) ? NULL : lmv->tgts[*pos];
164}
165
166static int lmv_tgt_seq_show(struct seq_file *p, void *v)
167{
168 struct lmv_tgt_desc *tgt = v;
169
Oleg Drokin2cbdaa42016-02-16 00:46:48 -0500170 if (!tgt)
Peng Taod7e09d02013-05-02 16:46:55 +0800171 return 0;
Dmitry Eremind0d3d222016-09-18 16:37:41 -0400172 seq_printf(p, "%u: %s %sACTIVE\n",
Joe Perches8faeebd2015-02-21 18:53:28 -0800173 tgt->ltd_idx, tgt->ltd_uuid.uuid,
174 tgt->ltd_active ? "" : "IN");
175 return 0;
Peng Taod7e09d02013-05-02 16:46:55 +0800176}
177
Xavier Roche02b31072015-06-05 10:19:20 +0200178static const struct seq_operations lmv_tgt_sops = {
Peng Taod7e09d02013-05-02 16:46:55 +0800179 .start = lmv_tgt_seq_start,
180 .stop = lmv_tgt_seq_stop,
181 .next = lmv_tgt_seq_next,
182 .show = lmv_tgt_seq_show,
183};
184
185static int lmv_target_seq_open(struct inode *inode, struct file *file)
186{
Peng Taod7e09d02013-05-02 16:46:55 +0800187 struct seq_file *seq;
188 int rc;
189
190 rc = seq_open(file, &lmv_tgt_sops);
191 if (rc)
192 return rc;
193
194 seq = file->private_data;
Dmitry Eremin61e87ab2015-05-21 15:32:27 -0400195 seq->private = inode->i_private;
Peng Taod7e09d02013-05-02 16:46:55 +0800196
197 return 0;
198}
199
Luca Ceresoli5dc8d7b2015-01-18 15:06:48 +0100200static struct lprocfs_vars lprocfs_lmv_obd_vars[] = {
John de la Garzaf5e82692014-03-24 13:58:02 -0700201 { "desc_uuid", &lmv_desc_uuid_fops, NULL, 0 },
202 { NULL }
Peng Taod7e09d02013-05-02 16:46:55 +0800203};
204
Julia Lawalld6e7a2fe2016-08-28 23:16:07 +0200205const struct file_operations lmv_proc_target_fops = {
Peng Taod7e09d02013-05-02 16:46:55 +0800206 .owner = THIS_MODULE,
207 .open = lmv_target_seq_open,
208 .read = seq_read,
209 .llseek = seq_lseek,
210 .release = seq_release,
211};
212
Oleg Drokinb5fa70d2015-05-21 15:32:23 -0400213static struct attribute *lmv_attrs[] = {
214 &lustre_attr_activeobd.attr,
215 &lustre_attr_numobd.attr,
216 &lustre_attr_placement.attr,
217 NULL,
218};
219
220static struct attribute_group lmv_attr_group = {
221 .attrs = lmv_attrs,
222};
223
Peng Taod7e09d02013-05-02 16:46:55 +0800224void lprocfs_lmv_init_vars(struct lprocfs_static_vars *lvars)
225{
Oleg Drokinb5fa70d2015-05-21 15:32:23 -0400226 lvars->sysfs_vars = &lmv_attr_group;
Peng Taod7e09d02013-05-02 16:46:55 +0800227 lvars->obd_vars = lprocfs_lmv_obd_vars;
228}