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 (lcfg->lcfg_inllen1 < 1 || !lcfg->lcfg_inlbuf1) {
156 CERROR("CONFOBD setup requires device name\n");
159 if (lcfg->lcfg_inllen2 < 1 || !lcfg->lcfg_inlbuf2) {
160 CERROR("CONFOBD setup requires fstype\n");
164 OBD_ALLOC(name, lcfg->lcfg_inllen1 + 1);
166 CERROR("No Memory\n");
167 GOTO(out, rc = -ENOMEM);
169 memcpy(name, lcfg->lcfg_inlbuf1, lcfg->lcfg_inllen1);
171 OBD_ALLOC(fstype, lcfg->lcfg_inllen2 + 1);
173 CERROR("No Memory\n");
174 GOTO(out, rc = -ENOMEM);
176 memcpy(fstype, lcfg->lcfg_inlbuf2, lcfg->lcfg_inllen2);
178 obd->obd_fsops = fsfilt_get_ops(fstype);
179 if (IS_ERR(obd->obd_fsops)) {
180 CERROR("No fstype %s rc=%ld\n", fstype, PTR_ERR(obd->obd_fsops));
181 GOTO(err_ops, rc = PTR_ERR(obd->obd_fsops));
184 if (lcfg->lcfg_inllen3 >= 1 && lcfg->lcfg_inlbuf3) {
185 OBD_ALLOC(mountoption, lcfg->lcfg_inllen3 + 1);
187 CERROR("No Memory\n");
188 GOTO(err_ops, rc = -ENOMEM);
190 memcpy(mountoption, lcfg->lcfg_inlbuf3, lcfg->lcfg_inllen3);
192 rc = lvfs_mount_fs(name, fstype, mountoption, 0, &lvfs_ctxt);
197 confobd->cfobd_lvfs_ctxt = lvfs_ctxt;
199 rc = confobd_fs_setup(obd, lvfs_ctxt);
203 rc = obd_llog_setup(obd, &obd->obd_llogs, LLOG_CONFIG_ORIG_CTXT,
204 obd, 0, NULL, &llog_lvfs_ops);
211 lvfs_umount_fs(lvfs_ctxt);
213 OBD_FREE(name, lcfg->lcfg_inllen1 + 1);
215 OBD_FREE(fstype, lcfg->lcfg_inllen2 + 1);
217 OBD_FREE(mountoption, lcfg->lcfg_inllen3 + 1);
221 fsfilt_put_ops(obd->obd_fsops);
225 static int confobd_cleanup(struct obd_device *obd, int flags)
227 struct conf_obd *confobd = &obd->u.conf;
230 /* stop recording any log in case lconf didn't do that for us */
231 if (confobd->cfobd_cfg_llh) {
232 struct lvfs_run_ctxt saved;
233 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
234 llog_close(confobd->cfobd_cfg_llh);
235 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
238 obd_llog_cleanup(llog_get_context(&obd->obd_llogs,
239 LLOG_CONFIG_ORIG_CTXT));
240 confobd_fs_cleanup(obd, flags);
241 if (confobd->cfobd_lvfs_ctxt)
242 lvfs_umount_fs(confobd->cfobd_lvfs_ctxt);
244 if (!list_empty(&obd->obd_exports))
246 fsfilt_put_ops(obd->obd_fsops);
250 static int confobd_iocontrol(unsigned int cmd, struct obd_export *exp,
251 int len, void *karg, void *uarg)
253 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
254 struct obd_device *obd = exp->exp_obd;
255 struct conf_obd *confobd = &obd->u.conf;
256 struct obd_ioctl_data *data = karg;
257 struct lvfs_run_ctxt saved;
261 CDEBUG(D_INFO, "ioctl cmd %x\n", cmd);
263 case OBD_IOC_CLEAR_LOG: {
264 char *name = data->ioc_inlbuf1;
265 if (confobd->cfobd_cfg_llh)
268 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
269 rc = llog_open(llog_get_context(&obd->obd_llogs,
270 LLOG_CONFIG_ORIG_CTXT),
271 &confobd->cfobd_cfg_llh, NULL, name,
274 llog_init_handle(confobd->cfobd_cfg_llh,
275 LLOG_F_IS_PLAIN, NULL);
277 rc = llog_destroy(confobd->cfobd_cfg_llh);
278 llog_free_handle(confobd->cfobd_cfg_llh);
280 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
282 confobd->cfobd_cfg_llh = NULL;
285 case OBD_IOC_RECORD: {
286 char *name = data->ioc_inlbuf1;
287 if (confobd->cfobd_cfg_llh)
290 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
291 rc = llog_open(llog_get_context(&obd->obd_llogs,
292 LLOG_CONFIG_ORIG_CTXT),
293 &confobd->cfobd_cfg_llh, NULL, name,
296 llog_init_handle(confobd->cfobd_cfg_llh,
297 LLOG_F_IS_PLAIN, &cfg_uuid);
299 confobd->cfobd_cfg_llh = NULL;
300 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
304 case OBD_IOC_ENDRECORD: {
305 if (!confobd->cfobd_cfg_llh)
308 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
309 rc = llog_close(confobd->cfobd_cfg_llh);
310 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
312 confobd->cfobd_cfg_llh = NULL;
315 case OBD_IOC_DORECORD: {
317 struct llog_rec_hdr rec;
318 if (!confobd->cfobd_cfg_llh)
321 rec.lrh_len = llog_data_len(data->ioc_plen1);
323 switch(data->ioc_type) {
324 case LUSTRE_CFG_TYPE:
325 rec.lrh_type = OBD_CFG_REC;
327 case PORTALS_CFG_TYPE:
328 rec.lrh_type = PTL_CFG_REC;
331 CERROR("unknown cfg record type:%d \n", data->ioc_type);
335 OBD_ALLOC(cfg_buf, data->ioc_plen1);
336 if (cfg_buf == NULL) {
337 CERROR("No Memory\n");
340 if (copy_from_user(cfg_buf, data->ioc_pbuf1, data->ioc_plen1)) {
341 OBD_FREE(cfg_buf, data->ioc_plen1);
345 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
346 rc = llog_write_rec(confobd->cfobd_cfg_llh, &rec, NULL, 0,
348 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
350 OBD_FREE(cfg_buf, data->ioc_plen1);
353 case OBD_IOC_DUMP_LOG: {
354 struct llog_ctxt *ctxt =
355 llog_get_context(&obd->obd_llogs, LLOG_CONFIG_ORIG_CTXT);
356 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
357 rc = class_config_dump_llog(ctxt, data->ioc_inlbuf1, NULL);
358 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
365 case OBD_IOC_START: {
366 struct llog_ctxt *ctxt;
368 char *name = data->ioc_inlbuf1;
369 int len = strlen(name) + sizeof("-conf");
371 OBD_ALLOC(conf_prof, len);
373 CERROR("no memory\n");
376 sprintf(conf_prof, "%s-conf", name);
378 ctxt = llog_get_context(&obd->obd_llogs, LLOG_CONFIG_ORIG_CTXT);
379 rc = class_config_process_llog(ctxt, conf_prof, NULL);
381 CERROR("Unable to process log: %s\n", conf_prof);
382 OBD_FREE(conf_prof, len);
388 CDEBUG(D_INFO, "unknown command %x\n", cmd);
394 static struct obd_ops conf_obd_ops = {
395 .o_owner = THIS_MODULE,
396 .o_setup = confobd_setup,
397 .o_cleanup = confobd_cleanup,
398 .o_attach = confobd_attach,
399 .o_detach = confobd_detach,
400 .o_iocontrol = confobd_iocontrol,
403 static int __init confobd_init(void)
405 struct lprocfs_static_vars lvars;
408 lprocfs_init_vars(confobd, &lvars);
409 RETURN(class_register_type(&conf_obd_ops, NULL, lvars.module_vars,
410 LUSTRE_CONFOBD_NAME));
413 static void __exit confobd_exit(void)
415 class_unregister_type(LUSTRE_CONFOBD_NAME);
418 MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
419 MODULE_DESCRIPTION("Lustre Config OBD driver");
420 MODULE_LICENSE("GPL");
422 module_init(confobd_init);
423 module_exit(confobd_exit);