lustre_compat25.h lustre_fsfilt.h lustre_import.h lustre_mds.h obd.h \
lvfs.h lvfs_linux.h lustre_cfg.h lustre_lite.h lustre_idl.h lustre_smfs.h \
lustre_cmobd.h obd_lmv.h lustre_snap.h lustre_sec.h lustre_ucache.h \
- lustre_acl.h lustre_gs.h
+ lustre_acl.h lustre_audit.h lustre_gs.h
+
--- /dev/null
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * Copyright (C) 2001-2003 Cluster File Systems, Inc. <info@clusterfs.com>
+ *
+ * This file is part of Lustre, http://www.lustre.org.
+ *
+ * Lustre is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * Lustre is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Lustre; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * smfs data structures.
+ * See also lustre_idl.h for wire formats of requests.
+ *
+ */
+
+#ifndef __LUSTRE_AUDIT_H
+#define __LUSTRE_AUDIT_H
+
+/* Audit plugin stuff */
+#define AUDIT_MDS_NAME "audit_mds"
+#define AUDIT_OST_NAME "audit_ost"
+#define AUDIT_CLI_NAME "audit_client-"
+#define AUDIT_ATTR_EA "audit"
+#define AUDIT_ATTR_FILE "audit_setting"
+//AUDIT OPCODES, also bit number in audit_setting mask
+
+typedef enum {
+ AUDIT_NONE = 0,
+ AUDIT_CREATE,
+ AUDIT_LINK,
+ AUDIT_UNLINK,
+ AUDIT_SYMLINK,
+ AUDIT_RENAME,
+ AUDIT_SETATTR,
+ AUDIT_WRITE,
+ AUDIT_READ,
+ AUDIT_OPEN,
+ AUDIT_STAT,
+ AUDIT_MMAP,
+ AUDIT_READLINK,
+ AUDIT_READDIR,
+ AUDIT_MAX,
+} audit_op;
+
+#define AUDIT_FAIL AUDIT_MAX
+#define AUDIT_DIR (AUDIT_MAX + 1)
+#define AUDIT_FS (AUDIT_MAX + 2)
+
+#define AUD_BIT(a) (1 << a)
+
+#define AUDIT_ALL_OPS ((1 << AUDIT_MAX) - 1)
+#define AUDIT_OFF 0
+
+#define IS_AUDIT_OP(mask,op) (mask & (1<<op))
+#define IS_AUDIT(mask) (mask & AUDIT_ALL_OPS)
+#define SET_AUDIT_OP(mask,op) (mask |= (1<<op))
+
+//llog audit record 24 bytes
+struct audit_record {
+ __u64 nid;
+ __u32 uid;
+ __u32 gid;
+ __u32 time;
+ __u16 opcode;
+ __u16 result;
+} __attribute__ ((packed));
+
+//32 bytes
+struct audit_id_record {
+ __u64 au_num;
+ __u64 au_fid;
+ __u32 au_gen;
+ __u32 au_type;
+ __u64 au_mds;
+} __attribute__ ((packed));
+
+//1 + namelen
+struct audit_name_record {
+ __u8 name_len;
+ char name[0];
+} __attribute__ ((packed));
+
+struct audit_info {
+ struct audit_msg m;
+ char * name;
+ __u32 namelen;
+};
+
+struct audit_lov_msg {
+ struct lov_stripe_md * lsm;
+ __u64 mask;
+ uid_t uid;
+ gid_t gid;
+};
+
+#endif
LCFG_ADD_CONN = 0x00cf00d,
LCFG_DEL_CONN = 0x00cf00e,
LCFG_SET_SECURITY = 0x00cf00f,
+ LCFG_SET_AUDIT = 0x00cf010,
};
struct lustre_cfg_bufs {
#define LDLM_FL_CLEANED 0x800000
/* optimization hint: LDLM can run blocking callback from current context
- * w/o involving separate thread. in order to decrease cs rate */
+ * w/o involving separate thread. in order to decrease cs rate -bzzz */
#define LDLM_FL_ATOMIC_CB 0x1000000
/* while this flag is set, the lock can't change resource */
EA_MEA = (1 << 1),
EA_SID = (1 << 2),
EA_MID = (1 << 3),
- EA_KEY = (1 << 4)
+ EA_KEY = (1 << 4),
+ EA_PID = (1 << 5),
};
struct fsfilt_operations {
int (* fs_post_setup)(struct obd_device *obd, struct vfsmount *mnt,
struct dentry *dentry);
int (* fs_post_cleanup)(struct obd_device *obd, struct vfsmount *mnt);
- int (* fs_get_reint_log_ctxt)(struct super_block *sb,
- struct llog_ctxt **ctxt);
+ int (* fs_set_info)(struct super_block *, struct inode *,
+ __u32, void *, __u32, void *);
+ int (* fs_get_info)(struct super_block *, struct inode *,
+ __u32, void *, __u32 *, void *);
int (* fs_set_fs_flags)(struct inode *inode, int flags);
int (* fs_clear_fs_flags)(struct inode *inode, int flags);
int (* fs_set_ost_flags)(struct super_block *sb);
int (* fs_set_mds_flags)(struct super_block *sb);
- int (* fs_precreate_rec)(struct dentry *dentry, int *num,
+ int (* fs_precreate_rec)(struct dentry *dentry, int *num,
struct obdo *oa);
int (* fs_set_xattr)(struct inode *inode, void *handle, char *name,
void *buffer, int buffer_size);
}
static inline int
-fsfilt_get_reint_log_ctxt(struct obd_device *obd,
- struct super_block *sb,
- struct llog_ctxt **ctxt)
+fsfilt_set_info(struct obd_device *obd, struct super_block *sb,
+ struct inode * inode, __u32 keylen, void * key,
+ __u32 valsize, void * val)
+{
+ if (obd->obd_fsops->fs_set_info)
+ return obd->obd_fsops->fs_set_info(sb, inode,
+ keylen, key,
+ valsize, val);
+ return 0;
+}
+
+static inline int
+fsfilt_get_info(struct obd_device *obd, struct super_block *sb,
+ struct inode * inode, __u32 keylen, void * key,
+ __u32 * valsize, void * val)
{
- if (obd->obd_fsops->fs_get_reint_log_ctxt)
- return obd->obd_fsops->fs_get_reint_log_ctxt(sb, ctxt);
+ if (obd->obd_fsops->fs_get_info)
+ return obd->obd_fsops->fs_get_info(sb, inode, keylen, key,
+ valsize, val);
return 0;
}
#define OBD_MD_FLXATTRLIST (0x0000000200000000LL) /* user xattr list */
#define OBD_MD_FLACL (0x0000000400000000LL) /* acl */
#define OBD_MD_FLRMTACL (0x0000000800000000LL) /* remote acl */
-#define OBD_MD_FLKEY (0x0000001000000000LL) /* mds key extended attributes */
+#define OBD_MD_FLKEY (0x0000001000000000LL) /* mds key extended attributes */
+#define OBD_MD_FLAUDIT (0x0000002000000000LL) /* audit setting */
#define OBD_MD_FLNOTOBD (~(OBD_MD_FLBLOCKS | OBD_MD_LINKNAME | \
OBD_MD_FLEASIZE | OBD_MD_FLHANDLE | \
OBD_MD_FLCKSUM | OBD_MD_FLQOS | \
OBD_MD_FLOSCOPQ | OBD_MD_FLCOOKIE | \
OBD_MD_FLXATTR | OBD_MD_FLXATTRLIST | \
- OBD_MD_FLACL | OBD_MD_FLKEY | OBD_MD_MDS))
+ OBD_MD_FLACL | OBD_MD_FLKEY | \
+ OBD_MD_MDS | OBD_MD_FLAUDIT))
static inline struct lustre_handle *obdo_handle(struct obdo *oa)
{
MDS_SYNC = 44,
MDS_DONE_WRITING = 45,
MDS_ACCESS_CHECK = 46,
+ MDS_PARSE_ID = 47,
MDS_LAST_OPC
} mds_cmd_t;
__u32 repbuf;
};
+struct parseid_pkg {
+ __u32 pp_type;
+ __u32 pp_rc;
+ struct lustre_id pp_id1;
+ struct lustre_id pp_id2;
+ __u8 pp_name[NAME_MAX + 1];
+};
+
+struct audit_msg {
+ struct lustre_id id;
+ __u64 nid;
+ __u32 result;
+ __u32 uid;
+ __u32 gid;
+ __u32 code;
+};
+
+struct audit_attr_msg {
+ struct lustre_id id;
+ __u64 attr;
+};
+#if 0
+extern void lustre_swab_lustre_id(struct lustre_id *id);
+extern void lustre_swab_lustre_stc(struct lustre_stc *stc);
+extern void lustre_swab_lustre_fid(struct lustre_fid *fid);
+extern void lustre_swab_parseid_pkg(struct parseid_pkg *pkg);
+extern void lustre_swab_mds_status_req (struct mds_status_req *r);
+#endif
+extern void lustre_swab_audit_msg (struct audit_msg *r);
+extern void lustre_swab_audit_attr (struct audit_attr_msg *r);
+extern void lustre_swab_parseid_pkg(struct parseid_pkg *pkg);
+
#define MDS_BFLAG_UNCOMMITTED_WRITES 0x1
#define MDS_BFLAG_CLOSE_EPOCH 0x2
#define MDS_BFLAG_DIRTY_EPOCH 0x4
__u64 blocks; /* XID, in the case of MDS_READPAGE */
__u64 io_epoch;
__u64 valid;
+ __u64 audit;
__u32 mode;
__u32 uid;
__u32 gid;
LLOG_LOGID_MAGIC = 0x1064553b,
SMFS_UPDATE_REC = 0x10650000,
CACHE_LRU_REC = 0x10660000,
+ SMFS_AUDIT_GEN_REC = 0x10670000,
+ SMFS_AUDIT_NAME_REC = 0x10680000,
} llog_op_type;
/* Log record header - stored in little endian order.
struct semaphore lli_size_sem;
__u64 lli_maxbytes;
__u64 lli_io_epoch;
+ __u64 lli_audit_mask;
unsigned long lli_flags;
/* this lock protects s_d_w and p_w_ll */
int mdc_done_writing(struct obd_export *, struct obdo *);
+/* mds_audit_path.c */
+int mds_audit_id2name(struct obd_device *obd, char **name, int *namelen,
+ struct lustre_id *id);
+
/* ioctls for trying requests */
#define IOC_REQUEST_TYPE 'f'
#define IOC_REQUEST_MIN_NR 30
return 0;
}
-
extern int smfs_write_extents(struct inode *dir, struct dentry *dentry,
unsigned long from, unsigned long num);
extern int smfs_rec_precreate(struct dentry *dentry, int *num, struct obdo *oa);
struct lvfs_ucred {
struct lustre_sec_desc *luc_lsd;
struct group_info *luc_ginfo;
+ __u64 luc_nid;
__u32 luc_uid;
__u32 luc_gid;
__u32 luc_fsuid;
LLOG_TEST_ORIG_CTXT = 10,
LLOG_TEST_REPL_CTXT = 11,
LLOG_REINT_ORIG_CTXT = 12,
+ LLOG_AUDIT_ORIG_CTXT = 13,
LLOG_MAX_CTXTS
};
#define LL_IOC_KEY_TYPE _IOW ('f', 171, long)
#define LL_IOC_DISABLE_CRYPTO _IOW ('f', 172, long)
#define LL_IOC_ENABLE_CRYPTO _IOW ('f', 173, long)
-
+#define LL_IOC_AUDIT _IOW ('f', 174, __u64)
#define O_LOV_DELAY_CREATE 0100000000 /* hopefully this does not conflict */
--- /dev/null
+Index: linux-2.6.10/kernel/sched.c
+===================================================================
+--- linux-2.6.10.orig/include/linux/sched.h 2005-04-06 15:38:35.000000000 +0000
++++ linux-2.6.10/include/linux/sched.h 2005-07-06 15:06:06.000000000 +0000
+@@ -365,6 +376,7 @@ struct user_struct {
+ /* Hash table maintenance information */
+ struct list_head uidhash_list;
+ uid_t uid;
++ __u64 nid;
+ };
+
+ extern struct user_struct *find_user(uid_t);
hostfs_readdir_large.patch
vfs-intent_release_umount-vanilla-2.6.10-fc3.patch
vfs-umount_lustre-vanilla-2.6.10-fc3.patch
+nid-2.6-fc3.patch
pag-basic-2.6.10-fc3.patch
+
vfs-intent_release_umount-vanilla-2.6.10-fc3.patch
vfs-umount_lustre-vanilla-2.6.10-fc3.patch
export-show_task-2.6-vanilla.patch
+nid-2.6-fc3.patch
highmem-split-2.6.10-fc3.patch
pag-basic-2.6.10-fc3.patch
+
* will never call the local blocking_ast until we drop our
* reader/writer reference, which we won't do until we get the
* reply and finish enqueueing. */
-
+
list_for_each_safe(tmp, pos, rpc_list) {
struct ldlm_lock *lock =
list_entry(tmp, struct ldlm_lock, l_cp_ast);
MODULES := llite
llite-objs := dcache.o dir.o file.o llite_close.o llite_gns.o llite_lib.o llite_nfs.o
-llite-objs += rw.o lproc_llite.o namei.o special.o symlink.o llite_mmap.o llite_gs.o
+llite-objs += rw.o lproc_llite.o namei.o special.o symlink.o llite_mmap.o
+llite-objs += llite_gs.o llite_audit.o
ifeq ($(PATCHLEVEL),4)
llite-objs += rw24.o super.o
#include <linux/lustre_lite.h>
#include <linux/lustre_dlm.h>
#include <linux/lustre_sec.h>
+#include <linux/lustre_audit.h>
#include <linux/lustre_acl.h>
#include "llite_internal.h"
}
case LL_IOC_FLUSH_CRED:
RETURN(ll_flush_cred(inode));
+ case LL_IOC_AUDIT:
+ RETURN(ll_set_audit(inode, SET_AUDIT_OP(arg, AUDIT_DIR)));
default:
return obd_iocontrol(cmd, sbi->ll_dt_exp, 0,
NULL, (void *)arg);
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
#include <linux/lustre_compat25.h>
#endif
-#include "llite_internal.h"
#include <linux/obd_lov.h>
+#include <linux/lustre_audit.h>
+#include "llite_internal.h"
__u64 lov_merge_size(struct lov_stripe_md *lsm, int kms);
__u64 lov_merge_blocks(struct lov_stripe_md *lsm);
file->private_data = fd;
ll_readahead_init(file->f_dentry->d_inode, &fd->fd_ras);
fd->fd_omode = it->it_flags;
+
RETURN(0);
}
file->f_flags &= ~O_LOV_DELAY_CREATE;
GOTO(out, rc);
out:
+ /* audit stuff if there was no RPC */
+ if (LUSTRE_IT(it)->it_data == 0) {
+ ll_audit_log(inode, AUDIT_OPEN, rc);
+ }
+
req = LUSTRE_IT(it)->it_data;
ll_intent_drop_lock(it);
ll_intent_release(it);
CDEBUG(D_DLMTRACE, "Locking inode %lu, start "LPU64" end "LPU64"\n",
inode->i_ino, policy->l_extent.start, policy->l_extent.end);
- do_gettimeofday(&start);
+ do_gettimeofday(&start);
rc = obd_enqueue(sbi->ll_dt_exp, lsm, LDLM_EXTENT, policy, mode,
&ast_flags, ll_extent_lock_callback,
ldlm_completion_ast, ll_glimpse_callback, inode,
LCK_PR);
tree.lt_fd = file->private_data;
-
+
rc = ll_tree_lock(&tree, node, inode, buf, count,
file->f_flags & O_NONBLOCK ? LDLM_FL_BLOCK_NOWAIT :0);
if (rc != 0)
CDEBUG(D_INFO, "Read ino %lu, "LPSZ" bytes, offset %lld, i_size %llu\n",
inode->i_ino, count, *ppos, inode->i_size);
-
+
/* turn off the kernel's read-ahead */
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
file->f_ramax = 0;
file->f_ra.ra_pages = 0;
#endif
retval = generic_file_read(file, buf, count, ppos);
+ ll_audit_log(inode, AUDIT_READ, retval);
out:
ll_tree_unlock(&tree, inode);
RETURN(PTR_ERR(node));
tree.lt_fd = file->private_data;
-
+
rc = ll_tree_lock(&tree, node, inode, buf, count,
file->f_flags & O_NONBLOCK ? LDLM_FL_BLOCK_NOWAIT :0);
if (rc != 0)
/* generic_file_write handles O_APPEND after getting i_sem */
retval = generic_file_write(file, buf, count, ppos);
+
EXIT;
out:
+ ll_audit_log(inode, AUDIT_WRITE, retval);
+
ll_tree_unlock(&tree, inode);
/* serialize with mmap/munmap/mremap */
lprocfs_counter_add(ll_i2sbi(inode)->ll_stats, LPROC_LL_WRITE_BYTES,
*/
case LL_IOC_FLUSH_CRED:
RETURN(ll_flush_cred(inode));
+ case LL_IOC_AUDIT:
+ RETURN(ll_set_audit(inode, arg));
default:
RETURN( obd_iocontrol(cmd, ll_i2dtexp(inode), 0, NULL,
(void *)arg) );
--- /dev/null
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * Copyright (c) 2002, 2003 Cluster File Systems, Inc.
+ *
+ * osc_audit.c - audit code for client side.
+ *
+ * This file is part of Lustre, http://www.lustre.org.
+ *
+ * Lustre is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * Lustre is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Lustre; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#define DEBUG_SUBSYSTEM S_LLITE
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/random.h>
+#include <linux/version.h>
+
+#include <linux/lustre_lite.h>
+#include <linux/lustre_ha.h>
+#include <linux/lustre_dlm.h>
+#include <linux/lprocfs_status.h>
+#include <linux/lustre_acl.h>
+#include <linux/lustre_audit.h>
+#include "llite_internal.h"
+
+//audit is set via obd_set_info() on mds
+int ll_set_audit(struct inode * inode, __u64 arg)
+{
+ struct audit_attr_msg msg;
+ struct obd_export * exp = ll_i2mdexp(inode);
+ int rc;
+
+ msg.attr = arg;
+ msg.id = ll_i2info(inode)->lli_id;
+ //set audit on MDS (fs/dir/file)
+ rc = obd_set_info(exp, 5, "audit", sizeof(msg), &msg);
+
+ //if fs audit is being set for fs then pass attr to all OSS
+ if (IS_AUDIT_OP(arg, AUDIT_FS)) {
+ exp = ll_i2dtexp(inode);
+ rc = obd_set_info(exp, 5, "audit", sizeof(msg), &msg);
+ }
+ return rc;
+}
+
+int ll_check_audit(struct inode * inode, audit_op op, int ret)
+{
+ __u64 mask = 0;
+
+ LASSERT(op < AUDIT_MAX);
+ //check fs audit
+ if (IS_AUDIT(ll_s2sbi(inode->i_sb)->ll_audit_mask)) {
+ mask = ll_s2sbi(inode->i_sb)->ll_audit_mask;
+ }
+ else if (IS_AUDIT(ll_i2info(inode)->lli_audit_mask)) {
+ mask = ll_i2info(inode)->lli_audit_mask;
+ }
+ else
+ return 0;
+
+ //if audit is only for failures?
+ if (!ret && IS_AUDIT_OP(mask, AUDIT_FAIL))
+ return 0;
+
+ return (IS_AUDIT_OP(mask,op));
+}
+/*
+ * this function send audit record data to selected OST
+ * obd_set_info() RPC is using for this with key "auditlog"
+ */
+
+int ll_audit_log (struct inode * inode, audit_op code, int ret)
+{
+ struct audit_msg msg;
+ //struct lustre_id * id = &msg.id;
+ struct obd_export * exp = ll_i2dtexp(inode);
+ int rc = 0;
+
+ if (ll_check_audit(inode, code, ret)) {
+ msg.id = ll_i2info(inode)->lli_id;
+ msg.code = code;
+ msg.result = ret;
+ msg.uid = current->fsuid;
+ msg.gid = current->fsgid;
+ msg.nid = 0xFEED;
+
+ rc = obd_set_info(exp, 8, "auditlog", sizeof(msg), &msg);
+ }
+
+ RETURN(rc);
+}
+
#define LLITE_INTERNAL_H
#include <linux/lustre_debug.h>
+#include <linux/lustre_audit.h>
/* default to about 40meg of readahead on a given system. That much tied
* up in 512k readahead requests serviced at 40ms each is about 1GB/s. */
struct lov_desc ll_dt_desc;
struct proc_dir_entry *ll_proc_root;
struct lustre_id ll_rootid; /* root lustre id */
-
+
struct lustre_mount_data *ll_lmd;
char *ll_instance;
struct ll_ra_info ll_ra_info;
unsigned int ll_remote; /* remote client? */
-
+
+ __u64 ll_audit_mask;
/* times spent waiting for locks in each call site. These are
* all protected by the ll_lock */
struct obd_service_time ll_read_stime;
struct obd_client_handle *och, int dirty);
void ll_och_fill(struct inode *inode, struct lookup_intent *it,
struct obd_client_handle *och);
+int ll_set_audit(struct inode *, __u64);
+int ll_audit_log(struct inode *, audit_op, int);
int ll_getxattr_internal(struct inode *inode, const char *name,
void *value, size_t size, __u64 valid);
typedef struct rb_node rb_node_t;
#endif
-struct ll_lock_tree_node;
+struct ll_lock_tree_node {
+ rb_node_t lt_node;
+ struct list_head lt_locked_item;
+ __u64 lt_oid;
+ ldlm_policy_data_t lt_policy;
+ struct lustre_handle lt_lockh;
+ ldlm_mode_t lt_mode;
+};
+//struct ll_lock_tree_node;
struct ll_lock_tree {
rb_root_t lt_root;
struct list_head lt_locked_list;
#include <linux/lustre_dlm.h>
#include <linux/lprocfs_status.h>
#include <linux/lustre_acl.h>
+#include <linux/lustre_audit.h>
#include <linux/lustre_gs.h>
#include <linux/lustre_sec.h>
#include "llite_internal.h"
sbi->ll_gns_timer.data = (unsigned long)sbi;
sbi->ll_gns_timer.function = ll_gns_timer_callback;
init_timer(&sbi->ll_gns_timer);
-
+ //audit mask
+ sbi->ll_audit_mask = AUDIT_OFF;
ll_set_sbi(sb, sbi);
generate_random_uuid(uuid);
lli->lli_mds_exec_och = NULL;
lli->lli_open_fd_read_count = lli->lli_open_fd_write_count = 0;
lli->lli_open_fd_exec_count = 0;
+ lli->lli_audit_mask = AUDIT_OFF;
lli->lli_key_info = NULL;
}
OBD_FREE(mds_sec, strlen(mds_sec) + 1);
if (oss_sec)
OBD_FREE(oss_sec, strlen(oss_sec) + 1);
+ if (gkc)
+ OBD_FREE(gkc, strlen(gkc) + 1);
return err;
} /* ll_read_super */
if (body->valid & OBD_MD_FLSIZE)
set_bit(LLI_F_HAVE_MDS_SIZE_LOCK, &lli->lli_flags);
+ if (body->valid & OBD_MD_FLAUDIT) {
+ struct ll_sb_info * sbi = ll_s2sbi(inode->i_sb);
+ if (IS_AUDIT_OP(body->audit, AUDIT_FS))
+ sbi->ll_audit_mask = body->audit;
+ else
+ lli->lli_audit_mask = body->audit;
+ }
+
if (mkey != NULL) {
LASSERT(body->valid & OBD_MD_FLKEY);
ll_crypto_init_inode_key(inode, mkey);
#include <linux/lustre_mds.h>
#include <linux/lustre_lite.h>
+#include <linux/lustre_audit.h>
#include "llite_internal.h"
#include <linux/lustre_compat25.h>
-
+/*
struct ll_lock_tree_node {
rb_node_t lt_node;
struct list_head lt_locked_item;
struct lustre_handle lt_lockh;
ldlm_mode_t lt_mode;
};
-
+*/
__u64 lov_merge_size(struct lov_stripe_md *lsm, int kms);
int lt_get_mmap_locks(struct ll_lock_tree *tree, struct inode *inode,
unsigned long addr, size_t count);
.close = ll_close_vma,
};
+/* Audit functions */
+extern int ll_audit_log (struct inode *, audit_op, int);
+
int ll_file_mmap(struct file * file, struct vm_area_struct * vma)
{
int rc;
if (rc == 0) {
struct ll_inode_info *lli = ll_i2info(file->f_dentry->d_inode);
vma->vm_ops = &ll_file_vm_ops;
+
/* mark i/o epoch dirty */
if (vma->vm_flags & VM_SHARED)
set_bit(LLI_F_DIRTY_HANDLE, &lli->lli_flags);
}
+
+ ll_audit_log(file->f_dentry->d_inode, AUDIT_MMAP, rc);
RETURN(rc);
}
oa->o_gr = lsm->lsm_object_gr;
oa->o_valid = OBD_MD_FLID | OBD_MD_FLGROUP;
valid_flags = OBD_MD_FLTYPE | OBD_MD_FLATIME;
- if (cmd == OBD_BRW_WRITE) {
+ if (cmd == OBD_BRW_WRITE || cmd == OBD_BRW_READ) {
oa->o_valid |= OBD_MD_FLIFID | OBD_MD_FLEPOCH;
*(obdo_id(oa)) = ll_i2info(inode)->lli_id;
oa->o_easize = ll_i2info(inode)->lli_io_epoch;
#include <linux/lustre_fsfilt.h>
#include <linux/obd_lmv.h>
#include <linux/lustre_lite.h>
+#include <linux/lustre_audit.h>
#include "lmv_internal.h"
/* not defined for liblustre building */
RETURN(rc);
}
-
+ if (keylen == 5 && strcmp(key, "audit") == 0) {
+ struct audit_attr_msg * msg = val;
+ int mds = id_group(&msg->id);
+ int i, rc = 0;
+ LASSERT(mds < lmv->desc.ld_tgt_count);
+
+ if (IS_AUDIT_OP(msg->attr, AUDIT_FS)) {
+ //FS audit, send message to all mds
+ for (i = 0; i < lmv->desc.ld_tgt_count;i++) {
+ obd_set_info(lmv->tgts[i].ltd_exp,
+ keylen, key, vallen, val);
+ }
+ }
+ else if (IS_AUDIT_OP(msg->attr, AUDIT_DIR)) {
+ //audit for dir.
+ //if dir is splitted, send RPC to all mds involved
+ struct lmv_obj *obj;
+ struct lustre_id rid;
+ int i;
+
+ obj = lmv_grab_obj(obd, &msg->id);
+ if (obj) {
+ lmv_lock_obj(obj);
+ for (i = 0; i < obj->objcount; i++) {
+ rid = obj->objs[i].id;
+ mds = id_group(&rid);
+ obd_set_info(lmv->tgts[mds].ltd_exp,
+ keylen, key,
+ vallen, val);
+ }
+ lmv_unlock_obj(obj);
+ lmv_put_obj(obj);
+ }
+ else {
+ rc = obd_set_info(lmv->tgts[mds].ltd_exp,
+ keylen, key, vallen, val);
+ }
+ }
+ else {
+ //set audit for file
+ rc = obd_set_info(lmv->tgts[mds].ltd_exp,
+ keylen, key, vallen, val);
+ }
+ RETURN(rc);
+ }
if (((keylen == strlen("flush_cred") &&
strcmp(key, "flush_cred") == 0)) ||
((keylen == strlen("crypto_type") &&
#include <linux/obd_lov.h>
#include <linux/obd_ost.h>
#include <linux/lprocfs_status.h>
-
+#include <linux/lustre_audit.h>
#include "lov_internal.h"
/* obd methods */
spin_unlock(&lov->lov_lock);
RETURN(rc);
+ } else if (KEY_IS("auditlog")) {
+ ptl_nid_t nid = 0;
+ struct audit_msg * msg = val;
+ int i = 0, len = sizeof(nid);
+ struct obd_export * ost_exp;
+ //try to find client nid
+ for (i = 0; i < lov->desc.ld_tgt_count; i++) {
+ if (!lov->tgts[i].ltd_exp)
+ continue;
+ rc = obd_get_info(lov->tgts[i].ltd_exp, 10,
+ "client_nid", &len, &nid);
+ if (!rc)
+ break;
+ }
+
+ i = (__u32)nid % lov->desc.ld_tgt_count;
+
+ CDEBUG(D_INFO, "Select OST %i for nid %.8x\n",i, (__u32)nid);
+
+ ost_exp = lov->tgts[i].ltd_exp;
+ if (!ost_exp) {
+ CERROR("can't send auditlog data,"
+ "device %s is not attached?\n",
+ lov->tgts[i].uuid.uuid);
+ RETURN(-EFAULT);
+ }
+ msg->nid = nid;
+ rc = obd_set_info(ost_exp, keylen, key, vallen, val);
+
+ RETURN(rc);
+ } else if (KEY_IS("audit_obj")) {
+ struct audit_lov_msg * msg = val;
+ int i = 0, index;
+ struct obd_export * ost_exp;
+ struct lov_oinfo *loi;
+ struct obdo *oa = NULL;
+
+ oa = obdo_alloc();
+ if (oa == NULL)
+ RETURN(-ENOMEM);
+
+ //set audit for all objects of file
+ CDEBUG(D_INFO, "Set audit 0x%x for objects\n", (__u32)msg->mask);
+ //use o_fid to store audit mask
+ oa->o_fid = msg->mask;
+ oa->o_uid = msg->uid;
+ oa->o_gid = msg->gid;
+ //iterate over all objects and set audit for each
+ for (i = 0, loi = msg->lsm->lsm_oinfo;
+ i < msg->lsm->lsm_stripe_count; i++, loi++) {
+ index = loi->loi_ost_idx;
+ ost_exp = lov->tgts[index].ltd_exp;
+ if (!ost_exp) {
+ CERROR("can't send audit_obj data,"
+ "device %s is not attached?\n",
+ lov->tgts[i].uuid.uuid);
+ continue;
+ }
+ oa->o_id = loi->loi_id;
+ oa->o_gr = loi->loi_gr;
+
+ obd_set_info(ost_exp, keylen, key, sizeof(*oa), oa);
+ }
+
+ obdo_free(oa);
+ RETURN(0);
+ } else if (KEY_IS("audit")) {
+ int i = 0;
+ struct obd_export * ost_exp;
+
+ //set audit for whole fs on OSS
+ for (i = 0; i < lov->desc.ld_tgt_count; i++) {
+ ost_exp = lov->tgts[i].ltd_exp;
+ if (!ost_exp) {
+ CERROR("can't send audit_fs data,"
+ "device %s is not attached?\n",
+ lov->tgts[i].uuid.uuid);
+ continue;
+ }
+ obd_set_info(ost_exp, keylen, key, vallen, val);
+ }
+
+ RETURN(rc);
} else if (KEY_IS("flush_cred") || KEY_IS("crypto_cb")) {
struct lov_tgt_desc *tgt;
int rc = 0, i;
#define XATTR_LUSTRE_MDS_MEA_EA "mea"
#define XATTR_LUSTRE_MDS_MID_EA "mid"
#define XATTR_LUSTRE_MDS_SID_EA "sid"
+#define XATTR_LUSTRE_MDS_PID_EA "pid"
#define XATTR_LUSTRE_MDS_KEY_EA "key"
/*
XATTR_LUSTRE_MDS_MID_EA,
lmm, lmm_size);
break;
+ case EA_PID:
+ rc = fsfilt_ext3_set_xattr(inode, handle,
+ XATTR_LUSTRE_MDS_PID_EA,
+ lmm, lmm_size);
+ break;
case EA_KEY:
rc = fsfilt_ext3_set_xattr(inode, handle,
XATTR_LUSTRE_MDS_KEY_EA,
XATTR_LUSTRE_MDS_MID_EA,
lmm, lmm_size);
break;
+ case EA_PID:
+ rc = fsfilt_ext3_get_xattr(inode,
+ XATTR_LUSTRE_MDS_PID_EA,
+ lmm, lmm_size);
+ break;
case EA_KEY:
rc = fsfilt_ext3_get_xattr(inode,
XATTR_LUSTRE_MDS_KEY_EA,
save->luc.luc_fsuid = current->fsuid;
save->luc.luc_fsgid = current->fsgid;
save->luc.luc_cap = current->cap_effective;
-
+ save->luc.luc_nid = current->user->nid;
+
current->uid = uc->luc_uid;
current->gid = uc->luc_gid;
current->fsuid = uc->luc_fsuid;
current->fsgid = uc->luc_fsgid;
current->cap_effective = uc->luc_cap;
+ current->user->nid = uc->luc_nid;
push_group_info(save, uc->luc_ginfo);
}
current->fsuid = saved->luc.luc_fsuid;
current->fsgid = saved->luc.luc_fsgid;
current->cap_effective = saved->luc.luc_cap;
-
+ current->user->nid = saved->luc.luc_nid;
pop_group_info(saved, uc->luc_ginfo);
}
CDEBUG(D_HA, "%s: set async = %d\n",
exp->exp_obd->obd_name, cl->cl_async);
RETURN(0);
+ } else if (keylen == 5 && strcmp(key, "audit") == 0) {
+ struct ptlrpc_request *req;
+ char *bufs[2] = {key, val};
+ int rc, size[2] = {keylen, vallen};
+
+ req = ptlrpc_prep_req(class_exp2cliimp(exp), LUSTRE_OBD_VERSION,
+ OST_SET_INFO, 2, size, bufs);
+ if (req == NULL)
+ RETURN(-ENOMEM);
+
+ req->rq_replen = lustre_msg_size(0, NULL);
+ lustre_swab_reqbuf(req, 1, sizeof(struct audit_attr_msg),
+ lustre_swab_audit_attr);
+ rc = ptlrpc_queue_wait(req);
+ ptlrpc_req_finished(req);
+
+ RETURN(rc);
+ } else if (keylen == strlen("ids") && memcmp(key, "ids", keylen) == 0) {
+ struct ptlrpc_request *req;
+ struct lustre_id *ids = (struct lustre_id *)val;
+ char *bufs[3] = {key, (char *)ids, (char *)(ids + 1)};
+ int rc, size[3] = {keylen, sizeof(struct lustre_id),
+ sizeof(struct lustre_id)};
+
+ req = ptlrpc_prep_req(class_exp2cliimp(exp), LUSTRE_OBD_VERSION,
+ OST_SET_INFO, 3, size, bufs);
+ if (req == NULL)
+ RETURN(-ENOMEM);
+
+ req->rq_replen = lustre_msg_size(0, NULL);
+ rc = ptlrpc_queue_wait(req);
+ ptlrpc_req_finished(req);
+ RETURN(rc);
}
RETURN(rc);
}
if ((keylen < strlen("mdsize") || strcmp(key, "mdsize") != 0) &&
(keylen < strlen("mdsnum") || strcmp(key, "mdsnum") != 0) &&
- (keylen < strlen("rootid") || strcmp(key, "rootid") != 0))
+ (keylen < strlen("rootid") || strcmp(key, "rootid") != 0) &&
+ (keylen < strlen("auditid") || strcmp(key, "auditid") != 0))
RETURN(-EPROTO);
req = ptlrpc_prep_req(class_exp2cliimp(exp), LUSTRE_OBD_VERSION,
if (rc)
GOTO(out_req, rc);
- if (keylen >= strlen("rootid") && !strcmp(key, "rootid")) {
+ if ((keylen >= strlen("rootid") && !strcmp(key, "rootid")) ||
+ (keylen >= strlen("auditid") && !strcmp(key, "auditid"))) {
struct lustre_id *reply;
reply = lustre_swab_repbuf(req, 0, sizeof(*reply),
MODULES := mds
mds-objs := mds_log.o mds_unlink_open.o mds_lov.o handler.o mds_reint.o
mds-objs += mds_fs.o lproc_mds.o mds_open.o mds_lib.o mds_lmv.o mds_lsd.o
-mds-objs += mds_acl.o
+mds-objs += mds_audit_path.o mds_audit.o mds_acl.o
@INCLUDE_RULES@
#include <linux/lustre_gs.h>
#include "mds_internal.h"
#include <linux/lustre_sec.h>
+#include <linux/lustre_audit.h>
+
+extern int mds_audit_auth(struct ptlrpc_request *, struct lvfs_ucred *,
+ audit_op, struct lustre_id *,
+ char *, int);
+extern int mds_audit_stat(struct ptlrpc_request *, struct lustre_id *,
+ struct dentry *, int);
+extern int mds_audit_open(struct ptlrpc_request *, struct mds_update_record *,
+ int);
static int mds_intent_policy(struct ldlm_namespace *ns,
struct ldlm_lock **lockp, void *req_cookie,
if (reqbody->valid & OBD_MD_FLKEY) {
rc = mds_pack_gskey(obd, req->rq_repmsg, &offset,
body, inode);
- }
+ }
+
+ mds_pack_audit(obd, inode, body);
if (rc == 0)
mds_body_do_reverse_map(med, body);
rc = mds_md_get_attr(obd, inode, &mea, &mea_size);
if (rc)
RETURN(rc);
- if (mea != NULL) {
+ if (mea != NULL && mea->mea_count) {
/*
* dir is already splitted, check if requested filename should
* live at this MDS or at another one.
rc = mds_init_ucred(&uc, req, rsd);
if (rc) {
+ if (child_lockh->cookie == 0)
+ mds_audit_auth(req, &uc, AUDIT_STAT, &body->id1,
+ name, namesize);
GOTO(cleanup, rc);
}
#endif
if (dparent)
l_dput(dparent);
+
+ /* audit stuff for getattr */
+ if (dchild->d_inode)
+ mds_audit_stat(req, &body->id1, dchild, rc);
}
l_dput(dchild);
case 1:
rc = mds_init_ucred(&uc, req, rsd);
if (rc) {
+ mds_audit_auth(req, &uc, AUDIT_READDIR, &body->id1,
+ NULL, 0);
GOTO(out, rc);
}
rc = mds_init_ucred(&rec->ur_uc, req, rsd);
if (rc) {
+ audit_op code = AUDIT_NONE;
+ char * au_name = NULL;
+ int au_len = 0;
+ switch (rec->ur_opcode) {
+ case REINT_SETATTR:
+ code = AUDIT_SETATTR;
+ break;
+ case REINT_CREATE:
+ code = AUDIT_CREATE;
+ au_name = rec->ur_name;
+ au_len = rec->ur_namelen;
+ break;
+ case REINT_LINK:
+ code = AUDIT_LINK;
+ break;
+ case REINT_UNLINK:
+ code = AUDIT_UNLINK;
+ break;
+ case REINT_RENAME:
+ code = AUDIT_RENAME;
+ break;
+ case REINT_OPEN:
+ au_name = rec->ur_name;
+ au_len = rec->ur_namelen;
+ code = AUDIT_OPEN;
+ break;
+ default:
+ CERROR("Wrong opcode in reint\n");
+ LBUG();
+ }
+
+ mds_audit_auth(req, &rec->ur_uc, code, rec->ur_id1,
+ au_name, au_len);
GOTO(out, rc);
}
/* rc will be used to interrupt a for loop over multiple records */
rc = mds_reint_rec(rec, offset, req, lockh);
+ /* audit stuff for OPEN */
+ if (offset == 3 && rec->ur_opcode == REINT_OPEN)
+ mds_audit_open(req, rec, rc);
+
out:
mds_exit_ucred(&rec->ur_uc);
OBD_FREE(rec, sizeof(*rec));
if ((body->oa.o_flags & OBD_FL_RECREATE_OBJS) ||
lustre_msg_get_flags(req->rq_reqmsg) & MSG_REPLAY) {
- id_group(&id) = mds->mds_num;
-
- LASSERT(body->oa.o_fid != 0);
- id_fid(&id) = body->oa.o_fid;
-
LASSERT(body->oa.o_id != 0);
- id_ino(&id) = repbody->oa.o_id;
- id_gen(&id) = repbody->oa.o_generation;
-
- down(&new->d_inode->i_sem);
- rc = mds_update_inode_sid(obd, new->d_inode, handle, &id);
- up(&new->d_inode->i_sem);
-
- /*
- * make sure, that fid is up-to-date.
- */
- mds_set_last_fid(obd, id_fid(&id));
- } else {
- /*
- * allocate new sid, as object is created from scratch
- * and this is not replay.
- */
- down(&new->d_inode->i_sem);
- rc = mds_set_inode_sid(obd, new->d_inode, handle, &id, fid);
- up(&new->d_inode->i_sem);
- }
- if (rc) {
- CERROR("Can't update lustre ID for inode %lu, "
- "error = %d\n", new->d_inode->i_ino, rc);
- GOTO(cleanup, rc);
+ LASSERT(body->oa.o_fid != 0);
}
+
+ mds_inode2id(obd, &id, new->d_inode, fid);
+ mds_update_inode_ids(obd, new->d_inode, handle, &id,
+ obdo_id(&body->oa));
/* initializing o_fid after it is allocated. */
repbody->oa.o_fid = id_fid(&id);
GOTO(cleanup, rc = -ENOMEM);
mea->mea_magic = MEA_MAGIC_ALL_CHARS;
- mea->mea_master = 0;
+ mea->mea_master = body->oa.o_mds; /* master mds num */
mea->mea_count = 0;
+
+ obdo2id(&mea->mea_ids[body->oa.o_mds], &body->oa);
down(&new->d_inode->i_sem);
rc = fsfilt_set_md(obd, new->d_inode, handle,
rc = obd_set_info(mds->mds_dt_exp, strlen("mds_conn"),
"mds_conn", valsize, &group);
RETURN(rc);
+ } else if (keylen == 5 && memcmp(key, "audit", 5) == 0) {
+ rc = mds_set_audit(obd, val);
+ RETURN(rc);
+ } else if (keylen >= strlen("ids") && memcmp(key, "ids", keylen) == 0) {
+ struct lustre_id *ids = (struct lustre_id *)val;
+ struct dentry *de;
+ struct inode *inode;
+ void *handle;
+ int err;
+
+ de = mds_id2dentry(obd, ids, NULL);
+ if (IS_ERR(de)) {
+ rc = PTR_ERR(de);
+ CERROR("lookup by an id error %d\n", rc);
+ RETURN(rc);
+ }
+ inode = de->d_inode;
+ if (inode == NULL)
+ GOTO(out_put, rc = -ENOENT);
+
+ down(&inode->i_sem);
+ handle = fsfilt_start(obd, inode, FSFILT_OP_SETATTR, NULL);
+ if (IS_ERR(handle)) {
+ up(&inode->i_sem);
+ GOTO(out_put, rc = PTR_ERR(handle));
+ }
+
+ rc = mds_update_inode_ids(obd, inode, handle, NULL, ids + 1);
+
+ err = fsfilt_commit(obd, mds->mds_sb, inode, handle,
+ exp->exp_sync);
+ if (err) {
+ CERROR("error committing transaction: %d\n", err);
+ if (!rc) rc = err;
+ }
+ up(&inode->i_sem);
+out_put:
+ l_dput(de);
+ RETURN(rc);
}
+
if (keylen >= strlen("crypto_type") &&
memcmp(key, "crypto_type", keylen) == 0) {
rc = mds_set_crypto_type(obd, val, vallen);
{
char *key, *val;
struct obd_export *exp = req->rq_export;
- int keylen, rc = 0, vallen;
+ int keylen, rc = 0, vallen = 0;
ENTRY;
key = lustre_msg_buf(req->rq_reqmsg, 0, 1);
rc = obd_set_info(exp, keylen, key, vallen, val);
req->rq_repmsg->status = 0;
RETURN(rc);
+ } else if (keylen == 5 && memcmp(key, "audit", 5) == 0) {
+ struct audit_attr_msg msg, *p;
+ int rc = 0;
+
+ rc = lustre_pack_reply(req, 0, NULL, NULL);
+ if (rc)
+ RETURN(rc);
+
+ p = lustre_swab_reqbuf(req, 1, sizeof(msg),
+ lustre_swab_audit_attr);
+
+ msg = *p;
+ CDEBUG(D_INFO, "Get new audit setting 0x%x\n", (__u32)msg.attr);
+ rc = obd_set_info(exp, keylen, key, sizeof(msg), &msg);
+
+ req->rq_repmsg->status = rc;
+ RETURN(rc);
+ } else if (keylen == strlen("ids") &&
+ memcmp(key, "ids", keylen) == 0) {
+ struct lustre_id *id, ids[2];
+
+ rc = lustre_pack_reply(req, 0, NULL, NULL);
+ if (rc)
+ RETURN(rc);
+ id = lustre_swab_reqbuf(req, 1, sizeof(struct lustre_id),
+ lustre_swab_lustre_id);
+ ids[1] = *id;
+ id = lustre_swab_reqbuf(req, 2, sizeof(struct lustre_id),
+ lustre_swab_lustre_id);
+ ids[2] = *id;
+
+ rc = obd_set_info(exp, keylen, key, vallen, ids);
+ req->rq_repmsg->status = rc;
+ RETURN(rc);
}
+
CDEBUG(D_IOCTL, "invalid key\n");
RETURN(-EINVAL);
}
OBD_FAIL_RETURN(OBD_FAIL_MDS_SYNC_NET, 0);
rc = mds_sync(req, MDS_REQ_REC_OFF);
break;
-
+ case MDS_PARSE_ID:
+ DEBUG_REQ(D_INODE, req, "parseid");
+ rc = mds_parse_id(req);
+ break;
case OBD_PING:
DEBUG_REQ(D_INODE, req, "ping");
rc = target_handle_ping(req);
return fid;
}
-/*
- * update new lustre_id on passed @inode and saves it to inode EA.
- */
-int mds_set_inode_sid(struct obd_device *obd, struct inode *inode,
- void *handle, struct lustre_id *id, __u64 fid)
-{
- struct mds_obd *mds = &obd->u.mds;
- int alloc = 0, rc = 0;
- ENTRY;
-
- LASSERT(obd != NULL);
- LASSERT(inode != NULL);
-
- if (id == NULL) {
- OBD_ALLOC(id, sizeof(*id));
- if (id == NULL)
- RETURN(-ENOMEM);
- alloc = 1;
- }
- id_group(id) = mds->mds_num;
- id_fid(id) = fid;
- id_ino(id) = inode->i_ino;
- id_gen(id) = inode->i_generation;
- id_type(id) = (S_IFMT & inode->i_mode);
-
- rc = mds_update_inode_sid(obd, inode, handle, id);
- if (rc) {
- CERROR("Can't update inode FID EA, "
- "rc = %d\n", rc);
- }
-
- if (alloc)
- OBD_FREE(id, sizeof(*id));
- RETURN(rc);
-}
/*
* reads inode self id from inode EA. Probably later this should be replaced by
} else {
rc = 0;
}
+ id_ino(id) = inode->i_ino;
+ id_gen(id) = inode->i_generation;
+ id_type(id) = S_IFMT & inode->i_mode;
+
+ RETURN(rc);
+}
+
+int mds_read_inode_pid(struct obd_device *obd, struct inode *inode,
+ struct lustre_id *id)
+{
+ int rc;
+ ENTRY;
+
+ LASSERT(inode && id);
+
+ rc = fsfilt_get_md(obd, inode, id, sizeof(*id), EA_PID);
+ if (rc < 0)
+ CERROR("get parent id from EA failed, rc=%d\n", rc);
+ else if (!rc)
+ rc = -ENODATA;
+ else
+ rc = 0;
RETURN(rc);
}
/* updates inode self id in EA. */
-int mds_update_inode_sid(struct obd_device *obd, struct inode *inode,
- void *handle, struct lustre_id *id)
+int mds_update_inode_ids(struct obd_device *obd, struct inode *inode,
+ void *handle, struct lustre_id *id,
+ struct lustre_id *pid)
{
int rc = 0;
ENTRY;
-
- LASSERT(id != NULL);
+
+ LASSERT(id || pid);
+ LASSERT(id == NULL || id_fid(id) != 0);
+ LASSERT(pid == NULL || id_fid(pid) != 0);
LASSERT(obd != NULL);
LASSERT(inode != NULL);
- rc = fsfilt_set_md(obd, inode, handle, &id->li_fid,
- sizeof(id->li_fid), EA_SID);
- if (rc) {
- CERROR("fsfilt_set_md() failed, rc = %d\n", rc);
- RETURN(rc);
+ if (id) {
+ mds_set_last_fid(obd, id_fid(id));
+ rc = fsfilt_set_md(obd, inode, handle, &id->li_fid,
+ sizeof(id->li_fid), EA_SID);
+ LASSERTF(rc == 0, "failed to update fid: %d\n", rc);
+ }
+ if (pid) {
+ rc = fsfilt_set_md(obd, inode, handle, pid,
+ sizeof(*pid), EA_PID);
+ LASSERTF(rc == 0, "failed to update parent fid: %d\n", rc);
}
RETURN(rc);
rc = mds_fs_setup_virtid(obd);
if (rc)
GOTO(err_fs, rc);
+
}
ptlrpc_init_client(LDLM_CB_REQUEST_PORTAL, LDLM_CB_REPLY_PORTAL,
(int)PTR_ERR(dentry));
RETURN(PTR_ERR(dentry));
}
-
rc = fsfilt_post_setup(obd, dentry);
+ //set id2name function handler
+ fsfilt_set_info(obd, mds->mds_sb, NULL, 7, "id2name",
+ sizeof(mds_audit_id2name), mds_audit_id2name);
l_dput(dentry);
RETURN(rc);
fixup_handle_for_resent_req(req, MDS_REQ_INTENT_LOCKREQ_OFF,
lock, NULL, lockh);
rep->lock_policy_res2 = mds_reint(req, offset, lockh);
-
+
if (rep->lock_policy_res2) {
/*
* mds_open() returns ENOLCK where it should return
{
struct obd_device *obd;
struct mds_obd *mds;
+ int rc = 0;
ENTRY;
obd = class_exp2obd(exp);
if (keylen >= strlen("reint_log") && memcmp(key, "reint_log", 9) == 0) {
/* get log_context handle. */
+ struct llog_ctxt *ctxt;
unsigned long *llh_handle = val;
*valsize = sizeof(unsigned long);
- *llh_handle = (unsigned long)obd->obd_llog_ctxt[LLOG_REINT_ORIG_CTXT];
+ ctxt = llog_get_context(&obd->obd_llogs, LLOG_REINT_ORIG_CTXT);
+ if (!ctxt) {
+ CERROR("Cannot get REINT llog context\n");
+ RETURN(-ENOENT);
+ }
+ *llh_handle = (unsigned long)ctxt;
RETURN(0);
}
if (keylen >= strlen("cache_sb") && memcmp(key, "cache_sb", 8) == 0) {
*rootid = mds->mds_rootid;
RETURN(0);
}
-
+
if (keylen >= strlen("lovdesc") && strcmp(key, "lovdesc") == 0) {
struct lov_desc *desc = val;
*valsize = sizeof(*desc);
*desc = mds->mds_dt_desc;
RETURN(0);
}
-
- CDEBUG(D_IOCTL, "invalid key\n");
- RETURN(-EINVAL);
-
+
+ rc = fsfilt_get_info(obd, mds->mds_sb, NULL, keylen, key, valsize, val);
+ if (rc)
+ CDEBUG(D_IOCTL, "invalid key\n");
+
+ RETURN(rc);
}
+
struct lvfs_callback_ops mds_lvfs_ops = {
l_id2dentry: mds_lvfs_id2dentry,
};
--- /dev/null
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * lustre/mds/mds_audit.c
+ * Lustre Metadata Server (mds) audit stuff
+ *
+ * Copyright (c) 2001-2003 Cluster File Systems, Inc.
+ *
+ * This file is part of Lustre, http://www.lustre.org.
+ *
+ * Lustre is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * Lustre is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Lustre; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
+#define DEBUG_SUBSYSTEM S_MDS
+
+#include <linux/module.h>
+#include <linux/lustre_mds.h>
+#include <linux/lustre_dlm.h>
+#include <linux/init.h>
+#include <linux/obd_class.h>
+#include <linux/random.h>
+#include <linux/fs.h>
+#include <linux/jbd.h>
+#include <linux/namei.h>
+#include <linux/ext3_fs.h>
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
+# include <linux/smp_lock.h>
+# include <linux/buffer_head.h>
+# include <linux/workqueue.h>
+# include <linux/mount.h>
+#else
+# include <linux/locks.h>
+#endif
+#include <linux/obd_lov.h>
+#include <linux/obd_ost.h>
+#include <linux/lustre_mds.h>
+#include <linux/lustre_fsfilt.h>
+#include <linux/lprocfs_status.h>
+#include <linux/lustre_commit_confd.h>
+#include <linux/lustre_acl.h>
+#include <linux/lustre_audit.h>
+#include "mds_internal.h"
+
+int mds_audit_stat(struct ptlrpc_request *req, struct lustre_id * id,
+ struct dentry * dentry, int ret)
+{
+ struct obd_device *obd = req->rq_export->exp_obd;
+ struct inode * inode = dentry->d_inode;
+ ptl_nid_t nid = req->rq_peer.peer_id.nid;
+ struct audit_info info;
+ int rc = 0, len = sizeof(info);
+ ENTRY;
+
+ LASSERT(inode);
+ LASSERT(id);
+ memcpy(&info.m.id, id, sizeof(*id));
+ info.m.nid = nid;
+ info.m.uid = current->uid;
+ info.m.gid = current->gid;
+ info.m.result = ret;
+ info.m.code = AUDIT_STAT;
+
+ //send info to local fs
+ fsfilt_set_info(obd, inode->i_sb, inode,
+ 10, "audit_info", len, (void*)&info);
+
+ RETURN(rc);
+}
+
+int mds_audit_open(struct ptlrpc_request *req, struct mds_update_record * rec,
+ int ret)
+{
+ struct obd_device *obd = req->rq_export->exp_obd;
+ struct inode * inode = NULL;
+ ptl_nid_t nid = req->rq_peer.peer_id.nid;
+ struct audit_info info;
+ int rc = 0, len = sizeof(info);
+
+ struct dentry * dparent = NULL;
+
+ dparent = mds_id2dentry(obd, rec->ur_id1, NULL);
+ if (IS_ERR(dparent)) {
+ rc = PTR_ERR(dparent);
+ RETURN(rc);
+ }
+ inode = dparent->d_inode;
+
+ info.m.id = *(rec->ur_id1);
+ info.m.nid = nid;
+ info.m.uid = rec->ur_uc.luc_uid;
+ info.m.gid = rec->ur_uc.luc_gid;
+ info.m.result = ret;
+ info.m.code = AUDIT_OPEN;
+ info.name = rec->ur_name;
+ info.namelen = rec->ur_namelen;
+
+ //send info to local fs
+ fsfilt_set_info(obd, inode->i_sb, inode,
+ 10, "audit_info", len, (void*)&info);
+
+ l_dput(dparent);
+
+ RETURN(rc);
+}
+
+int mds_audit_auth(struct ptlrpc_request *req, struct lvfs_ucred * uc,
+ audit_op op, struct lustre_id * id,
+ char * name, int namelen)
+{
+ struct obd_device *obd = req->rq_export->exp_obd;
+ ptl_nid_t nid = req->rq_peer.peer_id.nid;
+ int rc = 0;
+ struct dentry * dparent;
+ struct inode * inode;
+ struct audit_info info;
+
+ ENTRY;
+
+ dparent = mds_id2dentry(obd, id, NULL);
+ if (IS_ERR(dparent)) {
+ rc = PTR_ERR(dparent);
+ GOTO(out, rc);
+ }
+ inode = dparent->d_inode;
+
+ info.m.nid = nid;
+ info.m.uid = uc->luc_uid;
+ info.m.gid = uc->luc_gid;
+ info.m.id = (*id);
+ info.m.result = -EPERM;
+ info.m.code = op;
+ info.name = name;
+ info.namelen = namelen;
+
+ fsfilt_set_info(obd, inode->i_sb, inode,
+ 10, "audit_info", sizeof(info), &info);
+ l_dput(dparent);
+
+ EXIT;
+ out:
+ return rc;
+}
+
+static int mds_set_obj_audit(struct obd_device * obd, struct inode * inode,
+ __u64 * mask)
+{
+ struct audit_lov_msg msg = {
+ .mask = *mask,
+ .lsm = NULL,
+ .uid = inode->i_uid,
+ .gid = inode->i_gid,
+ };
+ int len, rc = 0;
+ void *lmm = NULL;
+
+ down(&inode->i_sem);
+ len = fsfilt_get_md(obd, inode, NULL, 0, EA_LOV);
+ up(&inode->i_sem);
+
+ if (len < 0) {
+ CERROR("error getting inode %lu LOV: %d\n", inode->i_ino, len);
+ GOTO(out, rc = len);
+ } else if (len == 0) {
+ CDEBUG(D_INODE, "no LOV in inode %lu\n", inode->i_ino);
+ GOTO(out, rc = 0);
+ }
+
+ OBD_ALLOC(lmm, len);
+ if (lmm == NULL) {
+ CERROR("can't allocate memory\n");
+ GOTO(out, rc = -ENOMEM);
+ }
+
+ down(&inode->i_sem);
+ rc = fsfilt_get_md(obd, inode, lmm, len, EA_LOV);
+ up(&inode->i_sem);
+
+ if (rc < 0) {
+ CERROR("error getting inode %lu MD: %d\n", inode->i_ino, rc);
+ GOTO(out, rc);
+ }
+
+ rc = obd_unpackmd(obd->u.mds.mds_dt_exp, &msg.lsm, lmm, len);
+ if (rc < 0) {
+ CERROR("error unpacking inode %lu MD: %d\n", inode->i_ino, rc);
+ GOTO(out, rc);
+ }
+
+ obd_set_info(obd->u.mds.mds_dt_exp, 9, "audit_obj", sizeof(msg), &msg);
+
+out:
+ if (msg.lsm != NULL)
+ obd_free_memmd(obd->u.mds.mds_dt_exp, &msg.lsm);
+
+ if (lmm != NULL)
+ OBD_FREE(lmm, len);
+
+ RETURN(rc);
+}
+
+//set audit attributes for directory/file
+int mds_set_audit(struct obd_device * obd, void * val)
+{
+ struct inode * inode = NULL;
+ struct dentry * dentry = NULL;
+ //struct lvfs_run_ctxt saved;
+ struct audit_attr_msg * msg = val;
+
+ ENTRY;
+
+ //push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
+
+ dentry = mds_id2dentry(obd, &msg->id, NULL);
+ if (IS_ERR(dentry)) {
+ CERROR("Cannot get dentry\n");
+ RETURN(PTR_ERR(dentry));
+ }
+
+ inode = dentry->d_inode;
+ fsfilt_set_info(obd, inode->i_sb, inode,
+ 5, "audit", sizeof(msg->attr), &msg->attr);
+
+ if (S_ISREG(inode->i_mode) && !IS_AUDIT_OP(msg->attr, AUDIT_FS))
+ mds_set_obj_audit(obd, inode, &msg->attr);
+
+ l_dput(dentry);
+
+ //pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
+
+ RETURN(0);
+}
+
+int mds_pack_audit(struct obd_device * obd, struct inode * inode,
+ struct mds_body * body)
+{
+ __u64 mask = 0;
+ int len = sizeof(mask);
+ int rc = 0;
+
+ rc = fsfilt_get_info(obd, inode->i_sb, inode,
+ 5, "audit", &len, &mask);
+ if (!rc) {
+ body->audit = mask;
+ body->valid |= OBD_MD_FLAUDIT;
+ }
+ return rc;
+}
--- /dev/null
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *
+ * Copyright (C) 2001-2003 Cluster File Systems, Inc.
+ *
+ * This file is part of Lustre, http://www.lustre.org.
+ *
+ * Lustre is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * Lustre is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Lustre; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
+#define DEBUG_SUBSYSTEM S_MDS
+
+#include <linux/module.h>
+#include <linux/lustre_mds.h>
+#include <linux/lustre_dlm.h>
+#include <linux/lustre_fsfilt.h>
+#include <linux/init.h>
+#include <linux/obd_class.h>
+#include <linux/fs.h>
+#include <linux/namei.h>
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
+# include <linux/smp_lock.h>
+# include <linux/buffer_head.h>
+# include <linux/workqueue.h>
+# include <linux/mount.h>
+#else
+# include <linux/locks.h>
+#endif
+#include <linux/lustre_audit.h>
+#include "mds_internal.h"
+
+
+#define PP_FILE 1
+#define PP_DIR 2
+#define PP_SPLIT_MASTER 3
+#define PP_SPLIT_SLAVE 4
+#define PP_CROSS_DIR 5
+#define PP_AUDIT_LOG 6 /* search id in audit log */
+
+struct scan_dir_data {
+ int rc;
+ struct lustre_id *id;
+ char *name;
+};
+
+static int filldir(void *__buf, const char *name, int namlen,
+ loff_t offset, ino_t ino, unsigned int d_type)
+{
+ struct scan_dir_data *sd = __buf;
+ ENTRY;
+
+ if (name[0] == '.' &&
+ (namlen == 1 || (namlen == 2 && name[1] == '.'))) {
+ /* skip special entries */
+ RETURN(0);
+ }
+
+ LASSERT(sd != NULL);
+
+ if (ino == id_ino(sd->id)) {
+ strncpy(sd->name, name, namlen);
+ sd->rc = 0;
+ RETURN(-EINTR); /* break the readdir loop */
+ }
+ RETURN(0);
+}
+
+int
+scan_name_in_parent(struct lustre_id *pid, struct lustre_id *id, char *name)
+{
+ struct file * file;
+ char *pname;
+ struct scan_dir_data sd;
+ int len, rc = 0;
+ ENTRY;
+
+ len = strlen("__iopen__/") + 10 + 1;
+ OBD_ALLOC(pname, len);
+ if (!pname)
+ RETURN(-ENOMEM);
+
+ sprintf(pname, "__iopen__/0x%llx", id_ino(pid));
+
+ file = filp_open(pname, O_RDONLY, 0);
+ if (IS_ERR(file)) {
+ CERROR("can't open directory %s: %d\n",
+ pname, (int) PTR_ERR(file));
+ GOTO(out, rc = PTR_ERR(file));
+ }
+
+ sd.id = id;
+ sd.name = name;
+ sd.rc = -ENOENT;
+ vfs_readdir(file, filldir, &sd);
+
+ filp_close(file, 0);
+ rc = sd.rc;
+
+out:
+ OBD_FREE(pname, len);
+ RETURN(rc);
+
+}
+
+/* id2pid - given id, get parent id or master id.
+ * @obd: obd device
+ * @id: child id to be parsed
+ * @pid: parent id or master id
+ * @type: id type
+ */
+static int
+id2pid(struct obd_device *obd, struct lustre_id *id, struct lustre_id *pid,
+ __u32 *type)
+{
+ struct dentry *dentry = NULL;
+ struct inode *inode = NULL;
+ struct mea *mea = NULL;
+ int mea_size, rc = 0;
+ ENTRY;
+
+ dentry = mds_id2dentry(obd, id, NULL);
+ if (IS_ERR(dentry) || !dentry->d_inode) {
+ CERROR("can't find inode "LPU64"\n", id_ino(id));
+ if (!IS_ERR(dentry)) l_dput(dentry);
+ RETURN(-ENOENT);
+ }
+ inode = dentry->d_inode;
+
+ if (S_ISDIR(id_type(id))) {
+ LASSERT(S_ISDIR(inode->i_mode));
+ rc = mds_md_get_attr(obd, inode, &mea, &mea_size);
+ if (rc)
+ GOTO(out, rc);
+
+ if (!mea) {
+ *type = PP_DIR;
+ goto read_pid;
+ } else if (mea && mea->mea_count) {
+ *type = PP_SPLIT_MASTER;
+ goto read_pid;
+ } else {
+ *type = PP_SPLIT_SLAVE;
+ *pid = mea->mea_ids[mea->mea_master];
+ }
+
+ } else {
+ LASSERT(!S_ISDIR(inode->i_mode));
+ *type = PP_FILE;
+read_pid:
+ rc = mds_read_inode_pid(obd, inode, pid);
+ if (rc) {
+ CERROR("can't read parent ino(%lu) rc(%d).\n",
+ inode->i_ino, rc);
+ GOTO(out, rc);
+ }
+ }
+
+ /* Well, if it's dir or master split, we have to check if it's
+ * a cross-ref dir */
+ if ((*type == PP_DIR || *type == PP_SPLIT_MASTER) &&
+ id_group(id) != id_group(pid))
+ *type = PP_CROSS_DIR;
+out:
+ if (mea)
+ OBD_FREE(mea, mea_size);
+ l_dput(dentry);
+ RETURN(rc);
+}
+
+static int local_parse_id(struct obd_device *obd, struct parseid_pkg *pkg)
+{
+ struct lvfs_run_ctxt saved;
+ int rc = 0;
+ ENTRY;
+
+ pkg->pp_rc = 0;
+ pkg->pp_type = 0;
+ memset(pkg->pp_name, 0, sizeof(pkg->pp_name));
+
+ LASSERT(obd->u.mds.mds_num == id_group(&pkg->pp_id1));
+
+ /* pp_id2 is present, which indicating we want to scan parent
+ * dir(pp_id2) to find the cross-ref entry(pp_id1) */
+ if (id_fid(&pkg->pp_id2)) {
+ LASSERT(S_ISDIR(id_type(&pkg->pp_id1)));
+ LASSERT(S_ISDIR(id_type(&pkg->pp_id2)));
+
+ pkg->pp_type = PP_DIR;
+ goto scan;
+ }
+
+ rc = id2pid(obd, &pkg->pp_id1, &pkg->pp_id2, &pkg->pp_type);
+ if (rc)
+ GOTO(out, rc);
+scan:
+ push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
+
+ switch (pkg->pp_type) {
+ case PP_FILE:
+ case PP_DIR:
+ case PP_SPLIT_MASTER:
+ rc = scan_name_in_parent(&pkg->pp_id2, &pkg->pp_id1,
+ pkg->pp_name);
+ if (rc)
+ CERROR("scan "LPU64" in parent failed. rc=%d\n",
+ id_ino(&pkg->pp_id1), rc);
+ break;
+ case PP_SPLIT_SLAVE:
+ case PP_CROSS_DIR:
+ break;
+ default:
+ CERROR("invalid id\n");
+ break;
+ }
+
+ pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
+out:
+ pkg->pp_rc = rc;
+ RETURN(rc);
+}
+
+static int
+local_scan_audit_log(struct obd_device *obd, struct parseid_pkg *pkg);
+
+int mds_parse_id(struct ptlrpc_request *req)
+{
+ struct parseid_pkg *pkg, *reppkg;
+ struct obd_device *obd = req->rq_export->exp_obd;
+ int rc = 0, size = sizeof(*reppkg);
+ ENTRY;
+
+ pkg = lustre_swab_reqbuf(req, 0, sizeof(*pkg),
+ lustre_swab_parseid_pkg);
+ if (pkg == NULL)
+ RETURN(-EPROTO);
+
+ rc = lustre_pack_reply(req, 1, &size, NULL);
+ if (rc)
+ RETURN(rc);
+
+ reppkg = lustre_msg_buf(req->rq_repmsg, 0, sizeof(*reppkg));
+ memcpy(reppkg, pkg, sizeof(*reppkg));
+
+ if (reppkg->pp_type == PP_AUDIT_LOG)
+ rc = local_scan_audit_log(obd, reppkg);
+ else
+ rc = local_parse_id(obd, reppkg);
+
+ if (rc)
+ CERROR("local parseid failed. (rc:%d)\n", rc);
+ RETURN(0); /* we do need pack reply here */
+}
+
+static int parse_id(struct obd_device *obd, struct parseid_pkg *pkg)
+{
+ int rc = 0;
+ int mds_num = id_group(&pkg->pp_id1);
+ ENTRY;
+
+ LASSERT(mds_num >= 0);
+
+ if (mds_num == obd->u.mds.mds_num) {
+ rc = local_parse_id(obd, pkg);
+ } else {
+ struct ptlrpc_request *req;
+ struct lmv_obd *lmv = &obd->u.mds.mds_md_obd->u.lmv;
+ struct parseid_pkg *body;
+ int size = sizeof(*body);
+ struct obd_export *exp = lmv->tgts[mds_num].ltd_exp;
+
+ req = ptlrpc_prep_req(class_exp2cliimp(exp),
+ LUSTRE_MDS_VERSION, MDS_PARSE_ID, 1,
+ &size, NULL);
+ if (!req)
+ RETURN(-ENOMEM);
+
+ body = lustre_msg_buf(req->rq_reqmsg, 0, sizeof(*body));
+ memcpy(body, pkg, sizeof(*body));
+
+ req->rq_replen = lustre_msg_size(1, &size);
+
+ rc = ptlrpc_queue_wait(req);
+ if (rc)
+ GOTO(out, rc);
+
+ body = lustre_swab_repbuf(req, 0, sizeof(*body),
+ lustre_swab_parseid_pkg);
+ if (body == NULL) {
+ CERROR("can't unpack parseid_pkg\n");
+ GOTO(out, rc = -EPROTO);
+ }
+ memcpy(pkg, body, sizeof(*pkg));
+out:
+ ptlrpc_req_finished(req);
+ }
+ RETURN(rc);
+}
+
+struct name_item {
+ struct list_head link;
+ char name[NAME_MAX + 1];
+};
+
+int
+mds_id2name(struct obd_device *obd, struct lustre_id *id,
+ struct lustre_id *rootid, struct list_head *list,
+ struct lustre_id *lastid)
+{
+ struct name_item *item;
+ struct parseid_pkg *pkg;
+ int rc = 0;
+ ENTRY;
+
+ OBD_ALLOC(pkg, sizeof(*pkg));
+ if (pkg == NULL)
+ RETURN(-ENOMEM);
+
+ pkg->pp_id1 = *id;
+ while (!id_equal(&pkg->pp_id1, rootid)) {
+
+ rc = parse_id(obd, pkg);
+ if (rc) {
+ CDEBUG(D_SEC, "parse id failed. rc=%d\n", rc);
+ *lastid = pkg->pp_id1;
+ break;
+ }
+
+ switch (pkg->pp_type) {
+ case PP_FILE:
+ case PP_DIR:
+ case PP_SPLIT_MASTER:
+ OBD_ALLOC(item, sizeof(*item));
+ if (item == NULL)
+ GOTO(out, rc = -ENOMEM);
+
+ INIT_LIST_HEAD(&item->link);
+ list_add(&item->link, list);
+ memcpy(item->name, pkg->pp_name, sizeof(item->name));
+
+ case PP_SPLIT_SLAVE:
+ pkg->pp_id1 = pkg->pp_id2;
+ memset(&pkg->pp_id2, 0, sizeof(struct lustre_id));
+ break;
+ case PP_CROSS_DIR:
+ break;
+ default:
+ LBUG();
+ break;
+ }
+
+ }
+out:
+ OBD_FREE(pkg, sizeof(*pkg));
+ RETURN(rc);
+}
+
+static int
+scan_audit_log_cb(struct llog_handle *llh, struct llog_rec_hdr *rec, void *data)
+{
+ struct parseid_pkg *pkg = (struct parseid_pkg *)data;
+ struct audit_record *ad_rec;
+ struct audit_id_record *cid_rec, *pid_rec;
+ struct audit_name_record *nm_rec;
+ ENTRY;
+
+ if (!(le32_to_cpu(llh->lgh_hdr->llh_flags) & LLOG_F_IS_PLAIN)) {
+ CERROR("log is not plain\n");
+ RETURN(-EINVAL);
+ }
+ if (rec->lrh_type != SMFS_AUDIT_NAME_REC &&
+ rec->lrh_type != LLOG_GEN_REC) {
+ RETURN(0);
+ }
+
+ ad_rec = (struct audit_record *)((char *)rec + sizeof(*rec));
+
+ if (ad_rec->result ||
+ ad_rec->opcode != AUDIT_UNLINK ||
+ ad_rec->opcode != AUDIT_RENAME)
+ RETURN(0);
+
+ cid_rec = (struct audit_id_record *)((char *)ad_rec + sizeof(*ad_rec));
+ pid_rec = cid_rec + 1;
+ nm_rec = (struct audit_name_record *)
+ ((char *)pid_rec + sizeof(*pid_rec));
+
+ if (cid_rec->au_num == id_ino(&pkg->pp_id1) &&
+ cid_rec->au_gen == id_gen(&pkg->pp_id1)) {
+ /* get parent id */
+ id_ino(&pkg->pp_id2) = pid_rec->au_num;
+ id_gen(&pkg->pp_id2) = pid_rec->au_gen;
+ id_type(&pkg->pp_id2) = pid_rec->au_type;
+ id_fid(&pkg->pp_id2) = pid_rec->au_fid;
+ id_group(&pkg->pp_id2) = pid_rec->au_mds;
+ /* get name */
+ memcpy(pkg->pp_name, nm_rec->name,
+ le32_to_cpu(nm_rec->name_len));
+
+ RETURN(LLOG_PROC_BREAK);
+ }
+ RETURN(0);
+}
+
+static int
+local_scan_audit_log(struct obd_device *obd, struct parseid_pkg *pkg)
+{
+ struct llog_handle *llh = NULL;
+ struct llog_ctxt *ctxt = llog_get_context(&obd->obd_llogs,
+ LLOG_AUDIT_ORIG_CTXT);
+ int rc = 0;
+ ENTRY;
+
+ if (ctxt)
+ llh = ctxt->loc_handle;
+
+ if (llh == NULL)
+ RETURN(-ENOENT);
+
+ rc = llog_cat_process(llh, (llog_cb_t)&scan_audit_log_cb, (void *)pkg);
+ if (rc != LLOG_PROC_BREAK) {
+ CWARN("process catalog log failed: rc(%d)\n", rc);
+ RETURN(-ENOENT);
+ }
+ RETURN(0);
+}
+
+static int
+scan_audit_log(struct obd_device *obd, struct lustre_id *cur_id,
+ struct list_head *list, struct lustre_id *parent_id)
+{
+ struct name_item *item = NULL;
+ int rc = 0, mds_num = id_group(cur_id);
+ struct parseid_pkg *pkg = NULL;
+ ENTRY;
+
+ OBD_ALLOC(pkg, sizeof(*pkg));
+ if (pkg == NULL)
+ RETURN(-ENOMEM);
+
+ pkg->pp_type = PP_AUDIT_LOG;
+ pkg->pp_id1 = *cur_id;
+
+ if (obd->u.mds.mds_num == mds_num) {
+ rc = local_scan_audit_log(obd, pkg);
+ } else {
+ struct ptlrpc_request *req;
+ struct lmv_obd *lmv = &obd->u.mds.mds_md_obd->u.lmv;
+ struct parseid_pkg *body;
+ int size = sizeof(*body);
+ struct obd_export *exp = lmv->tgts[mds_num].ltd_exp;
+
+ req = ptlrpc_prep_req(class_exp2cliimp(exp),
+ LUSTRE_MDS_VERSION, MDS_PARSE_ID, 1,
+ &size, NULL);
+ if (!req)
+ RETURN(-ENOMEM);
+
+ body = lustre_msg_buf(req->rq_reqmsg, 0, sizeof(*body));
+ memcpy(body, pkg, sizeof(*body));
+
+ req->rq_replen = lustre_msg_size(1, &size);
+
+ rc = ptlrpc_queue_wait(req);
+ if (rc)
+ GOTO(out_req, rc);
+
+ body = lustre_swab_repbuf(req, 0, sizeof(*body),
+ lustre_swab_parseid_pkg);
+ if (body == NULL) {
+ CERROR("can't unpack parseid_pkg\n");
+ GOTO(out, rc = -EPROTO);
+ }
+ memcpy(pkg, body, sizeof(*pkg));
+out_req:
+ ptlrpc_req_finished(req);
+
+ }
+
+ if (!rc) rc = pkg->pp_rc;
+ if (rc)
+ GOTO(out, rc);
+
+ *parent_id = pkg->pp_id2;
+
+ OBD_ALLOC(item, sizeof(*item));
+ if (item == NULL)
+ GOTO(out, rc = -ENOMEM);
+
+ INIT_LIST_HEAD(&item->link);
+ list_add(&item->link, list);
+ memcpy(item->name, pkg->pp_name, sizeof(item->name));
+out:
+ OBD_FREE(pkg, sizeof(*pkg));
+ RETURN(rc);
+}
+
+int
+mds_audit_id2name(struct obd_device *obd, char **name, int *namelen,
+ struct lustre_id *id)
+{
+ int rc = 0;
+ struct list_head list, *pos, *n;
+ struct name_item *item;
+ struct lustre_id parent_id, cur_id, rootid;
+ ENTRY;
+
+ *namelen = 0;
+ INIT_LIST_HEAD(&list);
+
+ if (obd->u.mds.mds_num) {
+ int valsize = sizeof(rootid);
+ rc = obd_get_info(obd->u.mds.mds_md_exp, strlen("rootid"),
+ "rootid", &valsize, &rootid);
+ if (rc) {
+ CERROR("cann't get rootid!\n");
+ RETURN(rc);
+ }
+ } else {
+ rootid = obd->u.mds.mds_rootid;
+ }
+
+ cur_id = *id;
+ if (id_equal(&cur_id, &rootid))
+ RETURN(0);
+next:
+ memset(&parent_id, 0, sizeof(parent_id));
+
+ rc = mds_id2name(obd, &cur_id, &rootid, &list, &parent_id);
+ if (rc == -ENOENT) {
+ /* can't reconstruct name from id, turn to audit log */
+ LASSERT(id_fid(&parent_id));
+ cur_id = parent_id;
+ memset(&parent_id, 0, sizeof(parent_id));
+
+ rc = scan_audit_log(obd, &cur_id, &list, &parent_id);
+ if (rc) {
+ CERROR("scan id in audit log failed. (rc:%d)\n", rc);
+ GOTO(out, rc);
+ }
+
+ LASSERT(id_fid(&parent_id));
+ cur_id = parent_id;
+ goto next;
+
+ } else if (rc) {
+ CERROR("reconstruct name from id failed. (rc:%d)\n", rc);
+ GOTO(out, rc);
+ }
+
+ list_for_each_safe (pos, n, &list) {
+ item = list_entry(pos, struct name_item, link);
+ *namelen += strlen(item->name) + 1;
+ }
+ OBD_ALLOC(*name, *namelen);
+ if (*name == NULL)
+ rc = -ENOMEM;
+out:
+ list_for_each_safe (pos, n, &list) {
+ item = list_entry(pos, struct name_item, link);
+ if (!rc) {
+ strcat(*name, "/");
+ strcat(*name, item->name);
+ }
+ list_del_init(&item->link);
+ OBD_FREE(item, sizeof(*item));
+ }
+ RETURN(rc);
+}
+EXPORT_SYMBOL(mds_audit_id2name);
struct inode *inode;
struct dentry *dentry;
struct mds_obd *mds = &obd->u.mds;
- __u64 fid;
ENTRY;
/* getting root directory and setup its fid. */
GOTO(out_dentry, rc);
}
- fid = mds_alloc_fid(obd);
- down(&inode->i_sem);
- rc = mds_set_inode_sid(obd, inode, handle, &mds->mds_rootid, fid);
- up(&inode->i_sem);
-
+ mds_inode2id(obd, &mds->mds_rootid, inode, mds_alloc_fid(obd));
+ rc = mds_update_inode_ids(obd, inode, handle, &mds->mds_rootid, NULL);
if (rc) {
- CERROR("mds_set_inode_sid() failed, rc = %d\n",
- rc);
+ CERROR("mds_update_inode_ids() failed, rc = %d\n", rc);
GOTO(out_dentry, rc);
}
id_gen(&sid) = inode->i_generation;
id_type(&sid) = (S_IFMT & inode->i_mode);
- down(&inode->i_sem);
- rc = mds_update_inode_sid(obd, inode, handle, &sid);
- up(&inode->i_sem);
+ rc = mds_update_inode_ids(obd, inode, handle, &sid, NULL);
if (rc) {
- CERROR("mds_update_inode_sid() failed, rc = %d\n",
- rc);
+ CERROR("mds_update_inode_ids() failed, rc = %d\n", rc);
RETURN(rc);
}
if (IS_ERR(dentry)) {
rc = PTR_ERR(dentry);
CERROR("cannot create UNNAMED directory: rc = %d\n", rc);
- GOTO(err_unnamed, rc);
+ GOTO(err_id_dir, rc);
}
mds->mds_unnamed_dir = dentry;
if (IS_ERR(file)) {
rc = PTR_ERR(file);
CERROR("cannot open/create %s file: rc = %d\n", LAST_RCVD, rc);
- GOTO(err_id_dir, rc = PTR_ERR(file));
+ GOTO(err_unnamed, rc = PTR_ERR(file));
}
mds->mds_rcvd_filp = file;
__u64 mds_alloc_fid(struct obd_device *obd);
-int mds_set_inode_sid(struct obd_device *, struct inode *,
- void *, struct lustre_id *, __u64 fid);
-
-int mds_update_inode_sid(struct obd_device *, struct inode *,
- void *, struct lustre_id *);
-
+void mds_inode2id(struct obd_device *obd, struct lustre_id *id,
+ struct inode *inode, __u64 fid);
+int mds_update_inode_ids(struct obd_device *, struct inode *,
+ void *, struct lustre_id *, struct lustre_id *);
int mds_read_inode_sid(struct obd_device *, struct inode *,
struct lustre_id *);
+int mds_read_inode_pid(struct obd_device *, struct inode *,
+ struct lustre_id *);
+
int mds_update_inode_mid(struct obd_device *, struct inode *,
void *, struct lustre_id *);
void mds_put_lsd(struct lustre_sec_desc *lsd);
void mds_flush_lsd(__u32 id);
+/* mds_audit_path.c */
+int mds_parse_id(struct ptlrpc_request *req);
+
+/* mds_audit.c */
+int mds_set_audit(struct obd_device * obd, void * val);
+int mds_pack_audit(struct obd_device *, struct inode *, struct mds_body *);
+
/* mds_acl.c */
struct upcall_cache *__mds_get_global_rmtacl_upcall_cache(void);
int mds_init_rmtacl_upcall_cache(void);
RETURN(rc);
}
+void mds_inode2id(struct obd_device *obd, struct lustre_id *id,
+ struct inode *inode, __u64 fid)
+{
+ struct mds_obd *mds = &obd->u.mds;
+ ENTRY;
+
+ LASSERT(inode != NULL);
+ LASSERT(id != NULL);
+ LASSERT(fid != 0);
+
+ id_fid(id) = fid;
+ id_ino(id) = inode->i_ino;
+ id_group(id) = mds->mds_num;
+ id_gen(id) = inode->i_generation;
+ id_type(id) = (S_IFMT & inode->i_mode);
+
+ EXIT;
+}
+
int mds_pack_gskey(struct obd_device *obd, struct lustre_msg *repmsg,
int *offset, struct mds_body *body, struct inode *inode)
{
CDEBUG(D_IOCTL, "invalid key\n");
RETURN(0);
-}
+}
+
/* Note that we can copy all of the fields, just some will not be "valid" */
void mds_pack_inode2body(struct obd_device *obd, struct mds_body *b,
struct inode *inode, int fid)
rsd->rsd_cap &= ~CAP_FS_MASK;
/* by now every fields other than groups in rsd have been granted */
+ ucred->luc_nid = peernid;
ucred->luc_uid = rsd->rsd_uid;
ucred->luc_gid = rsd->rsd_gid;
ucred->luc_fsuid = rsd->rsd_fsuid;
struct mea *mea = NULL;
int mea_size, update_mode;
int child_mode = LCK_PR;
+ struct lustre_id sid;
__u64 fid = 0;
ENTRY;
cleanup_phase = 1; /* parent dentry and lock */
- /* try to retrieve MEA data for this dir */
+ /* get parent id: ldlm lock on the parent protects ea */
+ rc = mds_read_inode_sid(obd, dparent->d_inode, &sid);
+ if (rc) {
+ CERROR("can't read parent inode id. ino(%lu) rc(%d)\n",
+ dparent->d_inode->i_ino, rc);
+ GOTO(cleanup, rc);
+ }
+ /* try to retrieve MEA data for this dir */
rc = mds_md_get_attr(obd, dparent->d_inode, &mea, &mea_size);
if (rc)
GOTO(cleanup, rc);
- if (mea != NULL) {
+ if (mea != NULL && mea->mea_count) {
/*
* dir is already splitted, check is requested filename should *
* live at this MDS or at another one.
else {
MD_COUNTER_INCREMENT(obd, create);
}
-
+
+ mds_inode2id(obd, &body->id1, inode, fid);
+ mds_update_inode_ids(obd, dchild->d_inode, handle, &body->id1, &sid);
+
if ((rec->ur_flags & MDS_OPEN_HAS_KEY) ||
mds->mds_crypto_type == MKS_TYPE) {
rc = mds_set_gskey(obd, handle, dchild->d_inode,
CERROR("error in set gs key rc %d\n", rc);
}
}
- if (ino) {
- rc = mds_update_inode_sid(obd, dchild->d_inode,
- handle, rec->ur_id2);
- if (rc) {
- CERROR("mds_update_inode_sid() failed, "
- "rc = %d\n", rc);
- }
- id_assign_fid(&body->id1, rec->ur_id2);
- /*
- * make sure, that fid is up-to-date.
- */
- mds_set_last_fid(obd, id_fid(rec->ur_id2));
- } else {
- rc = mds_set_inode_sid(obd, dchild->d_inode,
- handle, &body->id1, fid);
- if (rc) {
- CERROR("mds_set_inode_sid() failed, "
- "rc = %d\n", rc);
- }
- }
if (!(rec->ur_flags & O_EXCL)) { /* bug 3313 */
rc = fsfilt_commit(obd, dchild->d_inode->i_sb,
#define XATTR_LUSTRE_MDS_MEA_EA "mea"
#define XATTR_LUSTRE_MDS_MID_EA "mid"
#define XATTR_LUSTRE_MDS_SID_EA "sid"
+#define XATTR_LUSTRE_MDS_PID_EA "pid"
+#define XATTR_LUSTRE_MDS_KEY_EA "key"
static int mds_get_md_type(char *name)
{
RETURN(EA_MID);
if (!strcmp(name, XATTR_LUSTRE_MDS_SID_EA))
RETURN(EA_SID);
+ if (!strcmp(name, XATTR_LUSTRE_MDS_PID_EA))
+ RETURN(EA_PID);
+ if (!strcmp(name, XATTR_LUSTRE_MDS_KEY_EA))
+ RETURN(EA_KEY);
+
RETURN(0);
}
struct dentry *dparent = NULL;
struct mds_obd *mds = mds_req2mds(req);
struct obd_device *obd = req->rq_export->exp_obd;
+ struct mds_body *body = NULL;
struct dentry *dchild = NULL;
struct inode *dir = NULL;
void *handle = NULL;
struct dentry_params dp;
struct mea *mea = NULL;
int mea_size;
+ struct lustre_id sid;
__u64 fid;
ENTRY;
ldlm_lock_dump_handle(D_OTHER, lockh);
+ /* get parent id: ldlm lock on the parent protects ea */
+ rc = mds_read_inode_sid(obd, dir, &sid);
+ if (rc) {
+ CERROR("can't read parent id. ino(%lu) rc(%d)\n",
+ dir->i_ino, rc);
+ GOTO(cleanup, rc);
+ }
+
/* try to retrieve MEA data for this dir */
rc = mds_md_get_attr(obd, dparent->d_inode, &mea, &mea_size);
if (rc)
GOTO(cleanup, rc);
- if (mea != NULL) {
+ if (mea != NULL && mea->mea_count) {
/*
* dir is already splitted, check is requested filename should
* live at this MDS or at another one.
dp.p_fid = fid;
dp.p_group = mds->mds_num;
+ body = lustre_msg_buf(req->rq_repmsg, 0, sizeof(*body));
+
switch (type) {
case S_IFREG: {
handle = fsfilt_start(obd, dir, FSFILT_OP_CREATE, NULL);
GOTO(cleanup, rc);
}
- down(&dchild->d_inode->i_sem);
- if (dp.p_inum) {
- rc = mds_update_inode_sid(obd, dchild->d_inode,
- handle, rec->ur_id2);
- if (rc) {
- CERROR("mds_update_inode_sid() failed, inode %lu, "
- "rc %d\n", dchild->d_inode->i_ino, rc);
- }
-
- /*
- * make sure, that fid is up-to-date.
- */
- mds_set_last_fid(obd, id_fid(rec->ur_id2));
- } else {
- rc = mds_set_inode_sid(obd, dchild->d_inode,
- handle, NULL, fid);
- if (rc) {
- CERROR("mds_set_inode_sid() failed, inode %lu, "
- "rc %d\n", dchild->d_inode->i_ino, rc);
- }
- }
- up(&dchild->d_inode->i_sem);
-
- if (rc)
- GOTO(cleanup, rc);
-
if (rec->ur_eadata)
nstripes = *(u16 *)rec->ur_eadata;
} else if (!DENTRY_VALID(dchild)) {
/* inode will be created on another MDS */
struct obdo *oa = NULL;
- struct mds_body *body;
void *acl = NULL;
int acl_size;
oa->o_uid = current->fsuid;
oa->o_gid = (dir->i_mode & S_ISGID) ?
dir->i_gid : current->fsgid;
- oa->o_valid |= OBD_MD_FLTYPE|OBD_MD_FLUID|OBD_MD_FLGID;
-
+ /* transfer parent id to remote inode */
+ memcpy(obdo_id(oa), &sid, sizeof(sid));
+ oa->o_valid |= OBD_MD_FLTYPE | OBD_MD_FLUID |
+ OBD_MD_FLGID | OBD_MD_FLIFID;
+
CDEBUG(D_OTHER, "%s: create dir on MDS %u\n",
obd->obd_name, i);
}
/* fill reply */
- body = lustre_msg_buf(req->rq_repmsg,
- 0, sizeof(*body));
body->valid |= OBD_MD_FLID | OBD_MD_MDS | OBD_MD_FID;
obdo2id(&body->id1, oa);
} else if (dchild->d_inode) {
struct mds_export_data *med = &req->rq_export->u.eu_mds_data;
struct iattr iattr;
- struct mds_body *body;
struct inode *inode = dchild->d_inode;
created = 1;
if (id_ino(rec->ur_id2)) {
LASSERT(id_ino(rec->ur_id2) == inode->i_ino);
inode->i_generation = id_gen(rec->ur_id2);
-
- if (type != S_IFDIR) {
- down(&inode->i_sem);
- rc = mds_update_inode_sid(obd, inode,
- handle, rec->ur_id2);
- up(&inode->i_sem);
- if (rc) {
- CERROR("Can't update inode self id, "
- "rc = %d.\n", rc);
- }
-
- /*
- * make sure, that fid is up-to-date.
- */
- mds_set_last_fid(obd, id_fid(rec->ur_id2));
- }
-
/* dirtied and committed by the upcoming setattr. */
CDEBUG(D_INODE, "recreated ino %lu with gen %u\n",
inode->i_ino, inode->i_generation);
- } else {
- struct lustre_handle child_ino_lockh;
-
- CDEBUG(D_INODE, "created ino %lu with gen %x\n",
- inode->i_ino, inode->i_generation);
-
- if (type != S_IFDIR) {
- /*
- * allocate new id for @inode if it is not dir,
- * because for dir it was already done.
- */
- down(&inode->i_sem);
- rc = mds_set_inode_sid(obd, inode,
- handle, NULL, fid);
- up(&inode->i_sem);
- if (rc) {
- CERROR("mds_set_inode_sid() failed, "
- "inode %lu, rc %d\n", inode->i_ino,
- rc);
- }
- }
-
- if (rc == 0) {
- /*
- * the inode we were allocated may have just
- * been freed by an unlink operation. We take
- * this lock to synchronize against the matching
- * reply-ack-lock taken in unlink, to avoid
- * replay problems if this reply makes it out to
- * the client but the unlink's does not. See
- * bug 2029 for more detail.
- */
- rc = mds_lock_new_child(obd, inode, &child_ino_lockh);
- if (rc != ELDLM_OK) {
- CERROR("error locking for unlink/create sync: "
- "%d\n", rc);
- } else {
- ldlm_lock_decref(&child_ino_lockh, LCK_EX);
- }
- }
}
+ mds_inode2id(obd, &body->id1, dchild->d_inode, fid);
+ mds_update_inode_ids(obd, inode, handle, &body->id1, &sid);
rc = fsfilt_setattr(obd, dchild, handle, &iattr, 0);
if (rc)
}
}
- body = lustre_msg_buf(req->rq_repmsg, 0, sizeof(*body));
mds_pack_inode2body(obd, body, inode, 1);
mds_body_do_reverse_map(med, body);
}
CERROR("unlink in error path: %d\n", err);
break;
}
+ } else if (created) {
+ /* The inode we were allocated may have just been freed
+ * by an unlink operation. We take this lock to
+ * synchronize against the matching reply-ack-lock taken
+ * in unlink, to avoid replay problems if this reply
+ * makes it out to the client but the unlink's does not.
+ * See bug 2029 for more detail.*/
+ mds_lock_new_child(obd, dchild->d_inode, NULL);
} else {
rc = err;
}
struct dentry *de_new = NULL;
int cleanup_phase = 0;
int update_mode, rc = 0;
+ struct lustre_id ids[2]; /* sid, pid */
ENTRY;
/*
CDEBUG(D_OTHER, "%s: request to create name %s for "DLID4"\n",
obd->obd_name, rec->ur_tgt, OLID4(rec->ur_id1));
+ /* get parent id: ldlm lock on the parent protects ea */
+ rc = mds_read_inode_sid(obd, de_tgtdir->d_inode, &ids[1]);
+ if (rc)
+ GOTO(cleanup, rc);
+
/* first, lookup the target */
rc = mds_get_parent_child_locked(obd, mds, rec->ur_id2, parent_lockh,
&de_tgtdir, LCK_PW, MDS_INODELOCK_UPDATE,
rc = mds_add_local_dentry(rec, offset, req, rec->ur_id1,
de_tgtdir, de_new);
+ if (rc)
+ GOTO(cleanup, rc);
+ ids[0] = *(rec->ur_id1);
+ rc = obd_set_info(mds->mds_md_obd->u.lmv.tgts[id_group(rec->ur_id1)].ltd_exp,
+ strlen("ids"), "ids",
+ sizeof(struct lustre_id) * 2, ids);
+
EXIT;
cleanup:
struct llog_create_locks *lcl = NULL;
struct lov_mds_md *lmm = NULL;
int rc = 0, cleanup_phase = 0;
+ struct lustre_id ids[2]; /* sid, pid */
void *handle = NULL;
ENTRY;
body = lustre_msg_buf(req->rq_repmsg, 0, sizeof (*body));
LASSERT(body != NULL);
+ /* get new parent id: ldlm lock on the parent protects ea */
+ rc = mds_read_inode_sid(obd, de_tgtdir->d_inode, &ids[1]);
+ if (rc)
+ GOTO(cleanup, rc);
+
/* child i_alloc_sem protects orphan_dec_test && is_orphan race */
if (new_inode)
DOWN_READ_I_ALLOC_SEM(new_inode);
if (de_old->d_flags & DCACHE_CROSS_REF) {
struct lustre_id old_id;
+ struct obd_export *tgt_exp =
+ mds->mds_md_obd->u.lmv.tgts[de_old->d_mdsnum].ltd_exp;
+
mds_pack_dentry2id(obd, &old_id, de_old, 1);
rc = mds_add_local_dentry(rec, offset, req, &old_id,
de_tgtdir, de_new);
if (rc)
GOTO(cleanup, rc);
-
+
rc = mds_del_local_dentry(rec, offset, req, de_srcdir,
de_old);
+ if (rc)
+ GOTO(cleanup, rc);
+
+ ids[0] = old_id;
+ rc = obd_set_info(tgt_exp, strlen("ids"), "ids",
+ sizeof(struct lustre_id) * 2, ids);
+
GOTO(cleanup, rc);
}
}
}
+ if (rc == 0)
+ rc = mds_update_inode_ids(obd, de_old->d_inode,
+ handle, NULL, &ids[1]);
+
EXIT;
cleanup:
rc = mds_finish_transno(mds, (de_tgtdir ? de_tgtdir->d_inode : NULL),
rc = op->lop_setup(obd, llogs, index, disk_obd, count, logid);
if (ctxt && rc) {
obd->obd_llog_ctxt[index] = NULL;
+ llogs->llog_ctxt[index] = NULL;
OBD_FREE(ctxt, sizeof(*ctxt));
}
int mea_name2idx(struct mea *mea, char *name, int namelen)
{
unsigned int c;
-
- /* just to simplify caller code */
- if (mea == NULL)
- return 0;
-
- if (mea->mea_count == 0)
- return 0;
+
+ LASSERT(mea && mea->mea_count);
c = raw_name2idx(mea->mea_magic, mea->mea_count, name, namelen);
- LASSERT(c < mea->mea_count);
+
+ LASSERT(c < mea->mea_count);
return c;
}
#include <linux/lustre_smfs.h>
#include <linux/lustre_sec.h>
+#include <linux/lustre_audit.h>
#include "filter_internal.h"
/* Group 0 is no longer a legal group, to catch uninitialized IDs */
struct filter_obd *filter;
struct ldlm_resource *res;
struct dentry *dentry;
- obd_uid uid;
- obd_gid gid;
+ /*obd_uid uid;*/
+ /*obd_gid gid;*/
int rc;
ENTRY;
RETURN(rc);
}
+static int filter_set_info(struct obd_export *exp, __u32 keylen,
+ void *key, __u32 vallen, void *val)
+{
+ struct obd_device *obd;
+ int rc = -EINVAL;
+ ENTRY;
+
+ obd = class_exp2obd(exp);
+ if (obd == NULL) {
+ CDEBUG(D_IOCTL, "invalid client cookie "LPX64"\n",
+ exp->exp_handle.h_cookie);
+ RETURN(-EINVAL);
+ }
+
+ if (keylen == 8 && memcmp(key, "auditlog", 8) == 0) {
+
+ rc = fsfilt_set_info(obd, obd->u.filter.fo_sb, NULL,
+ 8, "auditlog", vallen, val);
+ RETURN(rc);
+ } else if (keylen == 5 && strcmp(key, "audit") == 0) {
+ //set audit for whole FS on OSS
+ struct audit_attr_msg * msg = val;
+
+ rc = fsfilt_set_info(obd, obd->u.filter.fo_sb, NULL,
+ 5, "audit", sizeof(msg->attr), &msg->attr);
+ RETURN(rc);
+ } else if (keylen == 9 && strcmp(key, "audit_obj") == 0) {
+ struct obdo * oa = val;
+ struct dentry * dentry;
+ __u64 mask = oa->o_fid;
+
+ dentry = filter_crow_object(obd, oa);
+ if (IS_ERR(dentry))
+ RETURN(PTR_ERR(dentry));
+
+ rc = fsfilt_set_info(obd, obd->u.filter.fo_sb, dentry->d_inode,
+ 5, "audit", sizeof(mask), &mask);
+
+ f_dput(dentry);
+
+ RETURN(rc);
+ }
+
+
+ if (rc)
+ CDEBUG(D_IOCTL, "invalid key\n");
+
+ RETURN(rc);
+}
+
static int filter_get_info(struct obd_export *exp, __u32 keylen,
void *key, __u32 *vallen, void *val)
{
/*Get log_context handle*/
unsigned long *llh_handle = val;
*vallen = sizeof(unsigned long);
- *llh_handle = (unsigned long)obd->obd_llog_ctxt[LLOG_REINT_ORIG_CTXT];
+ *llh_handle = (unsigned long)llog_get_context(&obd->obd_llogs,
+ LLOG_REINT_ORIG_CTXT);
RETURN(0);
}
if (keylen >= strlen("cache_sb") && memcmp(key, "cache_sb", 8) == 0) {
.o_owner = THIS_MODULE,
.o_attach = filter_attach,
.o_detach = filter_detach,
+ .o_set_info = filter_set_info,
.o_get_info = filter_get_info,
.o_setup = filter_setup,
.o_precleanup = filter_precleanup,
int filter_commitrw(int cmd, struct obd_export *exp, struct obdo *oa,
int objcount, struct obd_ioobj *obj, int niocount,
- struct niobuf_local *res, struct obd_trans_info *oti,int rc)
+ struct niobuf_local *res, struct obd_trans_info *oti,int ret)
{
- if (cmd == OBD_BRW_WRITE)
- return filter_commitrw_write(exp, oa, objcount, obj, niocount,
- res, oti, rc);
- if (cmd == OBD_BRW_READ)
- return filter_commitrw_read(exp, oa, objcount, obj, niocount,
- res, oti, rc);
- LBUG();
- return -EPROTO;
+ int rc = -EPROTO;
+ struct lustre_id *id = obdo_id(oa);
+ __u32 len = sizeof(*id);
+ struct inode * inode = res->dentry->d_inode;
+ struct super_block * sb = res->dentry->d_sb;
+ struct obd_device *obd = class_exp2obd(exp);
+
+ if (cmd == OBD_BRW_WRITE) {
+ rc = filter_commitrw_write(exp, oa, objcount, obj, niocount,
+ res, oti, ret);
+ fsfilt_set_info(obd, sb, inode, 10, "file_write", len, (void*)id);
+ }
+ else if (cmd == OBD_BRW_READ) {
+ rc = filter_commitrw_read(exp, oa, objcount, obj, niocount,
+ res, oti, ret);
+ fsfilt_set_info(obd, sb, inode, 9, "file_read", len, (void*)id);
+ }
+ else
+ LBUG();
+
+ return rc;
}
int filter_brw(int cmd, struct obd_export *exp, struct obdo *oa,
#include <linux/lustre_ha.h>
#include <linux/lprocfs_status.h>
#include <linux/lustre_log.h>
+#include <linux/lustre_audit.h>
#include <linux/lustre_gs.h>
#include "osc_internal.h"
}
}
- if (mode == LCK_PW) {
- rc = ldlm_lock_match(obd->obd_namespace, 0, &res_id, type,
- policy, LCK_PR, lockh);
- if (rc == 1) {
- rc = ldlm_cli_convert(lockh, mode, flags);
- if (!rc) {
- /* Update readers/writers accounting */
- ldlm_lock_addref(lockh, LCK_PW);
- ldlm_lock_decref(lockh, LCK_PR);
- osc_set_data_with_check(lockh, data);
- RETURN(ELDLM_OK);
- }
- /* If the conversion failed, we need to drop refcount
- on matched lock before we get new one */
- /* XXX Won't it save us some efforts if we cancel PR
- lock here? We are going to take PW lock anyway and it
- will invalidate PR lock */
- ldlm_lock_decref(lockh, LCK_PR);
- if (rc != EDEADLOCK) {
- RETURN(rc);
- }
- }
- }
-
- no_match:
+no_match:
if (*flags & LDLM_FL_HAS_INTENT) {
int size[2] = {0, sizeof(struct ldlm_request)};
out:
ptlrpc_req_finished(req);
RETURN(rc);
+ } else if (keylen >= strlen("client_nid") &&
+ strcmp(key, "client_nid") == 0) {
+ struct ptlrpc_connection * conn;
+ ptl_nid_t * nid = val;
+ *vallen = sizeof(*nid);
+
+ conn = class_exp2cliimp(exp)->imp_connection;
+ if (!conn)
+ RETURN(-ENOTCONN);
+
+ nid = &conn->c_peer.peer_id.nid;
+
+ RETURN(0);
}
RETURN(-EPROTO);
}
obd->obd_name, cl->cl_async);
RETURN(0);
}
+
+ if (keylen == 5 && strcmp(key, "audit") == 0) {
+ struct ptlrpc_request *req;
+ char *bufs[2] = {key, val};
+ int size[2] = {keylen, vallen};
+
+ req = ptlrpc_prep_req(class_exp2cliimp(exp), LUSTRE_OBD_VERSION,
+ OST_SET_INFO, 2, size, bufs);
+ if (req == NULL)
+ RETURN(-ENOMEM);
+
+ req->rq_replen = lustre_msg_size(0, size);
+ lustre_swab_reqbuf(req, 1, sizeof(struct audit_attr_msg),
+ lustre_swab_audit_attr);
+ rc = ptlrpc_queue_wait(req);
+
+ ptlrpc_req_finished(req);
+ RETURN(rc);
+ }
+
+ if (keylen == 9 && strcmp(key, "audit_obj") == 0) {
+ struct ptlrpc_request *req;
+ char *bufs[2] = {key, val};
+ int size[2] = {keylen, vallen};
+
+ req = ptlrpc_prep_req(class_exp2cliimp(exp), LUSTRE_OBD_VERSION,
+ OST_SET_INFO, 2, size, bufs);
+ if (req == NULL)
+ RETURN(-ENOMEM);
+
+ req->rq_replen = lustre_msg_size(0, size);
+ lustre_swab_reqbuf(req, 1, sizeof(struct obdo),
+ lustre_swab_obdo);
+ rc = ptlrpc_queue_wait(req);
+
+ ptlrpc_req_finished(req);
+ RETURN(rc);
+ }
+
+ if (keylen == 8 && memcmp(key, "auditlog", 8) == 0) {
+ struct ptlrpc_request *req;
+ char *bufs[2] = {key, val};
+ int size[2] = {keylen, vallen};
+
+ req = ptlrpc_prep_req(class_exp2cliimp(exp), LUSTRE_OBD_VERSION,
+ OST_SET_INFO, 2, size, bufs);
+ if (req == NULL)
+ RETURN(-ENOMEM);
+
+ req->rq_replen = lustre_msg_size(0, size);
+ lustre_swab_reqbuf(req, 1, sizeof(struct audit_msg),
+ lustre_swab_audit_msg);
+ rc = ptlrpc_queue_wait(req);
+
+ ptlrpc_req_finished(req);
+ RETURN(rc);
+ }
if (keylen == strlen("sec") &&
memcmp(key, "sec", keylen) == 0) {
#include <linux/lustre_commit_confd.h>
#include <libcfs/list.h>
#include <linux/lustre_sec.h>
+#include <linux/lustre_audit.h>
void oti_init(struct obd_trans_info *oti, struct ptlrpc_request *req)
{
RETURN(rc);
val = lustre_msg_buf(req->rq_reqmsg, 1, 0);
+
+ if (keylen == 8 && memcmp(key, "auditlog", 8) == 0) {
+ lustre_swab_reqbuf(req, 1, sizeof(struct audit_msg),
+ lustre_swab_audit_msg);
+ }
+ else if (keylen == 5 && strcmp(key, "audit") == 0) {
+ lustre_swab_reqbuf(req, 1, sizeof(struct audit_attr_msg),
+ lustre_swab_audit_attr);
+ }
+ else if (keylen == 9 && strcmp(key, "audit_obj") == 0) {
+ lustre_swab_reqbuf(req, 1, sizeof(struct obdo),
+ lustre_swab_obdo);
+ }
rc = obd_set_info(exp, keylen, key, req->rq_reqmsg->buflens[1], val);
req->rq_repmsg->status = 0;
{ MDS_SYNC, "mds_sync" },
{ MDS_DONE_WRITING, "mds_done_writing" },
{ MDS_ACCESS_CHECK, "mds_access_check"},
+ { MDS_PARSE_ID, "mds_parse_id" },
{ LDLM_ENQUEUE, "ldlm_enqueue" },
{ LDLM_CONVERT, "ldlm_convert" },
{ LDLM_CANCEL, "ldlm_cancel" },
#include <linux/obd_class.h>
#include <linux/lustre_net.h>
#include <linux/lustre_sec.h>
+#include <linux/lustre_audit.h>
#include <linux/fcntl.h>
#include <linux/posix_acl.h>
lustre_swab_lustre_fid(&id->li_fid);
}
+void lustre_swab_parseid_pkg (struct parseid_pkg *pkg)
+{
+ __swab32s(&pkg->pp_type);
+ __swab32s(&pkg->pp_rc);
+ lustre_swab_lustre_id(&pkg->pp_id1);
+ lustre_swab_lustre_id(&pkg->pp_id2);
+}
+
void lustre_swab_mds_status_req(struct mds_status_req *r)
{
__swab32s(&r->flags);
__swab64s(&b->size);
__swab64s(&b->blocks);
__swab64s(&b->valid);
+ __swab64s (&b->audit);
__swab32s(&b->mode);
__swab32s(&b->uid);
__swab32s(&b->gid);
__swab16s(&p->mrp_perm);
}
+void lustre_swab_audit_msg (struct audit_msg *r)
+{
+ lustre_swab_lustre_id(&r->id);
+ __swab32s (&r->code);
+ __swab32s (&r->result);
+ __swab32s (&r->uid);
+ __swab32s (&r->gid);
+ __swab64s (&r->nid);
+}
+
+void lustre_swab_audit_attr (struct audit_attr_msg *r)
+{
+ lustre_swab_lustre_id(&r->id);
+ __swab64s (&r->attr);
+}
+
/* no one calls this */
int llog_log_swabbed(struct llog_log_hdr *hdr)
{
EXPORT_SYMBOL(lustre_swab_lustre_id);
EXPORT_SYMBOL(lustre_swab_lustre_stc);
EXPORT_SYMBOL(lustre_swab_lustre_fid);
+EXPORT_SYMBOL(lustre_swab_parseid_pkg);
+EXPORT_SYMBOL(lustre_swab_audit_msg);
+EXPORT_SYMBOL(lustre_swab_audit_attr);
EXPORT_SYMBOL(lustre_swab_mds_status_req);
EXPORT_SYMBOL(lustre_swab_mds_secdesc);
EXPORT_SYMBOL(lustre_swab_remote_perm);
smfs-objs := super.o inode.o cache.o dir.o fsfilt.o ioctl.o
smfs-objs += sysctl.o file.o symlink.o smfs_lib.o smfs_llog.o
smfs-objs += kml.o mds_kml.o ost_kml.o cache_space.o
+smfs-objs += audit.o audit_mds.o audit_ost.o audit_transfer.o
@SNAPFS_TRUE@smfs-objs += smfs_cow.o
@INCLUDE_RULES@
--- /dev/null
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * lustre/smfs/audit_mds.c
+ * Lustre filesystem audit part for MDS
+ *
+ * Copyright (C) 2004 Cluster File Systems, Inc.
+ *
+ * This file is part of Lustre, http://www.lustre.org.
+ *
+ * Lustre is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * Lustre is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Lustre; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
+
+#define DEBUG_SUBSYSTEM S_SM
+
+#include <linux/kmod.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/obd_class.h>
+#include <linux/obd_support.h>
+#include <linux/lustre_lib.h>
+#include <linux/lustre_idl.h>
+#include <linux/lustre_fsfilt.h>
+#include <linux/lustre_smfs.h>
+#include <linux/lustre_audit.h>
+#include <linux/lustre_log.h>
+#include "smfs_internal.h"
+
+static audit_op hook2audit(hook_op hook)
+{
+ audit_op opcode = AUDIT_NONE;
+
+ switch (hook)
+ {
+ case HOOK_CREATE:
+ case HOOK_SYMLINK:
+ case HOOK_MKDIR:
+ case HOOK_MKNOD:
+ return AUDIT_CREATE;
+
+ case HOOK_LINK:
+ return AUDIT_LINK;
+
+ case HOOK_RMDIR:
+ case HOOK_UNLINK:
+ return AUDIT_UNLINK;
+
+ case HOOK_READLINK:
+ return AUDIT_READLINK;
+
+ case HOOK_RENAME:
+ return AUDIT_RENAME;
+
+ case HOOK_SETATTR:
+ case HOOK_F_SETATTR:
+ return AUDIT_SETATTR;
+
+ case HOOK_SI_WRITE:
+ return AUDIT_WRITE;
+
+ case HOOK_SI_READ:
+ return AUDIT_READ;
+
+ case HOOK_READDIR:
+ return AUDIT_READDIR;
+
+ default:
+ return AUDIT_NONE;
+ }
+
+ return opcode;
+}
+
+struct inode * get_inode_from_hook(hook_op hook, void * msg)
+{
+ struct inode * inode;
+
+ switch (hook)
+ {
+ case HOOK_LINK:
+ {
+ struct hook_link_msg * m = msg;
+ inode = m->dentry->d_inode;
+ break;
+ }
+ case HOOK_UNLINK:
+ case HOOK_RMDIR:
+ {
+ struct hook_unlink_msg * m = msg;
+ inode = m->dentry->d_inode;
+ break;
+ }
+ case HOOK_READLINK:
+ {
+ struct hook_symlink_msg * m = msg;
+ inode = m->dentry->d_inode;
+ break;
+ }
+ case HOOK_RENAME:
+ {
+ struct hook_rename_msg * m = msg;
+ inode = m->dentry->d_inode;
+ break;
+ }
+ default:
+ inode = NULL;
+ }
+
+ return inode;
+}
+
+int smfs_get_audit(struct super_block * sb, struct inode * parent,
+ struct inode * inode, __u64 * mask)
+{
+ struct smfs_super_info * smb = S2SMI(sb);
+ struct fsfilt_operations *fsfilt = smb->sm_fsfilt;
+ int rc;
+ struct audit_priv * priv = NULL;
+
+ ENTRY;
+
+ if (!SMFS_IS(smb->plg_flags, SMFS_PLG_AUDIT))
+ RETURN(-EINVAL);
+
+ priv = smfs_get_plg_priv(S2SMI(sb), SMFS_PLG_AUDIT);
+
+ //omit __iopen__ dir
+ if (parent->i_ino == SMFS_IOPEN_INO)
+ RETURN(-ENOENT);
+
+ if (!priv)
+ RETURN(-ENOENT);
+
+ if (IS_AUDIT(priv->a_mask)) {
+ (*mask) = priv->a_mask;
+ RETURN(0);
+ }
+ //get inode audit EA
+ rc = fsfilt->fs_get_xattr(parent, AUDIT_ATTR_EA,
+ mask, sizeof(*mask));
+ if (rc <= 0)
+ RETURN(-ENODATA);
+
+ //check if parent has audit
+ if (IS_AUDIT(*mask))
+ RETURN(0);
+
+ if (!inode)
+ RETURN(-ENOENT);
+
+ rc = fsfilt->fs_get_xattr(inode, AUDIT_ATTR_EA,
+ mask, sizeof(*mask));
+ if (rc <= 0)
+ RETURN(-ENODATA);
+
+ if (IS_AUDIT(*mask))
+ RETURN(0);
+
+ RETURN(-ENODATA);
+}
+
+int smfs_audit_check(struct inode * parent, hook_op hook, int ret,
+ struct audit_priv * priv, void * msg)
+{
+ audit_op code;
+ __u64 mask = 0;
+ int rc = 0;
+
+ ENTRY;
+
+ if (hook == HOOK_SPECIAL) {
+ struct audit_info * info = msg;
+ code = info->m.code;
+ }
+ else
+ code = hook2audit(hook);
+
+ rc = smfs_get_audit(parent->i_sb, parent,
+ get_inode_from_hook(hook, msg),
+ &mask);
+ if (rc < 0)
+ RETURN(0);
+ //should only failures be audited?
+ if (!ret && IS_AUDIT_OP(mask, AUDIT_FAIL))
+ RETURN(0);
+
+ //check audit mask
+ RETURN(IS_AUDIT_OP(mask, code));
+}
+
+static int smfs_set_fs_audit (struct super_block * sb, __u64 *mask)
+{
+ struct smfs_super_info * smb = S2SMI(sb);
+ struct fsfilt_operations * fsfilt = smb->sm_fsfilt;
+ int rc = 0;
+ loff_t off = 0;
+ struct file * f = NULL;
+ struct audit_priv *priv;
+ struct lvfs_run_ctxt * ctxt, saved;
+ ENTRY;
+
+ ctxt = &smb->smsi_exp->exp_obd->obd_lvfs_ctxt;
+ push_ctxt(&saved, ctxt, NULL);
+ priv = smfs_get_plg_priv(smb, SMFS_PLG_AUDIT);
+ if(!priv) {
+ CERROR("error updating audit setting: rc = %d\n", rc);
+ RETURN(-EINVAL);
+ }
+
+ push_ctxt(&saved, ctxt, NULL);
+
+ f = filp_open(AUDIT_ATTR_FILE, O_RDWR|O_CREAT, 0600);
+ if (IS_ERR(f)) {
+ CERROR("cannot get audit_setting file\n");
+ rc = -EINVAL;
+ goto exit;
+ }
+
+ rc = fsfilt->fs_write_record(f, mask, sizeof(*mask), &off, 1);
+ if (rc) {
+ CERROR("error writting audit setting: rc = %d\n", rc);
+ goto exit;
+ }
+
+ priv->a_mask = (*mask);
+
+exit:
+ if (f)
+ filp_close(f, 0);
+
+ pop_ctxt(&saved, ctxt, NULL);
+
+ RETURN (rc);
+}
+
+//set audit attributes for directory/file
+int smfs_set_audit(struct super_block * sb, struct inode * inode,
+ __u64 * mask)
+{
+ void * handle = NULL;
+ struct fsfilt_operations * fsfilt = S2SMI(sb)->sm_fsfilt;
+ int rc = 0;
+
+ ENTRY;
+
+ if (IS_AUDIT_OP((*mask), AUDIT_FS))
+ return smfs_set_fs_audit(sb, mask);
+
+ LASSERT(inode);
+
+ handle = fsfilt->fs_start(inode, FSFILT_OP_SETATTR, NULL, 0);
+ if (IS_ERR(handle))
+ RETURN(PTR_ERR(handle));
+
+ if (fsfilt->fs_set_xattr)
+ rc = fsfilt->fs_set_xattr(inode, handle, AUDIT_ATTR_EA,
+ mask, sizeof(*mask));
+
+ fsfilt->fs_commit(inode->i_sb, inode, handle, 1);
+ RETURN(rc);
+
+}
+
+static int smfs_audit_post_op(hook_op code, struct inode * inode, void * msg,
+ int ret, void * arg)
+{
+ int rc = 0, len;
+ char * buffer = NULL;
+ struct audit_record * rec = NULL;
+ struct llog_rec_hdr * llh;
+ struct timeval cur_time;
+ struct audit_priv * priv = arg;
+ audit_get_op * handler = priv->audit_get_record;
+
+ //check that we are in lustre ctxt
+ if (!SMFS_IS(I2SMI(inode)->smi_flags, SMFS_PLG_AUDIT))
+ return 0;
+
+ if (!handler || !handler[code])
+ return 0;
+
+ if (smfs_audit_check(inode, code, ret, priv, msg) == 0)
+ return 0;
+
+ ENTRY;
+
+ do_gettimeofday(&cur_time);
+
+ OBD_ALLOC(buffer, PAGE_SIZE);
+ if (!buffer)
+ RETURN(-ENOMEM);
+
+ llh = (void*)buffer;
+ //fill common fields
+ rec = (void*)(buffer + sizeof(*llh));
+
+ rec->result = ret;
+ rec->uid = current->uid;
+ rec->gid = current->gid;
+ rec->nid = current->user->nid;
+ rec->time = cur_time.tv_sec * USEC_PER_SEC + cur_time.tv_usec;
+
+
+ len = handler[code](inode, msg, priv, (char*)rec,
+ &llh->lrh_type);
+
+ llh->lrh_len = size_round(len);
+
+ rc = llog_cat_add_rec(priv->audit_ctxt->loc_handle, llh, NULL,
+ (void*)rec, NULL, NULL);
+ if (rc != 0) {
+ CERROR("Error adding audit record: %d\n", rc);
+ rc= -EINVAL;
+ } else {
+ audit_notify(priv->audit_ctxt->loc_handle, priv->au_id2name);
+ }
+
+ OBD_FREE(buffer, PAGE_SIZE);
+
+ RETURN(rc);
+}
+
+/* Helpers */
+static int smfs_trans_audit (struct super_block *sb, void *arg,
+ struct audit_priv * priv)
+{
+ int size = 1; //one record in log per operation.
+
+ return size;
+}
+
+extern int mds_alloc_inode_ids(struct obd_device *, struct inode *,
+ void *, struct lustre_id *, struct lustre_id *);
+
+static int smfs_start_audit(struct super_block *sb, void *arg,
+ struct audit_priv * audit_p)
+{
+ struct smfs_super_info * smb = S2SMI(sb);
+ struct fsfilt_operations * fsfilt = smb->sm_fsfilt;
+ struct obd_device *obd = arg;
+ struct file * f;
+ int rc = 0;
+
+ ENTRY;
+
+ //is plugin already activated
+ if (SMFS_IS(smb->plg_flags, SMFS_PLG_AUDIT))
+ RETURN(0);
+
+ rc = audit_start_transferd();
+ if (rc) {
+ CERROR("can't start audit transfer daemon. rc:%d\n", rc);
+ RETURN(rc);
+ }
+
+ if (obd && obd->obd_type && obd->obd_type->typ_name) {
+ if (!strcmp(obd->obd_type->typ_name, "mds")) {
+ CDEBUG(D_INODE, "Setup MDS audit handler\n");
+ audit_mds_setup(obd, sb, audit_p);
+ }
+ else if (!strcmp(obd->obd_type->typ_name, "obdfilter")) {
+ CDEBUG(D_INODE, "Setup OST audit handler\n");
+ audit_ost_setup(obd, sb, audit_p);
+ }
+ else {
+ CDEBUG(D_INODE, "Unknown obd type %s\n",
+ obd->obd_type->typ_name);
+ RETURN(0);
+ }
+ }
+ //read fs audit settings if any
+ audit_p->a_mask = AUDIT_OFF;
+
+ f = filp_open(AUDIT_ATTR_FILE, O_RDONLY, 0644);
+ if (!IS_ERR(f)) {
+ loff_t off = 0;
+ rc = fsfilt->fs_read_record(f, &audit_p->a_mask,
+ sizeof(audit_p->a_mask), &off);
+ if (rc) {
+ CERROR("error reading audit setting: rc = %d\n", rc);
+ }
+ filp_close(f, 0);
+ }
+
+ SMFS_SET(smb->plg_flags, SMFS_PLG_AUDIT);
+
+ RETURN(0);
+}
+
+int smfs_stop_audit(struct super_block *sb, void *arg,
+ struct audit_priv * audit_p)
+{
+ struct smfs_super_info * smb = S2SMI(sb);
+ struct llog_ctxt *ctxt = audit_p->audit_ctxt;
+ ENTRY;
+
+ if (!SMFS_IS(smb->plg_flags, SMFS_PLG_AUDIT))
+ RETURN(0);
+
+ audit_stop_transferd();
+
+ SMFS_CLEAR(smb->plg_flags, SMFS_PLG_AUDIT);
+
+ if (ctxt->loc_llogs)
+ ctxt->loc_llogs->llog_ctxt[LLOG_AUDIT_ORIG_CTXT] = NULL;
+
+ llog_catalog_cleanup(ctxt);
+ OBD_FREE(ctxt, sizeof(*ctxt));
+ audit_p->audit_ctxt = NULL;
+
+ RETURN(0);
+}
+
+int smfs_audit_set_info(struct super_block *sb, void *arg,
+ struct audit_priv *priv) {
+ struct plg_info_msg * msg = arg;
+ if (KEY_IS(msg->key, "id2name")) {
+ priv->au_id2name = msg->val;
+ }
+
+ return 0;
+}
+
+typedef int (*audit_helper)(struct super_block * sb, void *msg, struct audit_priv *);
+static audit_helper smfs_audit_helpers[PLG_HELPER_MAX] = {
+ [PLG_START] smfs_start_audit,
+ [PLG_STOP] smfs_stop_audit,
+ [PLG_TRANS_SIZE] smfs_trans_audit,
+ [PLG_TEST_INODE] NULL,
+ [PLG_SET_INODE] NULL,
+ [PLG_SET_INFO] smfs_audit_set_info,
+};
+
+static int smfs_audit_help_op(int code, struct super_block * sb,
+ void * arg, void * priv)
+{
+ int rc = 0;
+
+ if (smfs_audit_helpers[code])
+ rc = smfs_audit_helpers[code](sb, arg, (struct audit_priv *) priv);
+ return rc;
+}
+
+static int smfs_exit_audit(struct super_block *sb,
+ void * arg)
+{
+ struct audit_priv * priv = arg;
+ struct smfs_plugin * plg;
+ ENTRY;
+
+ plg = smfs_deregister_plugin(sb, SMFS_PLG_AUDIT);
+ if (plg)
+ OBD_FREE(plg, sizeof(*plg));
+ else
+ CERROR("Cannot find AUDIT plugin while unregistering\n");
+
+ if (priv)
+ OBD_FREE(priv, sizeof(*priv));
+
+ RETURN(0);
+}
+
+int smfs_init_audit(struct super_block *sb)
+{
+ int rc = 0;
+ struct audit_priv * priv = NULL;
+ struct smfs_plugin * plg = NULL;
+
+ ENTRY;
+
+ OBD_ALLOC(plg, sizeof(*plg));
+ if (!plg) {
+ rc = -ENOMEM;
+ goto exit;
+ }
+
+ plg->plg_type = SMFS_PLG_AUDIT;
+ plg->plg_post_op = &smfs_audit_post_op;
+ plg->plg_helper = &smfs_audit_help_op;
+ plg->plg_exit = &smfs_exit_audit;
+
+ OBD_ALLOC(priv, sizeof(*priv));
+ if (!priv) {
+ rc = -ENOMEM;
+ goto exit;
+ }
+
+ plg->plg_private = priv;
+ rc = smfs_register_plugin(sb, plg);
+ if (!rc)
+ RETURN(0);
+exit:
+ if (priv)
+ OBD_FREE(priv, sizeof(*priv));
+
+ if (plg)
+ OBD_FREE(plg, sizeof(*plg));
+
+ RETURN(rc);
+
+}
+
+int audit_client_log(struct super_block * sb, struct audit_msg * msg)
+{
+ struct smfs_super_info * smb = S2SMI(sb);
+ char *buffer = NULL, *pbuf = NULL;
+ struct audit_record * rec = NULL;
+ struct llog_rec_hdr * llh;
+ struct llog_handle * ll_handle = NULL;
+ int len = 0, rc = 0;
+ struct timeval cur_time;
+ //char name[32];
+ struct audit_priv * priv;
+
+ do_gettimeofday(&cur_time);
+
+ priv = smfs_get_plg_priv(smb, SMFS_PLG_AUDIT);
+ if (!priv)
+ RETURN(-EINVAL);
+
+ ll_handle = priv->audit_ctxt->loc_handle;
+
+ OBD_ALLOC(buffer, PAGE_SIZE);
+ if (!buffer)
+ RETURN(-ENOMEM);
+
+ llh = (void*)buffer;
+ llh->lrh_type = SMFS_AUDIT_GEN_REC;
+ pbuf = buffer + sizeof(*llh);
+
+ //fill common fields
+ rec = (void*)(pbuf);
+ rec->opcode = msg->code;
+ rec->result = msg->result;
+ rec->uid = msg->uid;
+ rec->gid = msg->gid;
+ rec->nid = msg->nid;
+ rec->time = cur_time.tv_sec * USEC_PER_SEC + cur_time.tv_usec;
+ pbuf += sizeof(*rec);
+
+ switch (msg->code) {
+ case AUDIT_READ:
+ case AUDIT_WRITE:
+ case AUDIT_MMAP:
+ case AUDIT_OPEN:
+ case AUDIT_STAT:
+ len = audit_rec_from_id(&pbuf, &msg->id);
+ break;
+ default:
+ CERROR("Unknown code %i in audit_msg\n", msg->code);
+ }
+
+ llh->lrh_len = size_round(len);
+
+ rc = llog_cat_add_rec(ll_handle, llh, NULL, (void*)rec, NULL, NULL);
+ if (rc != 0) {
+ CERROR("Error adding audit client record: %d\n", rc);
+ rc= -EINVAL;
+ } else {
+ audit_notify(ll_handle, priv->au_id2name);
+ }
+
+ OBD_FREE(buffer, PAGE_SIZE);
+ return rc;
+}
+
--- /dev/null
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * lustre/smfs/audit_mds.c
+ * Lustre filesystem audit part for MDS
+ *
+ * Copyright (C) 2004 Cluster File Systems, Inc.
+ *
+ * This file is part of Lustre, http://www.lustre.org.
+ *
+ * Lustre is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * Lustre is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Lustre; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
+
+#define DEBUG_SUBSYSTEM S_SM
+
+#include <linux/kmod.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/obd_class.h>
+#include <linux/obd.h>
+#include <linux/lustre_lib.h>
+#include <linux/lustre_log.h>
+#include <linux/lustre_fsfilt.h>
+#include <linux/lustre_smfs.h>
+#include <linux/lustre_audit.h>
+#include "smfs_internal.h"
+
+int static audit_mds_create_rec(struct inode * parent, void * arg,
+ struct audit_priv * priv, char * buffer,
+ __u32 * type)
+{
+ struct hook_msg * msg = arg;
+ struct audit_record * rec = (void*)buffer;
+ char * pbuf = buffer + sizeof(*rec);
+ struct inode * inode = msg->dentry->d_inode;
+ int len = sizeof(*rec);
+
+ rec->opcode = AUDIT_CREATE;
+ if (priv->result == 0) { //successfull operation
+ len += audit_fill_id_rec(&pbuf, inode);
+ *type = SMFS_AUDIT_GEN_REC;
+ }
+ else { //failed operation
+ len += audit_fill_id_rec(&pbuf, parent);
+ len += audit_fill_name_rec(&pbuf, msg->dentry->d_name.name,
+ msg->dentry->d_name.len);
+
+ *type = SMFS_AUDIT_NAME_REC;
+ }
+ return len;
+}
+
+int static audit_mds_link_rec(struct inode * parent, void * arg,
+ struct audit_priv * priv, char * buffer,
+ __u32 *type)
+{
+ struct hook_link_msg * msg = arg;
+ struct audit_record * rec = (void*)buffer;
+ char * pbuf = buffer + sizeof(*rec);
+ struct inode * inode = msg->dentry->d_inode;
+ int len = sizeof(*rec);
+
+ rec->opcode = AUDIT_LINK;
+
+ /* these things will be needed always */
+ len += audit_fill_id_rec(&pbuf, inode);
+ len += audit_fill_id_rec(&pbuf, parent);
+ len += audit_fill_name_rec(&pbuf, msg->dentry->d_name.name,
+ msg->dentry->d_name.len);
+ *type = SMFS_AUDIT_NAME_REC;
+
+ return len;
+}
+
+int static audit_mds_unlink_rec(struct inode * parent, void * arg,
+ struct audit_priv * priv, char * buffer,
+ __u32 *type)
+{
+ struct hook_unlink_msg * msg = arg;
+ struct inode * inode = msg->dentry->d_inode;
+ struct audit_record * rec = (void*)buffer;
+ char * pbuf = buffer + sizeof(*rec);
+ int len = sizeof(*rec);
+
+ rec->opcode = AUDIT_UNLINK;
+
+
+ len += audit_fill_id_rec(&pbuf, inode);
+ len += audit_fill_id_rec(&pbuf, parent);
+ if (priv->result == 0) {
+ len += audit_fill_name_rec(&pbuf, msg->dentry->d_name.name,
+ msg->dentry->d_name.len);
+ *type = SMFS_AUDIT_NAME_REC;
+ } else {
+ //in case of failure name shouldn't be saved
+ *type = SMFS_AUDIT_GEN_REC;
+ }
+
+ return len;
+}
+
+int static audit_mds_rename_rec(struct inode * parent, void * arg,
+ struct audit_priv * priv, char * buffer,
+ __u32 *type)
+{
+ struct hook_rename_msg * msg = arg;
+ struct inode * inode = msg->dentry->d_inode;
+ struct audit_record * rec = (void*)buffer;
+ char * pbuf = buffer + sizeof(*rec);
+ int len = sizeof(*rec);
+
+ rec->opcode = AUDIT_RENAME;
+
+ len += audit_fill_id_rec(&pbuf, inode);
+ if (priv->result == 0) {
+ len += audit_fill_id_rec(&pbuf, msg->old_dir);
+ len += audit_fill_name_rec(&pbuf, msg->dentry->d_name.name,
+ msg->dentry->d_name.len);
+ } else {
+ len += audit_fill_id_rec(&pbuf, msg->new_dir);
+ len += audit_fill_name_rec(&pbuf, msg->new_dentry->d_name.name,
+ msg->new_dentry->d_name.len);
+ }
+
+ *type = SMFS_AUDIT_NAME_REC;
+
+ return len;
+
+}
+
+int static audit_mds_setattr_rec(struct inode * inode, void * arg,
+ struct audit_priv * priv, char * buffer,
+ __u32 *type)
+{
+ //struct hook_attr_msg * msg = arg;
+ struct audit_record * rec = (void*)buffer;
+ char * pbuf = buffer + sizeof(*rec);
+ int len = sizeof(*rec);
+
+ rec->opcode = AUDIT_SETATTR;
+ len += audit_fill_id_rec(&pbuf, inode);
+ *type = SMFS_AUDIT_GEN_REC;
+
+ return len;
+}
+
+int static audit_mds_readlink_rec(struct inode * inode, void * arg,
+ struct audit_priv * priv, char * buffer,
+ __u32 *type)
+{
+ //struct hook_symlink_msg * msg = arg;
+ struct audit_record * rec = (void*)buffer;
+ char * pbuf = buffer + sizeof(*rec);
+ int len = sizeof(*rec);
+
+ rec->opcode = AUDIT_READLINK;
+ len += audit_fill_id_rec(&pbuf, inode);
+ *type = SMFS_AUDIT_GEN_REC;
+
+ return len;
+}
+
+int static audit_mds_readdir_rec(struct inode * inode, void * arg,
+ struct audit_priv * priv, char * buffer,
+ __u32 *type)
+{
+ struct audit_record * rec = (void*)buffer;
+ char * pbuf = buffer + sizeof(*rec);
+ int len = sizeof(*rec);
+
+ rec->opcode = AUDIT_READDIR;
+ len += audit_fill_id_rec(&pbuf, inode);
+ *type = SMFS_AUDIT_GEN_REC;
+
+ return len;
+}
+
+/* for special records from failed auth and open/stat*/
+int audit_mds_special_rec(struct inode * inode, void * arg,
+ struct audit_priv * priv, char *buffer,
+ __u32 * type)
+{
+ struct audit_info * info = arg;
+ struct audit_msg * msg = &info->m;
+ struct audit_record * rec = (void*)buffer;
+ char * pbuf = buffer + sizeof(*rec);
+ int len = sizeof(*rec);
+
+ //rewrite some fields
+ rec->opcode = msg->code;
+ rec->result = msg->result;
+ rec->uid = msg->uid;
+ rec->gid = msg->gid;
+ rec->nid = msg->nid;
+
+ len += audit_rec_from_id(&pbuf, &msg->id);
+ switch (rec->opcode)
+ {
+ case AUDIT_OPEN:
+ case AUDIT_CREATE:
+ if (info->name && info->namelen > 0) {
+ len += audit_fill_name_rec(&pbuf,
+ info->name,
+ info->namelen);
+ *type = SMFS_AUDIT_NAME_REC;
+ break;
+ }
+ default:
+ *type = SMFS_AUDIT_GEN_REC;
+ }
+
+ return len;
+}
+
+static audit_get_op audit_mds_record[HOOK_MAX] = {
+ [HOOK_CREATE] audit_mds_create_rec,
+ [HOOK_LINK] audit_mds_link_rec,
+ [HOOK_UNLINK] audit_mds_unlink_rec,
+ [HOOK_SYMLINK] audit_mds_create_rec,
+ [HOOK_READLINK] audit_mds_readlink_rec,
+ [HOOK_MKDIR] audit_mds_create_rec,
+ [HOOK_RMDIR] audit_mds_unlink_rec,
+ [HOOK_MKNOD] audit_mds_create_rec,
+ [HOOK_RENAME] audit_mds_rename_rec,
+ [HOOK_SETATTR] audit_mds_setattr_rec,
+ [HOOK_F_SETATTR] audit_mds_setattr_rec,
+ [HOOK_SPECIAL] audit_mds_special_rec,
+ [HOOK_READDIR] audit_mds_readdir_rec,
+};
+
+int audit_mds_setup(struct obd_device * obd, struct super_block *sb,
+ struct audit_priv *priv)
+{
+ int rc;
+ struct smfs_super_info * smb = S2SMI(sb);
+ struct llog_ctxt **ctxt = &priv->audit_ctxt;
+
+ //this will do OBD_ALLOC() for ctxt
+ rc = llog_catalog_setup(ctxt, AUDIT_MDS_NAME, smb->smsi_exp,
+ smb->smsi_ctxt, smb->sm_fsfilt,
+ smb->smsi_logs_dir, smb->smsi_objects_dir);
+
+ /* export audit llog ctxt */
+ if (*ctxt) {
+ (*ctxt)->loc_idx = LLOG_AUDIT_ORIG_CTXT;
+ (*ctxt)->loc_obd = obd;
+ (*ctxt)->loc_llogs = &obd->obd_llogs;
+ (*ctxt)->loc_llogs->llog_ctxt[LLOG_AUDIT_ORIG_CTXT] = *ctxt;
+ }
+ priv->audit_get_record = &audit_mds_record;
+ return 0;
+}
--- /dev/null
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * lustre/smfs/audit_mds.c
+ * Lustre filesystem audit part for MDS
+ *
+ * Copyright (C) 2004 Cluster File Systems, Inc.
+ *
+ * This file is part of Lustre, http://www.lustre.org.
+ *
+ * Lustre is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * Lustre is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Lustre; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
+
+#define DEBUG_SUBSYSTEM S_SM
+
+#include <linux/kmod.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/obd_class.h>
+#include <linux/obd.h>
+#include <linux/lustre_lib.h>
+#include <linux/lustre_log.h>
+#include <linux/lustre_fsfilt.h>
+#include <linux/lustre_smfs.h>
+#include <linux/lustre_audit.h>
+#include "smfs_internal.h"
+
+static int audit_ost_create_rec(struct inode * parent, void * arg,
+ struct audit_priv * priv, char * buffer,
+ __u32 * type)
+{
+ struct hook_msg * msg = arg;
+ struct audit_record * rec = (void*)buffer;
+ char * pbuf = buffer + sizeof(*rec);
+ struct inode * inode = msg->dentry->d_inode;
+ int len = sizeof(*rec);
+
+ //TODO: useless until lustre inode id is in EA
+ rec->opcode = AUDIT_CREATE;
+ len += audit_fill_id_rec(&pbuf, inode);
+ *type = SMFS_AUDIT_GEN_REC;
+ return len;
+}
+
+static int audit_ost_unlink_rec(struct inode * parent, void * arg,
+ struct audit_priv * priv, char * buffer,
+ __u32 *type)
+{
+ struct hook_unlink_msg * msg = arg;
+ struct inode * inode = msg->dentry->d_inode;
+ struct audit_record * rec = (void*)buffer;
+ char * pbuf = buffer + sizeof(*rec);
+ int len = sizeof(*rec);
+
+ //TODO: useless until lustre inode id is in EA
+ rec->opcode = AUDIT_UNLINK;
+ len += audit_fill_id_rec(&pbuf, inode);
+ len += audit_fill_id_rec(&pbuf, parent);
+ *type = SMFS_AUDIT_GEN_REC;
+
+ return len;
+}
+
+int static audit_ost_setattr_rec(struct inode * inode, void * arg,
+ struct audit_priv * priv, char * buffer,
+ __u32 *type)
+{
+ //struct hook_attr_msg * msg = arg;
+ struct audit_record * rec = (void*)buffer;
+ char * pbuf = buffer + sizeof(*rec);
+ int len = sizeof(*rec);
+
+ //TODO: useless until lustre inode id is in EA
+ rec->opcode = AUDIT_SETATTR;
+ len += audit_fill_id_rec(&pbuf, inode);
+ *type = SMFS_AUDIT_GEN_REC;
+
+ return len;
+}
+
+int static audit_ost_rw_rec(struct inode * inode, void * arg,
+ struct audit_priv * priv, char * buffer,
+ __u32 * type)
+{
+ struct hook_rw_msg * msg = arg;
+ struct audit_record * rec = (void*)buffer;
+ char * pbuf = buffer + sizeof(*rec);
+ int len = sizeof(*rec);
+
+ rec->opcode = msg->write ? AUDIT_WRITE : AUDIT_READ;
+ len += audit_rec_from_id(&pbuf, msg->id);
+ *type = SMFS_AUDIT_GEN_REC;
+
+ return len;
+}
+
+static audit_get_op audit_ost_record[HOOK_MAX] = {
+ [HOOK_SI_READ] audit_ost_rw_rec,
+ [HOOK_SI_WRITE] audit_ost_rw_rec,
+ [HOOK_CREATE] audit_ost_create_rec,
+ [HOOK_UNLINK] audit_ost_unlink_rec,
+ [HOOK_SETATTR] audit_ost_setattr_rec,
+ [HOOK_F_SETATTR] audit_ost_setattr_rec
+};
+
+int audit_ost_setup(struct obd_device * obd, struct super_block *sb,
+ struct audit_priv *priv)
+{
+ int rc;
+ struct smfs_super_info * smb = S2SMI(sb);
+ struct llog_ctxt **ctxt = &priv->audit_ctxt;
+
+ //this will do OBD_ALLOC() for ctxt
+ rc = llog_catalog_setup(ctxt, AUDIT_OST_NAME, smb->smsi_exp,
+ smb->smsi_ctxt, smb->sm_fsfilt,
+ smb->smsi_logs_dir, smb->smsi_objects_dir);
+
+ /* export audit llog ctxt */
+ if (*ctxt) {
+ (*ctxt)->loc_idx = LLOG_AUDIT_ORIG_CTXT;
+ (*ctxt)->loc_obd = obd;
+ (*ctxt)->loc_llogs = &obd->obd_llogs;
+ (*ctxt)->loc_llogs->llog_ctxt[LLOG_AUDIT_ORIG_CTXT] = *ctxt;
+ }
+
+ priv->audit_get_record = audit_ost_record;
+ return 0;
+}
--- /dev/null
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * lustre/smfs/audit_transfer.c
+ *
+ * Copyright (C) 2004 Cluster File Systems, Inc.
+ *
+ * This file is part of Lustre, http://www.lustre.org.
+ *
+ * Lustre is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * Lustre is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Lustre; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
+
+#define DEBUG_SUBSYSTEM S_SM
+
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/obd_class.h>
+#include <linux/obd_support.h>
+#include <linux/lustre_lib.h>
+#include <linux/lustre_idl.h>
+#include <linux/lustre_fsfilt.h>
+#include <linux/lustre_smfs.h>
+#include <linux/lustre_audit.h>
+#include <linux/lustre_log.h>
+#include "smfs_internal.h"
+
+struct transfer_item {
+ struct llog_handle *ti_llh;
+ struct list_head ti_link;
+ void * id2name;
+};
+
+#define TRANSFERD_STOP 0
+struct transferd_ctl {
+ unsigned long tc_flags;
+ wait_queue_head_t tc_waitq;
+ struct completion tc_starting;
+ struct completion tc_stopping;
+
+ struct list_head tc_list;
+ spinlock_t tc_lock;
+};
+
+static struct transferd_ctl transferd_tc;
+static DECLARE_MUTEX(transferd_sem);
+static int transferd_users = 0;
+char *buf = NULL;
+
+int audit_notify(struct llog_handle *llh, void * arg)
+{
+ struct transfer_item *ti;
+ ENTRY;
+
+ down(&transferd_sem);
+ if (transferd_users == 0) {
+ up(&transferd_sem);
+ RETURN(0);
+ }
+ up(&transferd_sem);
+
+ if (test_bit(TRANSFERD_STOP, &transferd_tc.tc_flags)) {
+ CDEBUG(D_INFO, "transfer daemon stopped\n");
+ RETURN(0);
+ }
+
+ OBD_ALLOC(ti, sizeof(*ti));
+ if (ti == NULL)
+ RETURN(-ENOMEM);
+
+ INIT_LIST_HEAD(&ti->ti_link);
+ ti->ti_llh = llh;
+ ti->id2name = arg;
+
+ spin_lock(&transferd_tc.tc_lock);
+ list_add_tail(&ti->ti_link, &transferd_tc.tc_list);
+ spin_unlock(&transferd_tc.tc_lock);
+
+ wake_up(&transferd_tc.tc_waitq);
+
+ RETURN(0);
+}
+
+const char *opstr[AUDIT_MAX] = {
+ [AUDIT_NONE] "null",
+ [AUDIT_CREATE] "create",
+ [AUDIT_LINK] "link",
+ [AUDIT_UNLINK] "unlink",
+ [AUDIT_SYMLINK] "symlink",
+ [AUDIT_RENAME] "rename",
+ [AUDIT_SETATTR] "setattr",
+ [AUDIT_WRITE] "write",
+ [AUDIT_READ] "read",
+ [AUDIT_OPEN] "open",
+ [AUDIT_STAT] "stat",
+ [AUDIT_MMAP] "mmap",
+ [AUDIT_READLINK] "readlink",
+ [AUDIT_READDIR] "readdir",
+};
+
+#define construct_header(buf, size, rec) \
+ snprintf(buf, size, \
+ "AUDIT [%u] [nid: "LPU64" uid: %u gid: %u rc: %d] [%s] ", \
+ rec->time, rec->nid, rec->uid, rec->gid, (__s16)rec->result, \
+ opstr[rec->opcode]);
+
+#define REC2ID(rec, id) { \
+ id_ino(id) = rec->au_num; \
+ id_gen(id) = rec->au_gen; \
+ id_type(id) = rec->au_type; \
+ id_fid(id) = rec->au_fid; \
+ id_group(id) = rec->au_mds; \
+}
+
+static int
+transfer_record(struct obd_device *obd, struct audit_record *rec, int type, void * data)
+{
+ struct audit_id_record *id_rec =
+ (struct audit_id_record *)((char *)rec + sizeof(*rec));
+ struct audit_name_record *name_rec = NULL;
+ int (*audit_id2name)(struct obd_device *obd, char **name,
+ int *namelen, struct lustre_id *id) = data;
+
+ int n, rc = 0;
+ ENTRY;
+
+ CDEBUG(D_INFO, "transfer %s\n", opstr[rec->opcode]);
+
+ memset(buf, 0, PAGE_SIZE);
+ n = construct_header(buf, PAGE_SIZE, rec);
+ if (n < 0)
+ RETURN(n);
+
+ switch (rec->opcode)
+ {
+ case AUDIT_UNLINK:
+ if (type != SMFS_AUDIT_NAME_REC)
+ break;
+ case AUDIT_LINK:
+ case AUDIT_RENAME:
+ id_rec++;
+ default:
+ break;
+ }
+
+ if (audit_id2name) {
+ char *name = NULL;
+ struct lustre_id id;
+ int namelen = 0;
+
+ REC2ID(id_rec, &id);
+ rc = audit_id2name(obd, &name, &namelen, &id);
+ if (rc < 0) {
+ strncat(buf, "unknown", PAGE_SIZE - n);
+ n += strlen("unknown");
+ } else if (namelen == 0) {
+ //root itself
+ if (type != SMFS_AUDIT_NAME_REC)
+ strcat(buf, "/");
+ } else {
+ strncat(buf, name, PAGE_SIZE - n);
+ n += namelen;
+ OBD_FREE(name, namelen);
+ }
+ }
+
+ if (type == SMFS_AUDIT_NAME_REC) {
+ name_rec = (struct audit_name_record *)((char *)(++id_rec));
+ strncat(buf, "/", 1);
+ n += 1;
+ strncat(buf, name_rec->name, PAGE_SIZE - n);
+ }
+
+ CDEBUG(D_INFO, "%s\n", buf);
+
+ printk("%s\n", buf);
+
+ RETURN(rc);
+}
+
+static int transfer_cb(struct llog_handle *llh, struct llog_rec_hdr *rec,
+ void *data)
+{
+ struct obd_device *obd = llh->lgh_ctxt->loc_obd;
+ struct audit_record *ad_rec;
+ int rc = 0;
+ ENTRY;
+
+ if (!(le32_to_cpu(llh->lgh_hdr->llh_flags) & LLOG_F_IS_PLAIN)) {
+ CERROR("log is not plain\n");
+ RETURN(-EINVAL);
+ }
+ if (rec->lrh_type != cpu_to_le32(SMFS_AUDIT_GEN_REC) &&
+ rec->lrh_type != cpu_to_le32(SMFS_AUDIT_NAME_REC)) {
+ CERROR("log record type error\n");
+ RETURN(-EINVAL);
+ }
+
+ ad_rec = (struct audit_record *)((char *)rec + sizeof(*rec));
+
+ LASSERT(ad_rec->opcode < AUDIT_MAX);
+
+ rc = transfer_record(obd, ad_rec, rec->lrh_type, data);
+ if (rc)
+ CERROR("transfer record failed! rc:%d\n", rc);
+
+ RETURN(LLOG_DEL_RECORD);
+}
+
+static int audit_transfer(struct transfer_item *ti)
+{
+ struct llog_handle *llh = ti->ti_llh;
+ int rc = 0;
+ ENTRY;
+
+ rc = llog_cat_process(llh, (llog_cb_t)&transfer_cb, ti->id2name);
+ if (rc)
+ CERROR("process catalog log failed: rc(%d)\n", rc);
+
+ RETURN(0);
+}
+
+static int transferd_check(struct transferd_ctl *tc)
+{
+ int rc = 0;
+ ENTRY;
+
+ if (test_bit(TRANSFERD_STOP, &tc->tc_flags))
+ RETURN(1);
+
+ spin_lock(&tc->tc_lock);
+ rc = list_empty(&tc->tc_list) ? 0 : 1;
+ spin_unlock(&tc->tc_lock);
+
+ RETURN(rc);
+}
+
+static int transferd(void *arg)
+{
+ struct transferd_ctl *tc = arg;
+ unsigned long flags;
+ struct list_head *pos, *tmp;
+ struct transfer_item *ti = NULL;
+ ENTRY;
+
+ lock_kernel();
+
+ /* ptlrpc_daemonize() */
+ exit_mm(current);
+ lustre_daemonize_helper();
+ exit_files(current);
+ reparent_to_init();
+
+ SIGNAL_MASK_LOCK(current, flags);
+ sigfillset(¤t->blocked);
+ RECALC_SIGPENDING;
+ SIGNAL_MASK_UNLOCK(current, flags);
+ THREAD_NAME(current->comm, sizeof(current->comm) - 1, "%s",
+ "audit_transferd");
+ unlock_kernel();
+
+ complete(&tc->tc_starting);
+
+ LASSERT(buf == NULL);
+ OBD_ALLOC(buf, PAGE_SIZE);
+ LASSERT(buf != NULL);
+
+ while (1) {
+ struct l_wait_info lwi = { 0 };
+
+ l_wait_event(tc->tc_waitq, transferd_check(tc), &lwi);
+
+ if (test_bit(TRANSFERD_STOP, &tc->tc_flags))
+ break;
+
+ spin_lock(&tc->tc_lock);
+ LASSERT(!list_empty(&tc->tc_list));
+ ti = list_entry(tc->tc_list.next, struct transfer_item, ti_link);
+ list_del_init(&ti->ti_link);
+ spin_unlock(&tc->tc_lock);
+
+ audit_transfer(ti);
+ OBD_FREE(ti, sizeof(*ti));
+
+ }
+
+ OBD_FREE(buf, PAGE_SIZE);
+
+ spin_lock(&tc->tc_lock);
+ list_for_each_safe(pos, tmp, &tc->tc_list) {
+ ti = list_entry(pos, struct transfer_item, ti_link);
+ list_del_init(&ti->ti_link);
+ OBD_FREE(ti, sizeof(*ti));
+ }
+ spin_unlock(&tc->tc_lock);
+
+ complete(&tc->tc_stopping);
+ RETURN(0);
+}
+
+int audit_start_transferd()
+{
+ int rc = 0;
+ ENTRY;
+
+ down(&transferd_sem);
+ if (++transferd_users != 1)
+ GOTO(out, rc = 0);
+
+ memset(&transferd_tc, 0, sizeof(transferd_tc));
+ init_completion(&transferd_tc.tc_starting);
+ init_completion(&transferd_tc.tc_stopping);
+ init_waitqueue_head(&transferd_tc.tc_waitq);
+ transferd_tc.tc_flags = 0;
+ INIT_LIST_HEAD(&transferd_tc.tc_list);
+ spin_lock_init(&transferd_tc.tc_lock);
+
+ if (kernel_thread(transferd, &transferd_tc, 0) < 0) {
+ transferd_users--;
+ GOTO(out, rc = -ECHILD);
+ }
+
+ wait_for_completion(&transferd_tc.tc_starting);
+out:
+ up(&transferd_sem);
+ RETURN(rc);
+}
+
+int audit_stop_transferd(void)
+{
+ int rc = 0;
+ ENTRY;
+
+ down(&transferd_sem);
+ if (--transferd_users > 0)
+ GOTO(out, rc = 0);
+
+ set_bit(TRANSFERD_STOP, &transferd_tc.tc_flags);
+ wake_up(&transferd_tc.tc_waitq);
+ wait_for_completion(&transferd_tc.tc_stopping);
+out:
+ up(&transferd_sem);
+ RETURN(rc);
+}
unlock_kernel();
}
-#define SMFS_IOPEN_INO 1
-
void sm_set_inode_ops(struct inode *inode)
{
struct smfs_super_info *smb = S2SMI(inode->i_sb);
[HOOK_READDIR] NULL,
};
-static int smfs_lru_pre_op(int op, struct inode *inode, void * msg, int ret,
+static int smfs_lru_pre_op(hook_op op, struct inode *inode, void * msg, int ret,
void *priv)
{
int rc = 0;
RETURN(rc);
}
-static int smfs_lru_post_op(int op, struct inode *inode, void *msg, int ret,
+static int smfs_lru_post_op(hook_op op, struct inode *inode, void *msg, int ret,
void *priv)
{
int rc = 0;
}
/* Helpers */
-static int smfs_exit_lru(struct super_block *sb, void * arg, void * priv)
-{
- ENTRY;
-
- smfs_deregister_plugin(sb, SMFS_PLG_LRU);
-
- EXIT;
- return 0;
-}
-
static int smfs_trans_lru (struct super_block *sb, void *arg, void * priv)
{
int size;
typedef int (*lru_helper)(struct super_block * sb, void *msg, void *);
static lru_helper smfs_lru_helpers[PLG_HELPER_MAX] = {
- [PLG_EXIT] smfs_exit_lru,
[PLG_START] smfs_start_lru,
[PLG_STOP] smfs_stop_lru,
[PLG_TRANS_SIZE] smfs_trans_lru,
RETURN(0);
}
+static int smfs_exit_lru(struct super_block *sb, void * arg)
+{
+ struct smfs_plugin * plg;
+
+ ENTRY;
+
+ plg = smfs_deregister_plugin(sb, SMFS_PLG_LRU);
+ if (plg)
+ OBD_FREE(plg, sizeof(*plg));
+ else
+ CERROR("Cannot find LRU plugin while unregistering\n");
+
+ EXIT;
+ return 0;
+}
+
int smfs_init_lru(struct super_block *sb)
{
- struct smfs_plugin plg = {
- .plg_type = SMFS_PLG_LRU,
- .plg_pre_op = &smfs_lru_pre_op,
- .plg_post_op = &smfs_lru_post_op,
- .plg_helper = &smfs_lru_help_op,
- .plg_private = NULL
- };
+ struct smfs_plugin * plg = NULL;
int rc = 0;
ENTRY;
-
- rc = smfs_register_plugin(sb, &plg);
+
+ OBD_ALLOC(plg, sizeof(*plg));
+ if (!plg) {
+ rc = -ENOMEM;
+ goto exit;
+ }
+
+ plg->plg_type = SMFS_PLG_LRU;
+ plg->plg_pre_op = &smfs_lru_pre_op;
+ plg->plg_post_op = &smfs_lru_post_op;
+ plg->plg_helper = &smfs_lru_help_op;
+ plg->plg_exit = &smfs_exit_lru;
+
+ rc = smfs_register_plugin(sb, plg);
+ if (!rc)
+ RETURN(0);
+exit:
+ if (plg)
+ OBD_FREE(plg, sizeof(*plg));
RETURN(rc);
}
rc = -ENOMEM;
goto exit;
}
-
+
handle = smfs_trans_start(dir, FSFILT_OP_RMDIR, NULL);
if (IS_ERR(handle) ) {
rc = -ENOSPC;
struct hook_rename_msg msg = {
.dentry = old_dentry,
.new_dir = new_dir,
- .new_dentry = new_dentry
+ .old_dir = old_dir,
+ .new_dentry = new_dentry,
};
ENTRY;
struct inode *cache_inode = NULL;
struct smfs_file_info *sfi = NULL;
int rc = 0;
- struct hook_readdir_msg msg = {
- .dentry = dentry,
- .filp = filp,
- .dirent = dirent,
- .filldir = filldir
- };
ENTRY;
sfi = F2SMFI(filp);
if (sfi->magic != SMFS_FILE_MAGIC) BUG();
- SMFS_PRE_HOOK(dentry->d_inode, HOOK_READDIR, &msg);
-
rc = cache_inode->i_fop->readdir(sfi->c_file, dirent, filldir);
- SMFS_POST_HOOK(dentry->d_inode, HOOK_READDIR, &msg, rc);
duplicate_file(filp, sfi->c_file);
RETURN(rc);
struct dentry *cache_dentry;
void *handle = NULL;
int rc = 0;
- struct hook_setattr_msg msg = {
+ struct hook_attr_msg msg = {
.dentry = dentry,
- .attr = attr
+ .attr = attr,
};
ENTRY;
{
struct inode *cache_inode = I2CI(dentry->d_inode);
struct dentry *cache_dentry = NULL;
+ struct hook_xattr_msg msg = {
+ .name = (char*)name,
+ };
int rc = 0;
ENTRY;
RETURN(-ENOMEM);
pre_smfs_inode(dentry->d_inode, cache_inode);
+ SMFS_PRE_HOOK(dentry->d_inode, HOOK_SETXATTR, &msg);
rc = cache_inode->i_op->setxattr(cache_dentry, name, value,
size, flags);
+
+ SMFS_POST_HOOK(dentry->d_inode, HOOK_SETXATTR, &msg, rc);
post_smfs_inode(dentry->d_inode, cache_inode);
post_smfs_dentry(cache_dentry);
{
struct inode *cache_inode = I2CI(dentry->d_inode);
struct dentry *cache_dentry;
+ struct hook_xattr_msg msg = {
+ .name = (char*)name,
+ };
int rc = 0;
ENTRY;
RETURN(-ENOMEM);
pre_smfs_inode(dentry->d_inode, cache_inode);
-
+ SMFS_PRE_HOOK(dentry->d_inode, HOOK_GETXATTR, &msg);
rc = cache_inode->i_op->getxattr(cache_dentry, name, buffer,
size);
-
+ SMFS_POST_HOOK(dentry->d_inode, HOOK_GETXATTR, &msg, rc);
post_smfs_inode(dentry->d_inode, cache_inode);
post_smfs_dentry(cache_dentry);
struct inode *cache_inode = I2CI(dentry->d_inode);
struct dentry *cache_dentry;
int rc = 0;
-
+ struct hook_xattr_msg msg = {
+ .name = NULL,
+ };
+
ENTRY;
LASSERT(cache_inode);
RETURN(-ENOMEM);
pre_smfs_inode(dentry->d_inode, cache_inode);
+ SMFS_PRE_HOOK(dentry->d_inode, HOOK_LISTXATTR, &msg);
rc = cache_inode->i_op->listxattr(cache_dentry, buffer, size);
+ SMFS_POST_HOOK(dentry->d_inode, HOOK_LISTXATTR, &msg, rc);
post_smfs_inode(dentry->d_inode, cache_inode);
post_smfs_dentry(cache_dentry);
struct inode *cache_inode = I2CI(dentry->d_inode);
struct dentry *cache_dentry;
int rc = 0;
-
+ struct hook_xattr_msg msg = {
+ .name = (char*)name,
+ };
ENTRY;
LASSERT(cache_inode);
RETURN(-ENOMEM);
pre_smfs_inode(dentry->d_inode, cache_inode);
+ SMFS_PRE_HOOK(dentry->d_inode, HOOK_REMOVEXATTR, &msg);
rc = cache_inode->i_op->removexattr(cache_dentry, name);
+ SMFS_POST_HOOK(dentry->d_inode, HOOK_REMOVEXATTR, &msg, rc);
post_smfs_inode(dentry->d_inode, cache_inode);
post_smfs_dentry(cache_dentry);
loff_t tmp_ppos;
loff_t *cache_ppos;
ssize_t rc = -EIO;
+ struct hook_msg msg = {
+ .dentry = file->f_dentry,
+ };
ENTRY;
*cache_ppos = *off;
pre_smfs_inode(file->f_dentry->d_inode, cache_inode);
+ SMFS_PRE_HOOK(file->f_dentry->d_inode, HOOK_READDIR, &msg);
+
#if CONFIG_SNAPFS
/*readdir page*/
if (smfs_dotsnap_inode(file->f_dentry->d_inode)) {
cache_ppos);
#endif
+ SMFS_POST_HOOK(file->f_dentry->d_inode, HOOK_READDIR, &msg, rc);
*off = *cache_ppos;
post_smfs_inode(file->f_dentry->d_inode, cache_inode);
duplicate_file(file, sfi->c_file);
struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
struct inode *cache_inode = NULL;
int rc = -EIO;
-
+ /*
+ struct hook_rw_msg msg = {
+ .write = create,
+ };
+ */
ENTRY;
if (!cache_fsfilt)
RETURN(-ENOSYS);
down(&cache_inode->i_sem);
+ //SMFS_PRE_HOOK(inode, HOOK_MAP_PAGES, &msg);
rc = cache_fsfilt->fs_map_inode_pages(cache_inode, page, pages, blocks,
created, create, sem);
+
up(&cache_inode->i_sem);
RETURN(rc);
}
static int fsfilt_smfs_post_setup(struct obd_device *obd, struct vfsmount *mnt,
- struct dentry *root_dentry)
+ struct dentry *root_dentry)//, void *data)
{
struct super_block *sb = NULL;
int rc = 0;
if (mnt) {
sb = mnt->mnt_sb;
- if (obd)
- S2SMI(sb)->smsi_exp = obd->obd_self_export;
+ LASSERT(obd);
+ S2SMI(sb)->smsi_exp = obd->obd_self_export;
- rc = smfs_post_setup(obd, mnt, root_dentry);
+ rc = smfs_post_setup(obd, mnt, root_dentry);//, data);
if (rc) {
CERROR("post_setup fails in obd %p rc=%d", obd, rc);
}
-
-
}
RETURN(rc);
struct dentry *cache_dentry = NULL;
struct inode *cache_inode = I2CI(dentry->d_inode);
struct smfs_super_info *sbi = S2SMI(dentry->d_inode->i_sb);
- struct hook_setattr_msg msg = {
+ struct hook_attr_msg msg = {
.dentry = dentry,
.attr = iattr
};
* aggregated i_blocks from all OSTs -bzzz */
cache_inode->i_blocks = dentry->d_inode->i_blocks;
}
+
rc = cache_fsfilt->fs_setattr(cache_dentry, handle, iattr, do_trunc);
SMFS_POST_HOOK(dentry->d_inode, HOOK_F_SETATTR, &msg, rc);
{
struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
struct inode *cache_inode = NULL;
- struct hook_setxattr_msg msg = {
- .inode = inode,
+ struct hook_xattr_msg msg = {
.name = name,
.buffer = buffer,
.buffer_size = buffer_size
ENTRY;
if (!cache_fsfilt)
- RETURN(rc);
+ RETURN(-EIO);
cache_inode = I2CI(inode);
if (!cache_inode)
RETURN(rc);
pre_smfs_inode(inode, cache_inode);
-
SMFS_PRE_HOOK(inode, HOOK_F_SETXATTR, &msg);
if (cache_fsfilt->fs_set_xattr)
rc = cache_fsfilt->fs_set_xattr(cache_inode, handle, name,
RETURN(rc);
pre_smfs_inode(inode, cache_inode);
-
if (cache_fsfilt->fs_get_xattr)
rc = cache_fsfilt->fs_get_xattr(cache_inode, name,
buffer, buffer_size);
#define XATTR_LUSTRE_MDS_MEA_EA "mea"
#define XATTR_LUSTRE_MDS_MID_EA "mid"
#define XATTR_LUSTRE_MDS_SID_EA "sid"
+#define XATTR_LUSTRE_MDS_PID_EA "pid"
#define XATTR_LUSTRE_MDS_KEY_EA "key"
static int fsfilt_smfs_set_md(struct inode *inode, void *handle,
XATTR_LUSTRE_MDS_MID_EA,
lmm, lmm_size);
break;
+ case EA_PID:
+ rc = fsfilt_smfs_set_xattr(inode, handle,
+ XATTR_LUSTRE_MDS_PID_EA,
+ lmm, lmm_size);
+ break;
case EA_KEY:
rc = fsfilt_smfs_set_xattr(inode, handle,
XATTR_LUSTRE_MDS_KEY_EA,
XATTR_LUSTRE_MDS_MID_EA,
lmm, lmm_size);
break;
+ case EA_PID:
+ rc = fsfilt_smfs_get_xattr(inode,
+ XATTR_LUSTRE_MDS_PID_EA,
+ lmm, lmm_size);
+ break;
+ case EA_KEY:
+ rc = fsfilt_smfs_get_xattr(inode,
+ XATTR_LUSTRE_MDS_KEY_EA,
+ lmm, lmm_size);
+ break;
default:
rc = -EINVAL;
}
}
+static int fsfilt_smfs_set_info (struct super_block *sb, struct inode * inode,
+ __u32 keylen, void *key,
+ __u32 valsize, void *val)
+{
+ int rc = 0;
+ struct plg_info_msg msg = {
+ .key = key,
+ .val = val,
+ };
+ ENTRY;
+
+ if (keylen >= 9 && memcmp(key, "file_read", 9) == 0) {
+ /*
+ * this key used to inform smfs on OST about incoming r/w
+ */
+ struct lustre_id * id = val;
+ struct hook_rw_msg msg = {
+ .write = 0,
+ .id = id,
+ };
+ if (inode)
+ SMFS_POST_HOOK(inode, HOOK_SI_READ, &msg, rc);
+ }
+ else if (keylen >= 10 && memcmp(key, "file_write", 10) == 0) {
+ /*
+ * this key used to inform smfs on OST about incoming r/w
+ */
+ struct lustre_id * id = val;
+ struct hook_rw_msg msg = {
+ .write = 1,
+ .id = id,
+ };
+ if (inode)
+ SMFS_POST_HOOK(inode, HOOK_SI_WRITE, &msg, rc);
+ }
+ else if (keylen >= 10 && memcmp(key, "audit_info", 10) == 0) {
+ /* this key used to pass audit data on MDS */
+ struct audit_info * info = val;
+
+ SMFS_POST_HOOK(inode, HOOK_SPECIAL, info, info->m.result);
+ }
+ else if (keylen >= 8 && memcmp(key, "auditlog", 8) == 0) {
+ /*
+ * this key used to inform smfs on OST about client audit data
+ */
+
+ audit_client_log(sb, val);
+ }
+ else if (keylen == 5 && memcmp(key, "audit", 5) == 0) {
+ rc = smfs_set_audit(sb, inode, (__u64 *)val);
+ }
+ else if (keylen == 7 && memcmp(key, "id2name", 7) == 0) {
+ rc = SMFS_PLG_HELP(sb, PLG_SET_INFO, &msg);
+ }
+ else
+ rc = -ENOENT;
+
+ RETURN(rc);
+}
+
+static int fsfilt_smfs_get_info (struct super_block *sb, struct inode * inode,
+ __u32 keylen, void *key,
+ __u32 *valsize, void *val)
+{
+ int rc = -ENOENT;
+
+ ENTRY;
+
+ if (keylen == 5 && strcmp(key, "audit") == 0) {
+ __u64 * mask = val;
+ rc = smfs_get_audit(sb, inode, NULL, mask);
+ }
+
+ RETURN(rc);
+}
static struct fsfilt_operations fsfilt_smfs_ops = {
.fs_type = "smfs",
.fs_set_ost_flags = fsfilt_smfs_set_ost_flags,
.fs_set_mds_flags = fsfilt_smfs_set_mds_flags,
.fs_precreate_rec = fsfilt_smfs_precreate_rec,
- .fs_get_reint_log_ctxt = NULL, /*fsfilt_smfs_get_reint_log_ctxt,*/
+ .fs_set_info = fsfilt_smfs_set_info,
+ .fs_get_info = fsfilt_smfs_get_info,
.fs_set_snap_item = fsfilt_smfs_set_snap_item,
.fs_do_write_cow = fsfilt_smfs_do_write_cow,
- };
+};
struct fsfilt_operations *get_smfs_fs_ops(void)
{
static int kml_setattr(struct inode *inode, void *arg, struct kml_priv *priv)
{
- struct hook_setattr_msg *msg = arg;
+ struct hook_attr_msg *msg = arg;
int rc = 0, length = 0;
char *buffer = NULL;
ENTRY;
static int kml_setxattr(struct inode *inode, void *arg, struct kml_priv *priv)
{
- struct hook_setxattr_msg *msg = arg;
+ struct hook_xattr_msg *msg = arg;
struct kml_buffer kbuf;
int rc = 0, length = 0;
char *buffer = NULL;
kbuf.buf = msg->buffer;
kbuf.buf_size = msg->buffer_size;
- rc = priv->pack_fn(REINT_SETXATTR, buffer, NULL, msg->inode, msg->name,
+ rc = priv->pack_fn(REINT_SETXATTR, buffer, NULL, inode, msg->name,
&kbuf);
if (rc <= 0)
GOTO(exit, rc);
[HOOK_F_SETXATTR] kml_setxattr,
};
-static int smfs_kml_post_op(int code, struct inode * inode,
+static int smfs_kml_post_op(hook_op code, struct inode * inode,
void * msg, int ret, void * priv)
{
int rc = 0;
ENTRY;
-
+
+ //check if inode has flag for KML
+ if (!SMFS_IS(I2SMI(inode)->smi_flags, SMFS_PLG_KML))
+ RETURN(0);
+
//KML don't handle failed ops
if (ret)
RETURN(0);
-
+
if (smfs_kml_post[code]) {
CDEBUG(D_INODE,"KML: inode %lu, code: %u\n", inode->i_ino, code);
rc = smfs_kml_post[code](inode, msg, priv);
}
/* Helpers */
-static int smfs_exit_kml(struct super_block *sb, void * arg, struct kml_priv * priv)
-{
- struct smfs_plugin * plg = NULL;
- ENTRY;
-
- plg = smfs_deregister_plugin(sb, SMFS_PLG_KML);
- if (plg)
- OBD_FREE(plg, sizeof(*plg));
- else
- CERROR("Cannot find KLM plugin while unregistering\n");
-
- if (priv)
- OBD_FREE(priv, sizeof(*priv));
-
- EXIT;
- return 0;
-}
-
static int smfs_trans_kml (struct super_block *sb, void *arg,
struct kml_priv * priv)
{
RETURN(rc);
}
- (*ctxt)->llog_proc_cb = NULL;//smfs_llog_process_rec_cb;
+ /* connect KML ctxt to obd */
+ if (obd && smb->smsi_kml_log) {
+ smb->smsi_kml_log->loc_idx = LLOG_REINT_ORIG_CTXT;
+ smb->smsi_kml_log->loc_obd = obd;
+ smb->smsi_kml_log->loc_llogs = &obd->obd_llogs;
+ obd->obd_llogs.llog_ctxt[LLOG_REINT_ORIG_CTXT] = smb->smsi_kml_log;
+ }
SMFS_SET(smb->plg_flags, SMFS_PLG_KML);
{
struct smfs_super_info * smb = S2SMI(sb);
struct llog_ctxt *ctxt = smb->smsi_kml_log;
+ struct obd_device * obd = ctxt->loc_obd;
ENTRY;
if (!SMFS_IS(smb->plg_flags, SMFS_PLG_KML))
SMFS_CLEAR(smb->plg_flags, SMFS_PLG_KML);
llog_catalog_cleanup(ctxt);
+ obd->obd_llogs.llog_ctxt[LLOG_REINT_ORIG_CTXT] = NULL;
OBD_FREE(ctxt, sizeof(*ctxt));
RETURN(0);
typedef int (*kml_helper)(struct super_block * sb, void *msg, struct kml_priv *);
static kml_helper smfs_kml_helpers[PLG_HELPER_MAX] = {
- [PLG_EXIT] smfs_exit_kml,
[PLG_START] smfs_start_kml,
[PLG_STOP] smfs_stop_kml,
[PLG_TRANS_SIZE] smfs_trans_kml,
return rc;
}
+static int smfs_exit_kml(struct super_block *sb, void * arg)
+{
+ struct smfs_plugin * plg = NULL;
+ struct kml_priv * priv = arg;
+ ENTRY;
+
+ plg = smfs_deregister_plugin(sb, SMFS_PLG_KML);
+ if (plg)
+ OBD_FREE(plg, sizeof(*plg));
+ else
+ CERROR("Cannot find KLM plugin while unregistering\n");
+
+ if (priv)
+ OBD_FREE(priv, sizeof(*priv));
+
+ EXIT;
+ return 0;
+}
+
int smfs_init_kml(struct super_block *sb)
{
int rc = 0;
plg->plg_type = SMFS_PLG_KML;
plg->plg_pre_op = NULL;
- plg->plg_post_op = &smfs_kml_post_op;
- plg->plg_helper = &smfs_kml_help_op;
+ plg->plg_post_op = smfs_kml_post_op;
+ plg->plg_helper = smfs_kml_help_op;
+ plg->plg_exit = smfs_exit_kml;
OBD_ALLOC(priv, sizeof(*priv));
if (!priv) {
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * Copyright (C) 2001-2003 Cluster File Systems, Inc. <info@clusterfs.com>
+ *
+ * This file is part of Lustre, http://www.lustre.org.
+ *
+ * Lustre is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * Lustre is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Lustre; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * smfs data structures.
+ * See also lustre_idl.h for wire formats of requests.
+ *
+ */
+
+#ifndef __SMFS_API_H
+#define __SMFS_API_H
+
+#include <linux/lustre_audit.h>
+
/* SMFS plugin stuff */
#define SMFS_PLG_KML 0x0001L
#define SMFS_PLG_LRU 0x0004L
#define SMFS_PLG_COW 0x0020L
#define SMFS_PLG_UNDO 0x0100L
+#define SMFS_PLG_AUDIT 0x0200L
#define SMFS_PLG_DUMMY 0x1000L
#define SMFS_PLG_ALL (~0L)
#define SMFS_IS(flags, mask) (flags & mask)
#define SMFS_CLEAR(flags, mask) (flags &= ~mask)
-typedef int (*smfs_plg_hook)(int hook_code, struct inode *,
+typedef enum {
+ HOOK_CREATE = 1,
+ HOOK_LOOKUP,
+ HOOK_LINK,
+ HOOK_UNLINK,
+ HOOK_SYMLINK,
+ HOOK_READLINK,
+ HOOK_MKDIR,
+ HOOK_RMDIR,
+ HOOK_MKNOD,
+ HOOK_RENAME,
+ HOOK_SETATTR,
+ HOOK_GETATTR,
+ HOOK_WRITE,
+ HOOK_READ,
+ HOOK_READDIR,
+ HOOK_F_SETATTR,
+ HOOK_SETXATTR,
+ HOOK_GETXATTR,
+ HOOK_REMOVEXATTR,
+ HOOK_LISTXATTR,
+ HOOK_F_SETXATTR,
+ HOOK_SI_READ,
+ HOOK_SI_WRITE,
+ HOOK_SPECIAL,
+ HOOK_MAX
+} hook_op;
+
+typedef int (*smfs_plg_hook)(hook_op hook_code, struct inode *,
void *arg, int rc, void * priv);
typedef int (*smfs_plg_func)(int help_code, struct super_block *,
void *arg, void * priv);
smfs_plg_hook plg_post_op;
smfs_plg_func plg_helper;
void * plg_private;
+ int (* plg_exit)(struct super_block *, void *);
};
-
+/* KML plugin stuff */
#define KML_LOG_NAME "smfs_kml"
struct kml_priv {
struct inode *, void *, void *);
};
-#define UNDO_LOG_NAME "smfs_undo"
-struct undo_priv {
- struct llog_ctxt *undo_ctxt;
+struct audit_priv {
+ struct llog_ctxt *audit_ctxt;
+ void * audit_get_record;
+ void * au_id2name;
+ int result;
+ __u64 a_mask;
};
-
-#define HOOK_CREATE 1
-#define HOOK_LOOKUP 2
-#define HOOK_LINK 3
-#define HOOK_UNLINK 4
-#define HOOK_SYMLINK 5
-#define HOOK_MKDIR 6
-#define HOOK_RMDIR 7
-#define HOOK_MKNOD 8
-#define HOOK_RENAME 9
-#define HOOK_SETATTR 10
-#define HOOK_WRITE 11
-#define HOOK_READDIR 12
-#define HOOK_F_SETATTR 13
-#define HOOK_SETXATTR 14
-#define HOOK_F_SETXATTR 15
-#define HOOK_MAX 16
+typedef int (*audit_get_op)(struct inode *, void *, struct audit_priv *,
+ char *, __u32*);
struct hook_msg {
struct dentry * dentry;
struct hook_rename_msg {
struct dentry * dentry;
+ struct inode * old_dir;
struct inode * new_dir;
struct dentry * new_dentry;
};
loff_t pos;
};
-struct hook_setattr_msg {
+struct hook_attr_msg {
struct dentry * dentry;
struct iattr *attr;
};
-struct hook_setxattr_msg {
- struct inode * inode;
- char *name;
+struct hook_xattr_msg {
+ char * name;
char *buffer;
int buffer_size;
};
-void smfs_pre_hook (struct inode*, int, void*);
-void smfs_post_hook(struct inode*,int, void*, int);
+struct hook_rw_msg {
+ int write;
+ struct lustre_id *id;
+};
+
+void smfs_pre_hook (struct inode*, hook_op, void*);
+void smfs_post_hook(struct inode*, hook_op, void*, int);
#define SMFS_PRE_HOOK(inode, op, msg) smfs_pre_hook (inode, op, msg)
#define SMFS_POST_HOOK(inode, op, msg, rc) smfs_post_hook(inode, op, msg, rc)
#define PLG_SET_INODE 3
#define PLG_START 4
#define PLG_STOP 5
-#define PLG_HELPER_MAX 6
+#define PLG_SET_INFO 6
+#define PLG_HELPER_MAX 7
struct plg_hmsg {
__u32 data;
__u32 result;
};
+struct plg_info_msg {
+ char * key;
+ void * val;
+};
int smfs_helper (struct super_block *, int, void *);
#define SMFS_PLG_HELP(sb, op, data) smfs_helper(sb, op, data)
int smfs_init_kml(struct super_block *);
int smfs_init_lru(struct super_block *);
int smfs_init_cow(struct super_block *);
-
+int smfs_init_audit(struct super_block *);
+//int audit_mds_op(hook_op, struct inode *, void *, struct audit_priv *);
+int audit_client_log(struct super_block*, struct audit_msg *);
+int audit_mds_setup(struct obd_device *, struct super_block *, struct audit_priv *);
+int audit_ost_setup(struct obd_device *, struct super_block *, struct audit_priv *);
+int smfs_set_audit(struct super_block *, struct inode *, __u64 *);
+int smfs_get_audit(struct super_block *, struct inode *,
+ struct inode *, __u64 *);
+
+static inline int audit_rec_from_id (char **pbuf, struct lustre_id * id)
+{
+ struct audit_id_record * rec = (void*)(*pbuf);
+ int len = sizeof(*rec);
+
+ rec->au_num = id_ino(id);
+ rec->au_fid = id_fid(id);
+ rec->au_gen = id_gen(id);
+ rec->au_type = id_type(id);
+ rec->au_mds = id_group(id);
+
+ *pbuf += len;
+ return len;
+}
+
+static inline int audit_fill_id_rec (char **pbuf, struct inode * inode)
+{
+ struct fsfilt_operations *fsfilt = I2FOPS(inode);
+ struct audit_id_record * rec = (void*)(*pbuf);
+ int len = sizeof(*rec);
+ struct lustre_fid fid;
+ int rc = 0;
+
+ rec->au_num = inode->i_ino;
+ rec->au_type = (S_IFMT & inode->i_mode);
+ rec->au_gen = inode->i_generation;
+
+ //fid & mdsnum
+ rc = fsfilt->fs_get_md(I2CI(inode), &fid, sizeof(fid), EA_SID);
+ if (rc > 0) {
+ rec->au_fid = fid.lf_id;
+ rec->au_mds = fid.lf_group;
+ }
+
+ *pbuf += len;
+ return len;
+}
+
+static inline int audit_fill_name_rec (char **pbuf, const char * name, int nlen)
+{
+ struct audit_name_record * n_rec = (void*)(*pbuf);
+ int len = sizeof(*n_rec) + nlen;
+
+ memcpy(n_rec->name, name, nlen);
+ n_rec->name_len = nlen;
+
+ *pbuf += len;
+ return len;
+}
+
+#endif
buffer += sizeof(opcode); \
} while (0)
+#define SMFS_IOPEN_INO 1
+#define KEY_IS(str, key) (strcmp(str,key) == 0)
extern int init_smfs_proc_sys(void);
/*cache.c*/
int smfs_fill_super(struct super_block *sb, void *data, int silent);
int smfs_post_setup(struct obd_device *, struct vfsmount *, struct dentry *);
void smfs_post_cleanup(struct super_block *);
+void * smfs_get_plg_priv(struct smfs_super_info *, int);
/*sysctl.c*/
extern int sm_debug_level;
extern int sm_inodes;
int ost_rec_pack_init(struct smfs_super_info *smb);
/*smfs_llog.c*/
-extern int smfs_llog_setup(struct smfs_super_info *);
+extern int smfs_llog_setup(struct dentry **, struct dentry **);
extern int smfs_llog_cleanup(struct smfs_super_info *);
extern int smfs_llog_add_rec(struct smfs_super_info *, void *, int);
/*ioctl.c*/
extern void smfs_cleanup_psdev(void);
/*smfs_cow.c */
+/* audit_transfer.c */
+int audit_notify(struct llog_handle *llh, void*);
+int audit_start_transferd(void);
+int audit_stop_transferd(void);
+
/* cache_space.c */
extern int do_cache_manage;
struct cache_purge_queue {
*namestr = pos + 5;
} else if (!strcmp(pos, "kml")) {
SMFS_SET(*flags, SMFS_PLG_KML);
+ } else if (!strcmp(pos, "audit")) {
+ SMFS_SET(*flags, SMFS_PLG_AUDIT);
} else if (!strcmp(pos, "cache")) {
SMFS_SET(*flags, SMFS_PLG_LRU);
} else if (!strcmp(pos, "snap")) {
}
+extern int (*audit_id2name_superhack) (struct obd_device *obd, char **name,
+ int *namelen, struct lustre_id *id);
+
int smfs_post_setup(struct obd_device *obd, struct vfsmount *mnt,
struct dentry * root_dentry)
{
int rc = 0;
ENTRY;
+
+ /* XXX to register id2name function of mds in smfs */
+ //if (data != NULL)
+ // audit_id2name_superhack = data;
OBD_ALLOC(current_ctxt, sizeof(*current_ctxt));
if (!current_ctxt)
push_ctxt(&saved, smb->smsi_ctxt, NULL);
- rc = smfs_llog_setup(smb);
+ rc = smfs_llog_setup(&smb->smsi_logs_dir, &smb->smsi_objects_dir);
if (!rc) {
- rc = SMFS_PLG_HELP(mnt->mnt_sb, PLG_START, NULL);
+ rc = SMFS_PLG_HELP(mnt->mnt_sb, PLG_START, obd);
}
pop_ctxt(&saved, smb->smsi_ctxt, NULL);
- /* connect KML ctxt to obd */
- if (obd && smb->smsi_kml_log) {
- smb->smsi_kml_log->loc_idx = LLOG_REINT_ORIG_CTXT;
- smb->smsi_kml_log->loc_obd = obd;
- obd->obd_llog_ctxt[LLOG_REINT_ORIG_CTXT] = smb->smsi_kml_log;
- }
-
/* enable plugins for directories on MDS or OST */
if (obd && obd->obd_type && obd->obd_type->typ_name) {
if (!strcmp(obd->obd_type->typ_name, "obdfilter")) {
INIT_LIST_HEAD(&smb->smsi_plg_list);
init_rwsem(&smb->plg_sem);
+ if (SMFS_IS(flags, SMFS_PLG_AUDIT))
+ smfs_init_audit(sb);
if (SMFS_IS(flags, SMFS_PLG_KML))
smfs_init_kml(sb);
if (SMFS_IS(flags, SMFS_PLG_LRU))
static void smfs_remove_plugins(struct super_block *sb)
{
+ struct smfs_plugin * plg, *tmp;
+ struct smfs_super_info *smb = S2SMI(sb);
+ struct list_head * plist = &smb->smsi_plg_list;
+
ENTRY;
-
- SMFS_PLG_HELP(sb, PLG_EXIT, (void*)sb);
+
+ list_for_each_entry_safe(plg, tmp, plist, plg_list) {
+ plg->plg_exit(sb, plg->plg_private);
+ }
EXIT;
}
RETURN(plg);
}
-void smfs_pre_hook (struct inode * inode, int op, void * msg)
+void smfs_pre_hook (struct inode * inode, hook_op op, void * msg)
{
struct smfs_super_info *smb = S2SMI(inode->i_sb);
struct smfs_inode_info *smi = I2SMI(inode);
//EXIT;
}
-void smfs_post_hook (struct inode * inode, int op, void * msg, int ret)
+void smfs_post_hook (struct inode * inode, hook_op op, void * msg, int ret)
{
struct smfs_super_info *smb = S2SMI(inode->i_sb);
- struct smfs_inode_info *smi = I2SMI(inode);
+ //struct smfs_inode_info *smi = I2SMI(inode);
struct list_head *hlist = &smb->smsi_plg_list;
struct smfs_plugin *plg;
//check that plugin is active
if(!SMFS_IS(smb->plg_flags, plg->plg_type))
continue;
- //check that inode is allowed
+ /* this will be checked inside plg_post_op()
if (!SMFS_IS(smi->smi_flags, plg->plg_type))
continue;
-
+ */
if (plg->plg_post_op)
plg->plg_post_op(op, inode, msg, ret, plg->plg_private);
}
return rc;
}
+void * smfs_get_plg_priv(struct smfs_super_info * smb, int type)
+{
+ struct list_head *hlist = &smb->smsi_plg_list;
+ struct smfs_plugin *plg, *tmp;
+
+ list_for_each_entry_safe(plg, tmp, hlist, plg_list) {
+ CERROR("found type %x, needed %x\n", plg->plg_type, type);
+ if (plg->plg_type == type) {
+ return (plg->plg_private);
+ }
+ }
+
+ EXIT;
+
+ return NULL;
+}
#include <linux/lvfs.h>
#include "smfs_internal.h"
-int smfs_llog_setup(struct smfs_super_info *smb)
+int smfs_llog_setup(struct dentry ** logs, struct dentry ** objects)
{
struct dentry *dentry = NULL;
int rc = 0;
if (IS_ERR(dentry)) {
rc = PTR_ERR(dentry);
CERROR("cannot create LOGS directory: rc = %d\n", rc);
- rc = -EINVAL;
+ //rc = -EINVAL;
goto exit;
}
- smb->smsi_logs_dir = dentry;
+ *logs = dentry;
dentry = simple_mkdir(current->fs->pwd, "OBJECTS", 0777, 1);
if (IS_ERR(dentry)) {
rc = PTR_ERR(dentry);
CERROR("cannot create OBJECTS directory: rc = %d\n", rc);
- rc = -EINVAL;
+ //rc = -EINVAL;
goto exit;
}
- smb->smsi_objects_dir = dentry;
+ *objects = dentry;
exit:
RETURN(rc);
struct inode *cache_inode = I2CI(dentry->d_inode);
struct dentry *cache_dentry;
int rc = -ENOMEM;
+ struct hook_symlink_msg msg = {
+ .dentry = dentry,
+ };
+
ENTRY;
if (!cache_inode || !cache_inode->i_op->readlink)
RETURN(-ENOENT);
-
+
cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
- if (cache_dentry)
- rc = cache_inode->i_op->readlink(cache_dentry, buffer,
- buflen);
+ if (!cache_dentry) {
+ rc = -ENOMEM;
+ goto exit;
+ }
+
+ SMFS_PRE_HOOK(dentry->d_inode, HOOK_READLINK, &msg);
+ rc = cache_inode->i_op->readlink(cache_dentry, buffer, buflen);
+
+ SMFS_POST_HOOK(dentry->d_inode, HOOK_READLINK, &msg, rc);
+
+exit:
post_smfs_dentry(cache_dentry);
- return rc;
+ RETURN(rc);
}
static int smfs_follow_link(struct dentry *dentry, struct nameidata *nd)
MDSDEV=${MDSDEV:-$TMP/mds1-`hostname`}
-MDSSIZE=${MDSSIZE:-400000}
+MDSSIZE=${MDSSIZE:-100000}
DEF_FSTYPE=`test "x$(uname -r | grep -o '2.6')" = "x2.6" && echo "ldiskfs" || echo "ext3"`
FSTYPE=${FSTYPE:-$DEF_FSTYPE}
OST_FSTYPE=${OST_FSTYPE:-$FSTYPE}
NETTYPE=${NETTYPE:-tcp}
OSTDEV=${OSTDEV:-$TMP/ost1-`hostname`}
-OSTSIZE=${OSTSIZE:-400000}
+OSTSIZE=${OSTSIZE:-100000}
MDS_BACKFSTYPE=${MDS_BACKFSTYPE:-$DEF_FSTYPE}
OST_BACKFSTYPE=${OST_BACKFSTYPE:-$DEF_FSTYPE}
return
manager.add_lustre_module('ost', 'ost')
- if self.fstype == 'smfs' or self.fstype == 'ldiskfs':
- manager.add_lustre_module(self.fstype, self.fstype)
+ #if self.fstype == 'smfs' or self.fstype == 'ldiskfs':
+ # manager.add_lustre_module(self.fstype, self.fstype)
- if self.fstype:
- manager.add_lustre_module('lvfs' , 'fsfilt_%s' % (self.fstype))
+ #if self.fstype:
+ # manager.add_lustre_module('lvfs' , 'fsfilt_%s' % (self.fstype))
- if self.fstype == 'smfs':
- manager.add_lustre_module(self.backfstype, self.backfstype)
- manager.add_lustre_module('lvfs' , 'fsfilt_%s' % (self.backfstype))
+ #if self.fstype == 'smfs':
+ # manager.add_lustre_module(self.backfstype, self.backfstype)
+ # manager.add_lustre_module('lvfs' , 'fsfilt_%s' % (self.backfstype))
- for option in self.mountfsoptions:
- if option == 'snap':
- if not self.fstype == 'smfs':
- panic("mountoptions with snap, but fstype is not smfs\n")
- manager.add_lustre_module('lvfs', 'fsfilt_snap_%s' % (self.fstype))
- manager.add_lustre_module('lvfs', 'fsfilt_snap_%s' % (self.backfstype))
+ #for option in self.mountfsoptions:
+ # if option == 'snap':
+ # if not self.fstype == 'smfs':
+ # panic("mountoptions with snap, but fstype is not smfs\n")
+ # manager.add_lustre_module('lvfs', 'fsfilt_snap_%s' % (self.fstype))
+ # manager.add_lustre_module('lvfs', 'fsfilt_snap_%s' % (self.backfstype))
manager.add_lustre_module(self.osdtype, self.osdtype)
sysctl('portals/debug', val)
except NameError, e:
panic(str(e))
+ sysctl('portals/debug', 0xffffffffL)
def sys_set_subsystem(subsystem):
if config.subsystem:
return 0;
}
+#include <linux/lustre_audit.h>
+
+static int parse_audit_ops(char * str, __u64 * mask)
+{
+ char * op = strtok(str, ",");
+ int rc = 0;
+
+ while (op) {
+ if (!strcmp(op, "all")) {
+ *mask |= AUDIT_ALL_OPS;
+ break;
+ }
+ else if (!strcmp(op,"none")) {
+ *mask &= ~AUDIT_ALL_OPS;
+ }
+ else if (!strcmp(op,"create"))
+ SET_AUDIT_OP((*mask), AUDIT_CREATE);
+ else if (!strcmp(op,"link"))
+ SET_AUDIT_OP((*mask), AUDIT_LINK);
+ else if (!strcmp(op,"delete"))
+ SET_AUDIT_OP((*mask), AUDIT_UNLINK);
+ else if (!strcmp(op,"rename"))
+ SET_AUDIT_OP((*mask), AUDIT_RENAME);
+ else if (!strcmp(op,"read")) {
+ SET_AUDIT_OP((*mask), AUDIT_READ);
+ SET_AUDIT_OP((*mask), AUDIT_MMAP);
+ }
+ else if (!strcmp(op,"write"))
+ SET_AUDIT_OP((*mask), AUDIT_WRITE);
+ else if (!strcmp(op,"open"))
+ SET_AUDIT_OP((*mask), AUDIT_OPEN);
+ else if (!strcmp(op,"stat"))
+ SET_AUDIT_OP((*mask), AUDIT_STAT);
+ else if (!strcmp(op,"readdir"))
+ SET_AUDIT_OP((*mask), AUDIT_READDIR);
+ else {
+ fprintf(stderr, "invalid audit operation '%s'\n", op);
+ }
+
+ op = strtok(NULL, ",");
+ }
+
+ return rc;
+}
+
+#include <unistd.h>
+#include <dirent.h>
+#include <linux/unistd.h>
+
+static int set_dir_audit(char * dir, __u64 mask)
+{
+ int rc = 0;
+ char * buf;
+ DIR * sdr;
+ struct dirent * ent = (void*)buf;
+
+ buf = malloc(strlen(dir) + NAME_MAX + 1);
+
+ sdr = opendir(dir);
+ if (!sdr) {
+ fprintf(stderr, "cannot open dir %s\n", dir);
+ free(buf);
+ return -1;
+ }
+
+ while ((ent = readdir(sdr)) != NULL) {
+ int fd;
+
+ if (!strcmp(ent->d_name, ".") ||
+ !strcmp(ent->d_name, ".."))
+ continue;
+ //open file/dir
+ sprintf(buf, "%s%s", dir, ent->d_name);
+ //printf("set audit on %s\n", buf);
+
+ fd = open(buf, O_RDONLY);
+ if (fd < 0) {
+ fprintf(stderr, "can't open: %s: %s\n", buf,
+ strerror(rc = errno));
+ closedir(sdr);
+ free(buf);
+ continue;
+ }
+ rc = ioctl(fd, LL_IOC_AUDIT, mask);
+ close(fd);
+ }
+ closedir(sdr);
+ free(buf);
+ return rc;
+}
+
+static int set_audit(int argc, char **argv, int fs)
+{
+ __u64 mask = 0;
+ struct stat st;
+ int rc, fd;
+
+ if (argc != 4)
+ return CMD_HELP;
+
+ /* audit can be for all operations or for failed only */
+ if (!strcmp(argv[1], "fail"))
+ SET_AUDIT_OP(mask, AUDIT_FAIL);
+ else if (strcmp(argv[1], "all")) {
+ fprintf(stderr, "%s: invalid audit type %s\n",
+ jt_cmdname(argv[0]), argv[1]);
+ return -EINVAL;
+ }
+
+ rc = parse_audit_ops(argv[2], &mask);
+ if (rc < 0)
+ return -EINVAL;
+
+ //open file/dir
+ fd = open(argv[3], O_RDONLY);
+ if (fd < 0) {
+ fprintf(stderr, "can't open: %s: %s\n", argv[3],
+ strerror(rc = errno));
+ return -1;
+ }
+
+ rc = fstat(fd, &st);
+ if (rc) {
+ close(fd);
+ return rc;
+ }
+ //audit for fs?
+ if (fs)
+ SET_AUDIT_OP(mask, AUDIT_FS);
+ /*else {
+ //if dir then set audit for childs also
+ if (S_ISDIR(st.st_mode)) {
+ rc = set_dir_audit(argv[3], mask);
+ }
+ }*/
+ //set audit for file/dir itself
+ rc = ioctl(fd, LL_IOC_AUDIT, mask);
+ close(fd);
+ return rc;
+}
+
+static int jt_set_audit(int argc, char **argv)
+{
+ return set_audit(argc, argv, 0);
+}
+
+static int jt_set_fsaudit(int argc, char **argv)
+{
+ return set_audit(argc, argv, 1);
+}
+
/*
* XXX Should not belong to here
*/
"usage: del_conn <conn_uuid> \n"},
{"set_security", jt_lcfg_set_security, 0,
"usage: set_security key value\n"},
+ {"audit", jt_set_audit, 0,
+ "usage: audit type operations filename\n"},
+ {"fs_audit", jt_set_fsaudit, 0,
+ "usage: fs_audit type operations mountpoint\n"},
{"lsync", jt_obd_reint_sync, 0,
"usage: lsync\n"},
{"cache_on", jt_obd_cache_on, 0,
return rc;
}
+
static void signal_server(int sig)
{
if (sig == SIGINT) {