Whamcloud - gitweb
add null_audit command to lctl which will make audit silent. For testing purposes.
[fs/lustre-release.git] / lustre / smfs / audit_transfer.c
index 5e58b0f..301d59e 100644 (file)
 #include <linux/lustre_log.h>
 #include "smfs_internal.h"
 
+struct tr_priv {
+        void *id2name;
+        int null;
+};
+
 struct transfer_item {
         struct llog_handle      *ti_llh;
         struct list_head        ti_link;
-        void * id2name;
+        struct tr_priv          priv;
 };
 
 #define TRANSFERD_STOP          0
@@ -60,7 +65,22 @@ static DECLARE_MUTEX(transferd_sem);
 static int transferd_users = 0;
 char *buf = NULL;
 
-int audit_notify(struct llog_handle *llh, void * arg)
+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);
+}
+
+int audit_notify(struct llog_handle *llh, void * arg, int null)
 {
         struct transfer_item *ti;
         ENTRY;
@@ -83,19 +103,27 @@ int audit_notify(struct llog_handle *llh, void * arg)
         
         INIT_LIST_HEAD(&ti->ti_link);
         ti->ti_llh = llh;
-        ti->id2name = arg;
+        ti->priv.id2name = arg;
+        ti->priv.null = null;
 
         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);
+        
+        if (llh == NULL) /* demand to flush list */
+        {
+                struct l_wait_info lwi = { 0 };
+                l_wait_event(transferd_tc.tc_waitq,
+                             transferd_check(&transferd_tc), &lwi);
+        }
 
         RETURN(0);
 }
                                                                                                                                                
 const char *opstr[AUDIT_MAX] = {
-        [AUDIT_NONE]     "null",
+        [AUDIT_UNKNOWN]  "unknown",
         [AUDIT_CREATE]   "create",
         [AUDIT_LINK]     "link",
         [AUDIT_UNLINK]   "unlink",
@@ -128,11 +156,12 @@ 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_id_record *)(rec + 1);
         struct audit_name_record *name_rec = NULL;
-        int (*audit_id2name)(struct obd_device *obd, char **name, 
-                     int *namelen, struct lustre_id *id) = data;
-
+        struct tr_priv * trp = data;
+        int (*audit_id2name)(struct obd_device *obd, char **name, int *namelen,
+                        struct lustre_id *id) = trp->id2name;
+        
         int n, rc = 0;
         ENTRY;
 
@@ -142,6 +171,8 @@ transfer_record(struct obd_device *obd, struct audit_record *rec, int type, void
         n = construct_header(buf, PAGE_SIZE, rec, id_rec);
         if (n < 0)
                 RETURN(n);
+        /* let's use remaining space */
+        n = PAGE_SIZE - n;
         
         switch (rec->opcode)
         {
@@ -154,7 +185,7 @@ transfer_record(struct obd_device *obd, struct audit_record *rec, int type, void
                 default:
                         break;
         }
-                
+        
         if (audit_id2name) {
                 char *name = NULL;
                 struct lustre_id id;
@@ -165,29 +196,33 @@ transfer_record(struct obd_device *obd, struct audit_record *rec, int type, void
                 //LASSERT(id_type(&id) & S_IFMT);
                 rc = audit_id2name(obd, &name, &namelen, &id);
                 if (rc < 0) {
-                        strncat(buf, "unknown", PAGE_SIZE - n);
-                        n += strlen("unknown");
+                        strncat(buf, "unknown", 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;
+                        strncat(buf, name, 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);
+
+        if (type == SMFS_AUDIT_NAME_REC && n > 0) {
+                name_rec = (struct audit_name_record *)(++id_rec);
+                strcat(buf, "/");
+                n -= 1;
+                /* get minimum size to copy name with exact len */
+                if (n > name_rec->name_len)
+                        n = name_rec->name_len; 
+                strncat(buf, name_rec->name, n);
         }
         
         CDEBUG(D_INFO, "%s\n", buf);
 
-        printk("%s\n", buf);
+        if (!trp->null)
+                printk("%s\n", buf);
 
         RETURN(0);
 }
@@ -230,29 +265,17 @@ static int audit_transfer(struct transfer_item *ti)
         struct llog_handle *llh = ti->ti_llh;
         int rc = 0;
         ENTRY;
+        
+        if (!llh)
+                RETURN(0);
 
-        rc = llog_cat_process(llh, (llog_cb_t)&transfer_cb, ti->id2name);
+        rc = llog_cat_process(llh, (llog_cb_t)&transfer_cb, &ti->priv);
         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;