1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (C) 2004 Cluster File Systems, Inc.
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 EXPORT_SYMTAB
24 #define DEBUG_SUBSYSTEM S_CONFOBD
26 #include <linux/version.h>
27 #include <linux/init.h>
28 #include <linux/obd_support.h>
29 #include <linux/lustre_lib.h>
30 #include <linux/lustre_net.h>
31 #include <linux/lustre_idl.h>
32 #include <linux/lustre_log.h>
33 #include <linux/lustre_fsfilt.h>
34 #include <linux/obd_class.h>
35 #include <linux/lprocfs_status.h>
37 #define LUSTRE_CONFOBD_NAME "confobd"
39 static struct lprocfs_vars lprocfs_module_vars[] = { {0} };
40 static struct lprocfs_vars lprocfs_obd_vars[] = { {0} };
42 LPROCFS_INIT_VARS(confobd, lprocfs_module_vars, lprocfs_obd_vars)
44 static int confobd_fs_setup(struct obd_device *obd,
45 struct lvfs_obd_ctxt *lvfs_ctxt)
47 struct conf_obd *confobd = &obd->u.conf;
48 struct lvfs_run_ctxt saved;
49 struct dentry *dentry;
53 OBD_SET_CTXT_MAGIC(&obd->obd_lvfs_ctxt);
54 obd->obd_lvfs_ctxt.pwdmnt = lvfs_ctxt->loc_mnt;
55 obd->obd_lvfs_ctxt.pwd = lvfs_ctxt->loc_mnt->mnt_root;
56 obd->obd_lvfs_ctxt.fs = get_ds();
57 /*Now we did not set cb_ops of CONFOBD FIXME later*/
60 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
62 dentry = simple_mkdir(current->fs->pwd, "LOGS", 0777, 1);
65 CERROR("cannot create LOGS directory: rc = %d\n", rc);
68 confobd->cfobd_logs_dir = dentry;
70 dentry = simple_mkdir(current->fs->pwd, "OBJECTS", 0777, 1);
73 CERROR("cannot create OBJECTS directory: rc = %d\n", rc);
76 confobd->cfobd_objects_dir = dentry;
78 dentry = simple_mkdir(current->fs->pwd, "PENDING", 0777, 1);
81 CERROR("cannot create PENDING directory: rc = %d\n", rc);
84 confobd->cfobd_pending_dir = dentry;
88 l_dput(confobd->cfobd_logs_dir);
90 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
94 static int confobd_fs_cleanup(struct obd_device *obd, int flags)
96 struct conf_obd *confobd = &obd->u.conf;
97 struct lvfs_run_ctxt saved;
101 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
102 if (confobd->cfobd_logs_dir != NULL) {
103 l_dput(confobd->cfobd_logs_dir);
104 confobd->cfobd_logs_dir = NULL;
106 if (confobd->cfobd_objects_dir != NULL) {
107 l_dput(confobd->cfobd_objects_dir);
108 confobd->cfobd_objects_dir = NULL;
110 if (confobd->cfobd_pending_dir != NULL) {
111 l_dput(confobd->cfobd_pending_dir);
112 confobd->cfobd_pending_dir = NULL;
115 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
119 int confobd_attach(struct obd_device *dev, obd_count len, void *data)
121 struct lprocfs_static_vars lvars;
125 lprocfs_init_vars(confobd, &lvars);
126 rc = lprocfs_obd_attach(dev, lvars.obd_vars);
130 rc = lprocfs_alloc_md_stats(dev, 0);
134 int confobd_detach(struct obd_device *dev)
139 lprocfs_free_md_stats(dev);
140 rc = lprocfs_obd_detach(dev);
144 static int confobd_setup(struct obd_device *obd, obd_count len, void *buf)
146 struct conf_obd *confobd = &obd->u.conf;
147 struct lustre_cfg* lcfg = buf;
148 struct lvfs_obd_ctxt *lvfs_ctxt = NULL;
151 char *mountoption = NULL;
155 if (LUSTRE_CFG_BUFLEN(lcfg, 1) < 1 ||
156 lustre_cfg_buf(lcfg, 1) == NULL) {
157 CERROR("CONFOBD setup requires device name\n");
160 if (LUSTRE_CFG_BUFLEN(lcfg, 2) < 1 ||
161 lustre_cfg_buf(lcfg, 2) == NULL) {
162 CERROR("CONFOBD setup requires fstype\n");
166 OBD_ALLOC(name, LUSTRE_CFG_BUFLEN(lcfg, 1));
168 CERROR("No Memory\n");
169 GOTO(out, rc = -ENOMEM);
171 memcpy(name, lustre_cfg_string(lcfg, 1), LUSTRE_CFG_BUFLEN(lcfg, 1));
173 OBD_ALLOC(fstype, LUSTRE_CFG_BUFLEN(lcfg, 2));
175 CERROR("No Memory\n");
176 GOTO(out, rc = -ENOMEM);
178 memcpy(fstype, lustre_cfg_string(lcfg, 2),
179 LUSTRE_CFG_BUFLEN(lcfg, 2));
181 obd->obd_fsops = fsfilt_get_ops(fstype);
182 if (IS_ERR(obd->obd_fsops)) {
183 CERROR("No fstype %s rc=%ld\n", fstype, PTR_ERR(obd->obd_fsops));
184 GOTO(err_ops, rc = PTR_ERR(obd->obd_fsops));
187 if (LUSTRE_CFG_BUFLEN(lcfg, 3) >= 1 && lustre_cfg_buf(lcfg, 3)) {
188 OBD_ALLOC(mountoption, LUSTRE_CFG_BUFLEN(lcfg, 3));
190 CERROR("No Memory\n");
191 GOTO(err_ops, rc = -ENOMEM);
193 memcpy(mountoption, lustre_cfg_string(lcfg, 3),
194 LUSTRE_CFG_BUFLEN(lcfg, 3));
196 rc = lvfs_mount_fs(name, fstype, mountoption, 0, &lvfs_ctxt);
201 confobd->cfobd_lvfs_ctxt = lvfs_ctxt;
203 rc = confobd_fs_setup(obd, lvfs_ctxt);
207 rc = obd_llog_setup(obd, &obd->obd_llogs, LLOG_CONFIG_ORIG_CTXT,
208 obd, 0, NULL, &llog_lvfs_ops);
215 lvfs_umount_fs(lvfs_ctxt);
217 OBD_FREE(name, LUSTRE_CFG_BUFLEN(lcfg, 1));
219 OBD_FREE(fstype, LUSTRE_CFG_BUFLEN(lcfg, 2));
221 OBD_FREE(mountoption, LUSTRE_CFG_BUFLEN(lcfg, 3));
225 fsfilt_put_ops(obd->obd_fsops);
229 static int confobd_cleanup(struct obd_device *obd, int flags)
231 struct conf_obd *confobd = &obd->u.conf;
234 /* stop recording any log in case lconf didn't do that for us */
235 if (confobd->cfobd_cfg_llh) {
236 struct lvfs_run_ctxt saved;
237 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
238 llog_close(confobd->cfobd_cfg_llh);
239 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
242 obd_llog_cleanup(llog_get_context(&obd->obd_llogs,
243 LLOG_CONFIG_ORIG_CTXT));
244 confobd_fs_cleanup(obd, flags);
245 if (confobd->cfobd_lvfs_ctxt)
246 lvfs_umount_fs(confobd->cfobd_lvfs_ctxt);
248 if (!list_empty(&obd->obd_exports))
250 fsfilt_put_ops(obd->obd_fsops);
254 static int confobd_iocontrol(unsigned int cmd, struct obd_export *exp,
255 int len, void *karg, void *uarg)
257 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
258 struct obd_device *obd = exp->exp_obd;
259 struct conf_obd *confobd = &obd->u.conf;
260 struct obd_ioctl_data *data = karg;
261 struct lvfs_run_ctxt saved;
265 CDEBUG(D_INFO, "ioctl cmd %x\n", cmd);
267 case OBD_IOC_CLEAR_LOG: {
268 char *name = data->ioc_inlbuf1;
269 if (confobd->cfobd_cfg_llh)
272 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
273 rc = llog_open(llog_get_context(&obd->obd_llogs,
274 LLOG_CONFIG_ORIG_CTXT),
275 &confobd->cfobd_cfg_llh, NULL, name,
278 llog_init_handle(confobd->cfobd_cfg_llh,
279 LLOG_F_IS_PLAIN, NULL);
281 rc = llog_destroy(confobd->cfobd_cfg_llh);
282 llog_free_handle(confobd->cfobd_cfg_llh);
284 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
286 confobd->cfobd_cfg_llh = NULL;
289 case OBD_IOC_RECORD: {
290 char *name = data->ioc_inlbuf1;
291 if (confobd->cfobd_cfg_llh)
294 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
295 rc = llog_open(llog_get_context(&obd->obd_llogs,
296 LLOG_CONFIG_ORIG_CTXT),
297 &confobd->cfobd_cfg_llh, NULL, name,
300 llog_init_handle(confobd->cfobd_cfg_llh,
301 LLOG_F_IS_PLAIN, &cfg_uuid);
303 confobd->cfobd_cfg_llh = NULL;
304 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
308 case OBD_IOC_ENDRECORD: {
309 if (!confobd->cfobd_cfg_llh)
312 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
313 rc = llog_close(confobd->cfobd_cfg_llh);
314 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
316 confobd->cfobd_cfg_llh = NULL;
319 case OBD_IOC_DORECORD: {
321 struct llog_rec_hdr rec;
322 if (!confobd->cfobd_cfg_llh)
325 rec.lrh_len = llog_data_len(data->ioc_plen1);
327 switch(data->ioc_type) {
328 case LUSTRE_CFG_TYPE:
329 rec.lrh_type = OBD_CFG_REC;
331 case PORTALS_CFG_TYPE:
332 rec.lrh_type = PTL_CFG_REC;
335 CERROR("unknown cfg record type:%d \n", data->ioc_type);
339 OBD_ALLOC(cfg_buf, data->ioc_plen1);
340 if (cfg_buf == NULL) {
341 CERROR("No Memory\n");
344 if (copy_from_user(cfg_buf, data->ioc_pbuf1, data->ioc_plen1)) {
345 OBD_FREE(cfg_buf, data->ioc_plen1);
349 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
350 rc = llog_write_rec(confobd->cfobd_cfg_llh, &rec, NULL, 0,
352 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
354 OBD_FREE(cfg_buf, data->ioc_plen1);
357 case OBD_IOC_DUMP_LOG: {
358 struct llog_ctxt *ctxt =
359 llog_get_context(&obd->obd_llogs, LLOG_CONFIG_ORIG_CTXT);
360 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
361 rc = class_config_dump_llog(ctxt, data->ioc_inlbuf1, NULL);
362 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
369 case OBD_IOC_START: {
370 struct llog_ctxt *ctxt;
372 char *name = data->ioc_inlbuf1;
373 int len = strlen(name) + sizeof("-conf");
375 OBD_ALLOC(conf_prof, len);
377 CERROR("no memory\n");
380 sprintf(conf_prof, "%s-conf", name);
382 ctxt = llog_get_context(&obd->obd_llogs, LLOG_CONFIG_ORIG_CTXT);
383 rc = class_config_process_llog(ctxt, conf_prof, NULL);
385 CERROR("Unable to process log: %s\n", conf_prof);
386 OBD_FREE(conf_prof, len);
392 CDEBUG(D_INFO, "unknown command %x\n", cmd);
398 static struct obd_ops conf_obd_ops = {
399 .o_owner = THIS_MODULE,
400 .o_setup = confobd_setup,
401 .o_cleanup = confobd_cleanup,
402 .o_attach = confobd_attach,
403 .o_detach = confobd_detach,
404 .o_iocontrol = confobd_iocontrol,
407 static int __init confobd_init(void)
409 struct lprocfs_static_vars lvars;
412 lprocfs_init_vars(confobd, &lvars);
413 RETURN(class_register_type(&conf_obd_ops, NULL, lvars.module_vars,
414 LUSTRE_CONFOBD_NAME));
417 static void __exit confobd_exit(void)
419 class_unregister_type(LUSTRE_CONFOBD_NAME);
422 MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
423 MODULE_DESCRIPTION("Lustre Config OBD driver");
424 MODULE_LICENSE("GPL");
426 module_init(confobd_init);
427 module_exit(confobd_exit);