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 lvfs_obd_ctxt *lvfs_ctxt = NULL;
148 struct lustre_cfg* lcfg = buf;
149 char *mountoptions = NULL;
150 unsigned long page = 0;
156 if (LUSTRE_CFG_BUFLEN(lcfg, 1) < 1 ||
157 lustre_cfg_buf(lcfg, 1) == NULL) {
158 CERROR("CONFOBD setup requires device name\n");
161 if (LUSTRE_CFG_BUFLEN(lcfg, 2) < 1 ||
162 lustre_cfg_buf(lcfg, 2) == NULL) {
163 CERROR("CONFOBD setup requires fstype\n");
167 OBD_ALLOC(name, LUSTRE_CFG_BUFLEN(lcfg, 1));
169 CERROR("No memory\n");
170 GOTO(out, rc = -ENOMEM);
172 memcpy(name, lustre_cfg_string(lcfg, 1), LUSTRE_CFG_BUFLEN(lcfg, 1));
174 OBD_ALLOC(fstype, LUSTRE_CFG_BUFLEN(lcfg, 2));
176 CERROR("No memory\n");
177 GOTO(out, rc = -ENOMEM);
179 memcpy(fstype, lustre_cfg_string(lcfg, 2),
180 LUSTRE_CFG_BUFLEN(lcfg, 2));
182 obd->obd_fsops = fsfilt_get_ops(fstype);
183 if (IS_ERR(obd->obd_fsops)) {
184 CERROR("No fstype %s rc=%ld\n", fstype, PTR_ERR(obd->obd_fsops));
185 GOTO(err_ops, rc = PTR_ERR(obd->obd_fsops));
188 if (LUSTRE_CFG_BUFLEN(lcfg, 3) >= 1 && lustre_cfg_buf(lcfg, 3)) {
189 /* 2.6.9 selinux wants a full option page for do_kern_mount
191 page = get_zeroed_page(GFP_KERNEL);
193 CERROR("No memory\n");
194 GOTO(err_ops, rc = -ENOMEM);
196 mountoptions = (char *)page;
198 memcpy(mountoptions, lustre_cfg_string(lcfg, 3),
199 LUSTRE_CFG_BUFLEN(lcfg, 3));
202 rc = lvfs_mount_fs(name, fstype, mountoptions, 0, &lvfs_ctxt);
213 confobd->cfobd_lvfs_ctxt = lvfs_ctxt;
215 rc = confobd_fs_setup(obd, lvfs_ctxt);
219 rc = obd_llog_setup(obd, &obd->obd_llogs, LLOG_CONFIG_ORIG_CTXT,
220 obd, 0, NULL, &llog_lvfs_ops);
227 lvfs_umount_fs(lvfs_ctxt);
229 OBD_FREE(name, LUSTRE_CFG_BUFLEN(lcfg, 1));
231 OBD_FREE(fstype, LUSTRE_CFG_BUFLEN(lcfg, 2));
235 fsfilt_put_ops(obd->obd_fsops);
239 static int confobd_cleanup(struct obd_device *obd, int flags)
241 struct conf_obd *confobd = &obd->u.conf;
244 /* stop recording any log in case lconf didn't do that for us */
245 if (confobd->cfobd_cfg_llh) {
246 struct lvfs_run_ctxt saved;
247 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
248 llog_close(confobd->cfobd_cfg_llh);
249 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
252 obd_llog_cleanup(llog_get_context(&obd->obd_llogs,
253 LLOG_CONFIG_ORIG_CTXT));
254 confobd_fs_cleanup(obd, flags);
255 if (confobd->cfobd_lvfs_ctxt)
256 lvfs_umount_fs(confobd->cfobd_lvfs_ctxt);
258 if (!list_empty(&obd->obd_exports))
260 fsfilt_put_ops(obd->obd_fsops);
264 static int confobd_iocontrol(unsigned int cmd, struct obd_export *exp,
265 int len, void *karg, void *uarg)
267 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
268 struct obd_device *obd = exp->exp_obd;
269 struct conf_obd *confobd = &obd->u.conf;
270 struct obd_ioctl_data *data = karg;
271 struct lvfs_run_ctxt saved;
275 CDEBUG(D_INFO, "ioctl cmd %x\n", cmd);
277 case OBD_IOC_CLEAR_LOG: {
278 char *name = data->ioc_inlbuf1;
279 if (confobd->cfobd_cfg_llh)
282 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
283 rc = llog_open(llog_get_context(&obd->obd_llogs,
284 LLOG_CONFIG_ORIG_CTXT),
285 &confobd->cfobd_cfg_llh, NULL, name,
288 llog_init_handle(confobd->cfobd_cfg_llh,
289 LLOG_F_IS_PLAIN, NULL);
291 rc = llog_destroy(confobd->cfobd_cfg_llh);
292 llog_free_handle(confobd->cfobd_cfg_llh);
294 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
296 confobd->cfobd_cfg_llh = NULL;
299 case OBD_IOC_RECORD: {
300 char *name = data->ioc_inlbuf1;
301 if (confobd->cfobd_cfg_llh)
304 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
305 rc = llog_open(llog_get_context(&obd->obd_llogs,
306 LLOG_CONFIG_ORIG_CTXT),
307 &confobd->cfobd_cfg_llh, NULL, name,
310 llog_init_handle(confobd->cfobd_cfg_llh,
311 LLOG_F_IS_PLAIN, &cfg_uuid);
313 confobd->cfobd_cfg_llh = NULL;
314 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
318 case OBD_IOC_ENDRECORD: {
319 if (!confobd->cfobd_cfg_llh)
322 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
323 rc = llog_close(confobd->cfobd_cfg_llh);
324 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
326 confobd->cfobd_cfg_llh = NULL;
329 case OBD_IOC_DORECORD: {
331 struct llog_rec_hdr rec;
332 if (!confobd->cfobd_cfg_llh)
335 rec.lrh_len = llog_data_len(data->ioc_plen1);
337 switch(data->ioc_type) {
338 case LUSTRE_CFG_TYPE:
339 rec.lrh_type = OBD_CFG_REC;
341 case PORTALS_CFG_TYPE:
342 rec.lrh_type = PTL_CFG_REC;
345 CERROR("unknown cfg record type:%d \n", data->ioc_type);
349 OBD_ALLOC(cfg_buf, data->ioc_plen1);
350 if (cfg_buf == NULL) {
351 CERROR("No Memory\n");
354 if (copy_from_user(cfg_buf, data->ioc_pbuf1, data->ioc_plen1)) {
355 OBD_FREE(cfg_buf, data->ioc_plen1);
359 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
360 rc = llog_write_rec(confobd->cfobd_cfg_llh, &rec, NULL, 0,
362 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
364 OBD_FREE(cfg_buf, data->ioc_plen1);
367 case OBD_IOC_DUMP_LOG: {
368 struct llog_ctxt *ctxt =
369 llog_get_context(&obd->obd_llogs, LLOG_CONFIG_ORIG_CTXT);
370 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
371 rc = class_config_dump_llog(ctxt, data->ioc_inlbuf1, NULL);
372 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
379 case OBD_IOC_START: {
380 struct llog_ctxt *ctxt;
382 char *name = data->ioc_inlbuf1;
383 int len = strlen(name) + sizeof("-conf");
385 OBD_ALLOC(conf_prof, len);
387 CERROR("no memory\n");
390 sprintf(conf_prof, "%s-conf", name);
392 ctxt = llog_get_context(&obd->obd_llogs, LLOG_CONFIG_ORIG_CTXT);
393 rc = class_config_process_llog(ctxt, conf_prof, NULL);
395 CERROR("Unable to process log: %s\n", conf_prof);
396 OBD_FREE(conf_prof, len);
402 CDEBUG(D_INFO, "unknown command %x\n", cmd);
408 static struct obd_ops conf_obd_ops = {
409 .o_owner = THIS_MODULE,
410 .o_setup = confobd_setup,
411 .o_cleanup = confobd_cleanup,
412 .o_attach = confobd_attach,
413 .o_detach = confobd_detach,
414 .o_iocontrol = confobd_iocontrol,
417 static int __init confobd_init(void)
419 struct lprocfs_static_vars lvars;
422 lprocfs_init_vars(confobd, &lvars);
423 RETURN(class_register_type(&conf_obd_ops, NULL, lvars.module_vars,
424 LUSTRE_CONFOBD_NAME));
427 static void __exit confobd_exit(void)
429 class_unregister_type(LUSTRE_CONFOBD_NAME);
432 MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
433 MODULE_DESCRIPTION("Lustre Config OBD driver");
434 MODULE_LICENSE("GPL");
436 module_init(confobd_init);
437 module_exit(confobd_exit);