1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (c) 2002 Cluster File Systems, Inc. <info@clusterfs.com>
6 * This file is part of Lustre, http://www.lustre.org.
8 * Lustre is free software; you can redistribute it and/or
9 * modify it under the terms of version 2 of the GNU General Public
10 * License as published by the Free Software Foundation.
12 * Lustre is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Lustre; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #define DEBUG_SUBSYSTEM S_CMOBD
24 #include <linux/version.h>
25 #include <linux/init.h>
26 #include <linux/obd_support.h>
27 #include <linux/lustre_lib.h>
28 #include <linux/lustre_net.h>
29 #include <linux/lustre_idl.h>
30 #include <linux/obd_class.h>
31 #include <linux/lustre_mds.h>
32 #include <linux/lustre_cmobd.h>
33 #include <linux/lprocfs_status.h>
34 #include <linux/obd_lov.h>
35 #include <linux/obd_lmv.h>
37 #include "cm_internal.h"
39 static int cmobd_attach(struct obd_device *obd,
40 obd_count len, void *data)
42 struct lprocfs_static_vars lvars;
44 lprocfs_init_vars(cmobd, &lvars);
45 return lprocfs_obd_attach(obd, lvars.obd_vars);
48 static int cmobd_detach(struct obd_device *obd)
50 return lprocfs_obd_detach(obd);
53 static struct obd_device *cmobd_find_master(struct obd_device *obd,
54 struct obd_uuid *uuid)
56 struct obd_device *master_obd;
58 CWARN("%s: looking for client obd %s\n",
59 obd->obd_uuid.uuid, uuid->uuid);
61 master_obd = class_find_client_obd(NULL,
67 master_obd = class_find_client_obd(NULL,
73 master_obd = class_find_client_obd(NULL, LUSTRE_MDC_NAME,
78 static inline int cmobd_lmv_obd(struct obd_device *obd)
80 if (!strcmp(obd->obd_type->typ_name, LUSTRE_MDC_NAME) ||
81 !strcmp(obd->obd_type->typ_name, OBD_LMV_DEVICENAME))
87 static inline int cmobd_lov_obd(struct obd_device *obd)
89 if (!strcmp(obd->obd_type->typ_name, OBD_LOV_DEVICENAME))
95 static void cmobd_init_ea_size(struct obd_device *obd)
97 int ost_count = 1, easize, cookiesize;
98 struct cm_obd *cmobd = &obd->u.cm;
101 /* FIXME-UMKA: here we should also take into account that there is
102 * possible to have few OSTs. */
103 easize = lov_mds_md_size(ost_count);
104 cookiesize = ost_count * sizeof(struct llog_cookie);
106 obd_init_ea_size(cmobd->master_exp, easize, cookiesize);
108 cmobd->master_obd->u.cli.cl_max_mds_easize = easize;
109 cmobd->master_obd->u.cli.cl_max_mds_cookiesize = cookiesize;
114 static int cmobd_setup(struct obd_device *obd, obd_count len, void *buf)
116 struct obd_uuid master_uuid, cache_uuid;
117 struct lustre_handle conn = { 0 };
118 struct cm_obd *cmobd = &obd->u.cm;
119 struct lustre_cfg* lcfg = buf;
120 struct lustre_id mid, lid;
124 if (lcfg->lcfg_inllen1 < 1 || !lcfg->lcfg_inlbuf1) {
125 CERROR("CMOBD setup requires master uuid\n");
128 if (lcfg->lcfg_inllen2 < 1 || !lcfg->lcfg_inlbuf2) {
129 CERROR("CMOBD setup requires cache uuid\n");
133 obd_str2uuid(&master_uuid, lcfg->lcfg_inlbuf1);
134 obd_str2uuid(&cache_uuid, lcfg->lcfg_inlbuf2);
136 /* FIXME-WANGDI: saving client obds here is not correct as they may
137 become invalid due to refcounter exhausting on cleanup. The prefer
138 way seems to be getting them each time we need them. */
139 cmobd->master_obd = cmobd_find_master(obd, &master_uuid);
140 if (cmobd->master_obd == NULL) {
141 CERROR("Can't find master obd %s\n", &master_uuid.uuid[0]);
145 cmobd->cache_obd = class_uuid2obd(&cache_uuid);
146 if (cmobd->cache_obd == NULL) {
147 CERROR("Can't find cache obd %s\n", &cache_uuid.uuid[0]);
151 rc = obd_connect(&conn, cmobd->master_obd, &obd->obd_uuid, 0);
154 cmobd->master_exp = class_conn2export(&conn);
156 memset(&conn, 0, sizeof(conn));
157 rc = class_connect(&conn, cmobd->cache_obd, &obd->obd_uuid);
159 GOTO(put_master, rc);
161 cmobd->cache_exp = class_conn2export(&conn);
163 if (cmobd_lov_obd(cmobd->master_obd)) {
164 /* for master osc remove the recovery flag. */
165 rc = obd_set_info(cmobd->master_exp, strlen("unrecovery"),
166 "unrecovery", 0, NULL);
168 GOTO(put_master, rc);
170 rc = cmobd_init_write_srv(obd);
174 cmobd_init_ea_size(obd);
175 cmobd->write_srv = NULL;
178 if (cmobd_lmv_obd(cmobd->master_obd)) {
179 /* making sure, that both obds are ready. This is especially
180 * important in the case of using LMV as master. */
181 rc = obd_getready(cmobd->master_exp);
183 CERROR("Can't make %s obd ready.\n",
188 rc = obd_getready(cmobd->cache_exp);
190 CERROR("Can't make %s obd ready.\n",
195 /* requesting master obd to have its root inode store cookie to
196 * be able to save it to local root inode EA. */
197 valsize = sizeof(struct lustre_id);
199 rc = obd_get_info(cmobd->master_exp, strlen("rootid"),
200 "rootid", &valsize, &mid);
202 CERROR("Can't get rootid from master MDS %s, "
203 "err= %d.\n", master_uuid.uuid, rc);
207 /* getting rootid from cache MDS. It is needed to update local
208 * (cache) root inode by rootid value from master obd. */
209 rc = obd_get_info(cmobd->cache_exp, strlen("rootid"),
210 "rootid", &valsize, &lid);
212 CERROR("Can't get rootid from local MDS %s, "
213 "err= %d.\n", cache_uuid.uuid, rc);
217 /* storing master MDS rootid to local root inode EA. */
218 CWARN("storing "DLID4" to local inode "DLID4".\n",
219 OLID4(&mid), OLID4(&lid));
221 rc = mds_update_mid(cmobd->cache_obd, &lid,
224 CERROR("Can't update local root inode by ID "
225 "from master MDS %s, err = %d.\n",
226 master_uuid.uuid, rc);
233 class_disconnect(cmobd->cache_exp, 0);
235 obd_disconnect(cmobd->master_exp, 0);
239 static int cmobd_cleanup(struct obd_device *obd, int flags)
241 struct cm_obd *cmobd = &obd->u.cm;
244 if (cmobd->write_srv)
245 cmobd_cleanup_write_srv(obd);
247 class_disconnect(cmobd->cache_exp, 0);
248 obd_disconnect(cmobd->master_exp, 0);
253 static int cmobd_iocontrol(unsigned int cmd, struct obd_export *exp,
254 int len, void *karg, void *uarg)
256 struct obd_device *obd = exp->exp_obd;
261 case OBD_IOC_CMOBD_SYNC: /* trigger reintegration */
262 rc = cmobd_reintegrate(obd);
265 CERROR("unrecognized ioctl %#x\n", cmd);
273 static struct obd_ops cmobd_ops = {
274 o_owner: THIS_MODULE,
275 o_attach: cmobd_attach,
276 o_detach: cmobd_detach,
277 o_setup: cmobd_setup,
278 o_cleanup: cmobd_cleanup,
279 o_iocontrol: cmobd_iocontrol,
282 kmem_cache_t *cmobd_extent_slab;
284 static int __init cmobd_init(void)
286 struct lprocfs_static_vars lvars;
290 printk(KERN_INFO "Lustre: Cache Manager OBD driver; info@clusterfs.com\n");
292 lprocfs_init_vars(cmobd, &lvars);
293 rc = class_register_type(&cmobd_ops, NULL, lvars.module_vars,
297 cmobd_extent_slab = kmem_cache_create("cmobd_extents",
298 sizeof(struct cmobd_extent_info), 0,
299 SLAB_HWCACHE_ALIGN, NULL, NULL);
300 if (cmobd_extent_slab == NULL) {
301 class_unregister_type(LUSTRE_CMOBD_NAME);
307 static void /*__exit*/ cmobd_exit(void)
309 class_unregister_type(LUSTRE_CMOBD_NAME);
310 if (kmem_cache_destroy(cmobd_extent_slab) != 0)
311 CERROR("couldn't free cmobd extent slab\n");
314 MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
315 MODULE_DESCRIPTION("Lustre Cache Manager OBD driver");
316 MODULE_LICENSE("GPL");
318 module_init(cmobd_init);
319 module_exit(cmobd_exit);