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 static struct lprocfs_vars lprocfs_module_vars[] = { {0} };
38 static struct lprocfs_vars lprocfs_obd_vars[] = { {0} };
40 LPROCFS_INIT_VARS(confobd, lprocfs_module_vars, lprocfs_obd_vars)
42 static int confobd_fs_setup(struct obd_device *obd,
43 struct lvfs_obd_ctxt *lvfs_ctxt)
45 struct conf_obd *confobd = &obd->u.conf;
46 struct lvfs_run_ctxt saved;
47 struct dentry *dentry;
51 OBD_SET_CTXT_MAGIC(&obd->obd_lvfs_ctxt);
52 obd->obd_lvfs_ctxt.pwdmnt = lvfs_ctxt->loc_mnt;
53 obd->obd_lvfs_ctxt.pwd = lvfs_ctxt->loc_mnt->mnt_root;
54 obd->obd_lvfs_ctxt.fs = get_ds();
55 /*Now we did not set cb_ops of CONFOBD FIXME later*/
58 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
60 dentry = simple_mkdir(current->fs->pwd, "LOGS", 0777, 1);
63 CERROR("cannot create LOGS directory: rc = %d\n", rc);
66 confobd->cfobd_logs_dir = dentry;
68 dentry = simple_mkdir(current->fs->pwd, "OBJECTS", 0777, 1);
71 CERROR("cannot create OBJECTS directory: rc = %d\n", rc);
74 confobd->cfobd_objects_dir = dentry;
76 dentry = simple_mkdir(current->fs->pwd, "PENDING", 0777, 1);
79 CERROR("cannot create PENDING directory: rc = %d\n", rc);
82 confobd->cfobd_pending_dir = dentry;
86 l_dput(confobd->cfobd_logs_dir);
88 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
92 static int confobd_fs_cleanup(struct obd_device *obd, int flags)
94 struct conf_obd *confobd = &obd->u.conf;
95 struct lvfs_run_ctxt saved;
99 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
100 if (confobd->cfobd_logs_dir != NULL) {
101 l_dput(confobd->cfobd_logs_dir);
102 confobd->cfobd_logs_dir = NULL;
104 if (confobd->cfobd_objects_dir != NULL) {
105 l_dput(confobd->cfobd_objects_dir);
106 confobd->cfobd_objects_dir = NULL;
108 if (confobd->cfobd_pending_dir != NULL) {
109 l_dput(confobd->cfobd_pending_dir);
110 confobd->cfobd_pending_dir = NULL;
113 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
117 int confobd_attach(struct obd_device *dev, obd_count len, void *data)
119 struct lprocfs_static_vars lvars;
123 lprocfs_init_vars(confobd, &lvars);
124 rc = lprocfs_obd_attach(dev, lvars.obd_vars);
128 rc = lprocfs_alloc_md_stats(dev, 0);
132 int confobd_detach(struct obd_device *dev)
137 lprocfs_free_md_stats(dev);
138 rc = lprocfs_obd_detach(dev);
142 static int confobd_setup(struct obd_device *obd, obd_count len, void *buf)
144 struct conf_obd *confobd = &obd->u.conf;
145 struct lvfs_obd_ctxt *lvfs_ctxt = NULL;
146 struct lustre_cfg* lcfg = buf;
147 char *mountoptions = NULL;
148 unsigned long page = 0;
154 if (LUSTRE_CFG_BUFLEN(lcfg, 1) < 1 ||
155 lustre_cfg_buf(lcfg, 1) == NULL) {
156 CERROR("CONFOBD setup requires device name\n");
159 if (LUSTRE_CFG_BUFLEN(lcfg, 2) < 1 ||
160 lustre_cfg_buf(lcfg, 2) == NULL) {
161 CERROR("CONFOBD setup requires fstype\n");
165 OBD_ALLOC(name, LUSTRE_CFG_BUFLEN(lcfg, 1));
167 CERROR("No memory\n");
168 GOTO(out, rc = -ENOMEM);
170 memcpy(name, lustre_cfg_string(lcfg, 1), LUSTRE_CFG_BUFLEN(lcfg, 1));
172 OBD_ALLOC(fstype, LUSTRE_CFG_BUFLEN(lcfg, 2));
174 CERROR("No memory\n");
175 GOTO(out, rc = -ENOMEM);
177 memcpy(fstype, lustre_cfg_string(lcfg, 2),
178 LUSTRE_CFG_BUFLEN(lcfg, 2));
180 obd->obd_fsops = fsfilt_get_ops(fstype);
181 if (IS_ERR(obd->obd_fsops)) {
182 CERROR("No fstype %s rc=%ld\n", fstype, PTR_ERR(obd->obd_fsops));
183 GOTO(err_ops, rc = PTR_ERR(obd->obd_fsops));
186 if (LUSTRE_CFG_BUFLEN(lcfg, 3) >= 1 && lustre_cfg_buf(lcfg, 3)) {
187 /* 2.6.9 selinux wants a full option page for do_kern_mount
189 page = get_zeroed_page(GFP_KERNEL);
191 CERROR("No memory\n");
192 GOTO(err_ops, rc = -ENOMEM);
194 mountoptions = (char *)page;
196 memcpy(mountoptions, lustre_cfg_string(lcfg, 3),
197 LUSTRE_CFG_BUFLEN(lcfg, 3));
200 rc = lvfs_mount_fs(name, fstype, mountoptions, 0, &lvfs_ctxt);
211 confobd->cfobd_lvfs_ctxt = lvfs_ctxt;
213 rc = confobd_fs_setup(obd, lvfs_ctxt);
217 rc = obd_llog_setup(obd, &obd->obd_llogs, LLOG_CONFIG_ORIG_CTXT,
218 obd, 0, NULL, &llog_lvfs_ops);
225 lvfs_umount_fs(lvfs_ctxt);
227 OBD_FREE(name, LUSTRE_CFG_BUFLEN(lcfg, 1));
229 OBD_FREE(fstype, LUSTRE_CFG_BUFLEN(lcfg, 2));
233 fsfilt_put_ops(obd->obd_fsops);
237 static int confobd_cleanup(struct obd_device *obd, int flags)
239 struct conf_obd *confobd = &obd->u.conf;
242 /* stop recording any log in case lconf didn't do that for us */
243 if (confobd->cfobd_cfg_llh) {
244 struct lvfs_run_ctxt saved;
245 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
246 llog_close(confobd->cfobd_cfg_llh);
247 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
250 obd_llog_cleanup(llog_get_context(&obd->obd_llogs,
251 LLOG_CONFIG_ORIG_CTXT));
252 confobd_fs_cleanup(obd, flags);
253 if (confobd->cfobd_lvfs_ctxt)
254 lvfs_umount_fs(confobd->cfobd_lvfs_ctxt);
256 if (!list_empty(&obd->obd_exports))
258 fsfilt_put_ops(obd->obd_fsops);
262 static int confobd_iocontrol(unsigned int cmd, struct obd_export *exp,
263 int len, void *karg, void *uarg)
265 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
266 struct obd_device *obd = exp->exp_obd;
267 struct conf_obd *confobd = &obd->u.conf;
268 struct obd_ioctl_data *data = karg;
269 struct lvfs_run_ctxt saved;
273 CDEBUG(D_INFO, "ioctl cmd %x\n", cmd);
275 case OBD_IOC_CLEAR_LOG: {
276 char *name = data->ioc_inlbuf1;
277 if (confobd->cfobd_cfg_llh)
280 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
281 rc = llog_open(llog_get_context(&obd->obd_llogs,
282 LLOG_CONFIG_ORIG_CTXT),
283 &confobd->cfobd_cfg_llh, NULL, name,
286 llog_init_handle(confobd->cfobd_cfg_llh,
287 LLOG_F_IS_PLAIN, NULL);
289 rc = llog_destroy(confobd->cfobd_cfg_llh);
290 llog_free_handle(confobd->cfobd_cfg_llh);
292 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
294 confobd->cfobd_cfg_llh = NULL;
297 case OBD_IOC_RECORD: {
298 char *name = data->ioc_inlbuf1;
299 if (confobd->cfobd_cfg_llh)
302 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
303 rc = llog_open(llog_get_context(&obd->obd_llogs,
304 LLOG_CONFIG_ORIG_CTXT),
305 &confobd->cfobd_cfg_llh, NULL, name,
308 llog_init_handle(confobd->cfobd_cfg_llh,
309 LLOG_F_IS_PLAIN, &cfg_uuid);
311 confobd->cfobd_cfg_llh = NULL;
312 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
316 case OBD_IOC_ENDRECORD: {
317 if (!confobd->cfobd_cfg_llh)
320 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
321 rc = llog_close(confobd->cfobd_cfg_llh);
322 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
324 confobd->cfobd_cfg_llh = NULL;
327 case OBD_IOC_DORECORD: {
329 struct llog_rec_hdr rec;
330 if (!confobd->cfobd_cfg_llh)
333 rec.lrh_len = llog_data_len(data->ioc_plen1);
335 switch(data->ioc_type) {
336 case LUSTRE_CFG_TYPE:
337 rec.lrh_type = OBD_CFG_REC;
339 case PORTALS_CFG_TYPE:
340 rec.lrh_type = PTL_CFG_REC;
343 CERROR("unknown cfg record type:%d \n", data->ioc_type);
347 OBD_ALLOC(cfg_buf, data->ioc_plen1);
348 if (cfg_buf == NULL) {
349 CERROR("No Memory\n");
352 if (copy_from_user(cfg_buf, data->ioc_pbuf1, data->ioc_plen1)) {
353 OBD_FREE(cfg_buf, data->ioc_plen1);
357 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
358 rc = llog_write_rec(confobd->cfobd_cfg_llh, &rec, NULL, 0,
360 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
362 OBD_FREE(cfg_buf, data->ioc_plen1);
365 case OBD_IOC_DUMP_LOG: {
366 struct llog_ctxt *ctxt =
367 llog_get_context(&obd->obd_llogs, LLOG_CONFIG_ORIG_CTXT);
368 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
369 rc = class_config_dump_llog(ctxt, data->ioc_inlbuf1, NULL);
370 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
377 case OBD_IOC_START: {
378 struct llog_ctxt *ctxt;
380 char *name = data->ioc_inlbuf1;
381 int len = strlen(name) + sizeof("-conf");
383 OBD_ALLOC(conf_prof, len);
385 CERROR("no memory\n");
388 sprintf(conf_prof, "%s-conf", name);
390 ctxt = llog_get_context(&obd->obd_llogs, LLOG_CONFIG_ORIG_CTXT);
391 rc = class_config_process_llog(ctxt, conf_prof, NULL);
393 CERROR("Unable to process log: %s\n", conf_prof);
394 OBD_FREE(conf_prof, len);
400 CDEBUG(D_INFO, "unknown command %x\n", cmd);
406 static struct obd_ops conf_obd_ops = {
407 .o_owner = THIS_MODULE,
408 .o_setup = confobd_setup,
409 .o_cleanup = confobd_cleanup,
410 .o_attach = confobd_attach,
411 .o_detach = confobd_detach,
412 .o_iocontrol = confobd_iocontrol,
415 static int __init confobd_init(void)
417 struct lprocfs_static_vars lvars;
420 lprocfs_init_vars(confobd, &lvars);
421 RETURN(class_register_type(&conf_obd_ops, NULL,
423 OBD_CONF_DEVICENAME));
426 static void __exit confobd_exit(void)
428 class_unregister_type(OBD_CONF_DEVICENAME);
431 MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
432 MODULE_DESCRIPTION("Lustre Config OBD driver");
433 MODULE_LICENSE("GPL");
435 module_init(confobd_init);
436 module_exit(confobd_exit);