Whamcloud - gitweb
add null_audit command to lctl which will make audit silent. For testing purposes.
[fs/lustre-release.git] / lustre / smfs / audit.c
index 8134204..fd83c0c 100644 (file)
@@ -132,16 +132,22 @@ static inline int smfs_get_inode_audit(struct inode *inode, __u64 *mask)
         struct smfs_inode_info * smi = I2SMI(inode);
         int rc = 0;
         
+        /* omit __iopen__ dir */
+        if (inode->i_ino == SMFS_IOPEN_INO) {
+                *mask = AUDIT_OFF;
+                RETURN(-ENOENT);
+        }
         if (smi->au_info.au_valid)
                 *mask = smi->au_info.au_mask;
         else {
-                rc = fsfilt->fs_get_xattr(I2CI(inode), AUDIT_ATTR_EA, mask, sizeof(*mask));
+                rc = fsfilt->fs_get_xattr(I2CI(inode), AUDIT_ATTR_EA,
+                                          mask, sizeof(*mask));
                 if (rc <= 0)
                         *mask = AUDIT_OFF;
                 smi->au_info.au_valid = 1;
                 smi->au_info.au_mask = *mask;
         }
-        return 0;
+        RETURN(0);
 }
 
 /* is called also from fsfilt_smfs_get_info */
@@ -149,9 +155,7 @@ 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;
         struct obd_device * obd = smb->smsi_exp->exp_obd;
-        int rc;
         struct audit_priv * priv = NULL;
         
         ENTRY;
@@ -161,10 +165,6 @@ int smfs_get_audit(struct super_block * sb, struct inode * parent,
         
         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);
         
@@ -176,18 +176,20 @@ int smfs_get_audit(struct super_block * sb, struct inode * parent,
                 (*mask) = priv->a_mask;
                 RETURN(0);
         }
-        /* get inode audit EA */
-        smfs_get_inode_audit(parent, mask);
-        /* check if parent has audit */
-        if (IS_AUDIT(*mask))
-                RETURN(0);
         
-        if (!inode)
-                RETURN(-ENOENT);
+        /* get inode audit EA */
+        if (parent) {
+                smfs_get_inode_audit(parent, mask);
+                /* check if parent has audit */
+                if (IS_AUDIT(*mask))
+                        RETURN(0);
+        }
         
-        smfs_get_inode_audit(inode, mask);
-        if (IS_AUDIT(*mask))
-                RETURN(0);
+        if (inode) {
+                smfs_get_inode_audit(inode, mask);
+                if (IS_AUDIT(*mask))
+                        RETURN(0);
+        }
 
         RETURN(-ENODATA);
 }
@@ -196,6 +198,7 @@ int smfs_audit_check(struct inode * parent, hook_op hook, int ret,
                      struct audit_priv * priv, void * msg)
 {
         audit_op code;
+        struct inode * inode = NULL;
         __u64 mask = 0;
         int rc = 0;
         
@@ -204,15 +207,18 @@ int smfs_audit_check(struct inode * parent, hook_op hook, int ret,
         if (hook == HOOK_SPECIAL) { 
                 struct audit_info * info = msg;
                 code = info->m.code;
+                inode = info->child;
         }
-        else
+        else {
+                inode = get_inode_from_hook(hook, msg);
                 code = hook2audit(hook);
-
-        rc = smfs_get_audit(parent->i_sb, parent,
-                            get_inode_from_hook(hook, msg),
-                            &mask);
+        }
+        
+        rc = smfs_get_audit(parent->i_sb, parent, inode, &mask);
+        
         if (rc < 0)
                 RETURN(0);
+
         //should only failures be audited?
         if (ret >= 0 && IS_AUDIT_OP(mask, AUDIT_FAIL))
                 RETURN(0); 
@@ -272,15 +278,40 @@ int smfs_set_audit(struct super_block * sb, struct inode * inode,
 {
         void * handle = NULL;
         struct fsfilt_operations * fsfilt = S2SMI(sb)->sm_fsfilt;
-        struct smfs_inode_info *smi = I2SMI(inode);
+        struct smfs_inode_info *smi = NULL;
         int rc = 0;
+        struct audit_priv *priv;
+        
+        priv = smfs_get_plg_priv(S2SMI(sb), SMFS_PLG_AUDIT);
         
         ENTRY;
         
+        if (IS_AUDIT_OP((*mask), AUDIT_SYNC)) {
+                struct audit_priv *priv;
+                
+                priv = smfs_get_plg_priv(S2SMI(sb), SMFS_PLG_AUDIT);
+                if (priv)
+                        audit_notify(priv->audit_ctxt->loc_handle, NULL, 1);
+                //to wait for flush
+                return audit_notify(NULL, NULL, 1);
+        }
+        
+        if (IS_AUDIT_OP((*mask), AUDIT_NULL)) {
+                if (priv)
+                        priv->audit_null ^= 1;
+                return 0;
+        }
+
         if (IS_AUDIT_OP((*mask), AUDIT_FS))
                 return smfs_set_fs_audit(sb, mask);
 
         LASSERT(inode);
+        smi = I2SMI(inode);
+        /* save audit EA in inode_info */
+        if (rc >= 0) {
+                smi->au_info.au_mask = *mask;
+                smi->au_info.au_valid = 1;
+        }
         
         handle = fsfilt->fs_start(inode, FSFILT_OP_SETATTR, NULL, 0);
         if (IS_ERR(handle))
@@ -289,12 +320,6 @@ int smfs_set_audit(struct super_block * sb, struct inode * inode,
         if (fsfilt->fs_set_xattr)
                 rc = fsfilt->fs_set_xattr(inode, handle, AUDIT_ATTR_EA,
                                           mask, sizeof(*mask));
-        /* save audit EA in inode_info */
-        if (rc >= 0) {
-                smi->au_info.au_mask = *mask;
-                smi->au_info.au_valid = 1;
-        }
-        
         fsfilt->fs_commit(inode->i_sb, inode, handle, 1);
         RETURN(rc);
                                 
@@ -352,8 +377,10 @@ static int smfs_audit_post_op(hook_op code, struct inode * inode, void * msg,
         if (rc != 0) {
                 CERROR("Error adding audit record: %d\n", rc);
                 rc= -EINVAL;
-        } else {
-                audit_notify(priv->audit_ctxt->loc_handle, priv->au_id2name);
+        /* delay notify for create op */
+        } else if (!(code == HOOK_CREATE && ret == 0)) { 
+                audit_notify(priv->audit_ctxt->loc_handle, priv->au_id2name,
+                             priv->audit_null);
         }
         
         OBD_FREE(buffer, PAGE_SIZE);
@@ -411,6 +438,7 @@ static int smfs_start_audit(struct super_block *sb, void *arg,
         }
         //read fs audit settings if any
        audit_p->a_mask = AUDIT_OFF;
+        audit_p->audit_null = 0;
 
         f = filp_open(AUDIT_ATTR_FILE, O_RDONLY, 0644);
         if (!IS_ERR(f)) {
@@ -606,7 +634,7 @@ int audit_client_log(struct super_block * sb, struct audit_msg * msg)
                 CERROR("Error adding audit client record: %d\n", rc);
                 rc= -EINVAL;
         } else {
-                audit_notify(ll_handle, priv->au_id2name);
+                audit_notify(ll_handle, priv->au_id2name, priv->audit_null);
         }
         
         OBD_FREE(buffer, PAGE_SIZE);