[9610] wlbt: WLBTD collect log files and tar them
authorPurnendu Kapadia <p.kapadia@samsung.com>
Wed, 18 Jul 2018 14:46:58 +0000 (15:46 +0100)
committerhskang <hs1218.kang@samsung.com>
Fri, 17 Aug 2018 00:32:59 +0000 (20:32 -0400)
For SBL support, we need wlbtd to collect various logs into a single tarball.
This patch adds the driver side changes to support this. A new EVENT_SABLE
and supporting infrastructure is introduced to handle trigger from log collection
(with reason for generating .sbl file) and EVENT_SABLE sent to wlbtd to generate
other logs (logcat, dmesg, mx.dump etc) and create tar containing .sbl file alongwith other logs.

for generating a tar this change dependens on change to wlbtd with EVENT_SABLE support.

Change-Id: I7a356327ef8cb74d5ff5cb7ce3fd12b880127601
SCSC-Bug-Id: SSB-41551
Signed-off-by: Purnendu Kapadia <p.kapadia@samsung.com>
drivers/misc/samsung/scsc/mxman.c
drivers/misc/samsung/scsc/scsc_log_collector.c
drivers/misc/samsung/scsc/scsc_wlbtd.c
drivers/misc/samsung/scsc/scsc_wlbtd.h

index 79fedb07afee0c41fa0a7a54d5e92e65f009d812..d85fcbcf7ec13f2d558f78be8b5d2e06d47aa9e5 100755 (executable)
@@ -1297,7 +1297,16 @@ static void mxman_failure_work(struct work_struct *work)
                                /* we can safely call call_wlbtd as we are
                                 * in workqueue context
                                 */
+#ifdef CONFIG_SCSC_LOG_COLLECTION
+                               /* Collect mxlogger logs */
+                               r = scsc_log_collector_collect(SCSC_LOG_REASON_FW_PANIC);
+                               if (r != 0)
+                                       SCSC_TAG_INFO(MXMAN, "sable creation failed.");
+                               /* call old method to generate moredump anyway */
+                               r = call_wlbtd(SCSC_SCRIPT_MOREDUMP);
+#else
                                r = call_wlbtd(SCSC_SCRIPT_MOREDUMP);
+#endif
 #else
                                r = coredump_helper();
 #endif
@@ -1339,10 +1348,6 @@ static void mxman_failure_work(struct work_struct *work)
                if (mif->mif_cleanup && mxman_recovery_disabled())
                        mif->mif_cleanup(mif);
        }
-#ifdef CONFIG_SCSC_LOG_COLLECTION
-       /* Collect mxlogger logs */
-       scsc_log_collector_collect(SCSC_LOG_REASON_FW_PANIC);
-#endif
 
        if (!mxman_recovery_disabled())
                srvman_clear_error(srvman);
@@ -1408,7 +1413,12 @@ static void print_mailboxes(struct mxman *mxman)
 static void wlbtd_work_func(struct work_struct *work)
 {
        /* require sleep-able workqueue to run successfully */
+#ifdef CONFIG_SCSC_LOG_COLLECTION
+       /* Collect mxlogger logs */
+       scsc_log_collector_collect(SCSC_LOG_REASON_WLAN_DISCONNECT);
+#else
        call_wlbtd(SCSC_SCRIPT_LOGGER_DUMP);
+#endif
 }
 
 static void wlbtd_wq_init(struct mxman *mx)
index 7874d32fa70435f31096e9ef6650e1f2b2713f5d..5de3cb990cc673ec5e8033d283b3ff3de82e5349 100644 (file)
@@ -18,6 +18,9 @@
 #include <scsc/scsc_log_collector.h>
 #include "scsc_log_collector_proc.h"
 #include <scsc/scsc_mx.h>
+#ifdef CONFIG_SCSC_WLBTD
+#include "scsc_wlbtd.h"
+#endif
 
 #define SCSC_NUM_CHUNKS_SUPPORTED      12
 
@@ -42,7 +45,7 @@ static bool collect_to_ram;
 module_param(collect_to_ram, bool, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(collect_to_ram, "Collect buffer in ram");
 
-static char collection_dir_buf[256] = "/data/exynos/log/wifi/";
+static char collection_dir_buf[256] = "/data/exynos/log/wifi";
 module_param_string(collection_target_directory, collection_dir_buf, sizeof(collection_dir_buf), S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(collection_target_directory, "Specify collection target directory");
 
@@ -222,8 +225,11 @@ static inline int __scsc_log_collector_collect_to_ram(enum scsc_log_reason reaso
 #define align_chunk(ppos) (((ppos) + (SCSC_LOG_CHUNK_ALIGN - 1)) & \
                          ~(SCSC_LOG_CHUNK_ALIGN - 1))
 
-const char *scsc_loc_reason_str[] = { "unknown", "fw_panic", "host_trig",
-                                     "fw_trig", "dumpstate", "wlan_disc", "bt_trig" /* Add others */};
+const char *scsc_loc_reason_str[] = { "unknown", "scsc_log_fw_panic",
+                                     "scsc_log_host_trig",
+                                     "scsc_log_fw_trig", "scsc_log_dumpstate",
+                                     "scsc_log_wlan_trig", "scsc_log_bt_trig",
+                                     "scsc_log_common_trig"/* Add others */};
 
 static inline int __scsc_log_collector_collect_to_file(enum scsc_log_reason reason)
 {
@@ -251,8 +257,8 @@ static inline int __scsc_log_collector_collect_to_file(enum scsc_log_reason reas
        do_gettimeofday(&t);
        time_to_tm(t.tv_sec, 0, &tm_n);
 
-       snprintf(memdump_path, sizeof(memdump_path), "%s%s_%s.sbl",
-                collection_dir_buf, "scsc_log", scsc_loc_reason_str[reason]);
+       snprintf(memdump_path, sizeof(memdump_path), "%s/%s.sbl",
+                collection_dir_buf, scsc_loc_reason_str[reason]);
 
        /* change to KERNEL_DS address limit */
        old_fs = get_fs();
@@ -349,7 +355,11 @@ exit:
 
        pr_info("File %s collection end. Took: %lld\n", memdump_path, ktime_to_ns(ktime_sub(ktime_get(), start)));
 
+#ifdef CONFIG_SCSC_WLBTD
+       call_wlbtd_sable(scsc_loc_reason_str[reason]);
+#endif
        mutex_unlock(&log_mutex);
+
        return ret;
 }
 
index 6951e8550f6360ba6874a87de7ca68de996582c5..b9c45857149b8fc1bedeb637fbe101bb94f2a6cc 100755 (executable)
@@ -22,17 +22,35 @@ static int msg_from_wlbtd_cb(struct sk_buff *skb, struct genl_info *info)
        int status;
 
        if (info->attrs[1])
-               SCSC_TAG_INFO(WLBTD, "wlbtd returned data : %s\n",
+               SCSC_TAG_INFO(WLBTD, "returned data : %s\n",
                                (char *)nla_data(info->attrs[1]));
 
        if (info->attrs[2]) {
                status = *((__u32 *)nla_data(info->attrs[2]));
                if (!status)
-                       SCSC_TAG_INFO(WLBTD,
-                               "wlbtd returned status : %u\n", status);
+                       SCSC_TAG_INFO(WLBTD, "returned status : %u\n", status);
                else
-                       SCSC_TAG_ERR(WLBTD,
-                               "wlbtd returned error : %u\n",  status);
+                       SCSC_TAG_ERR(WLBTD, "returned error : %u\n", status);
+       }
+
+       complete(&script_done);
+       return 0;
+}
+
+static int msg_from_wlbtd_sable_cb(struct sk_buff *skb, struct genl_info *info)
+{
+       int status;
+
+       if (info->attrs[1])
+               SCSC_TAG_INFO(WLBTD, "returned data : %s\n",
+                               (char *)nla_data(info->attrs[1]));
+
+       if (info->attrs[2]) {
+               status = nla_get_u16(info->attrs[2]);
+               if (!status)
+                       SCSC_TAG_INFO(WLBTD, "returned status : %u\n", status);
+               else
+                       SCSC_TAG_ERR(WLBTD, "returned error : %u\n", status);
        }
 
        complete(&script_done);
@@ -80,6 +98,11 @@ static struct nla_policy policies[] = {
        [ATTR_INT] = { .type = NLA_U32, },
 };
 
+static struct nla_policy policy_sable[] = {
+       [ATTR_STR] = { .type = NLA_STRING, },
+       [ATTR_INT] = { .type = NLA_U16, },
+};
+
 static struct nla_policy policies_build_type[] = {
        [ATTR_STR] = { .type = NLA_STRING, },
 };
@@ -102,6 +125,13 @@ const struct genl_ops scsc_ops[] = {
                .doit = msg_from_wlbtd_build_type_cb,
                .dumpit = NULL,
        },
+       {
+               .cmd = EVENT_SABLE,
+               .flags = 0,
+               .policy = policy_sable,
+               .doit = msg_from_wlbtd_sable_cb,
+               .dumpit = NULL,
+       },
 };
 
 /* The netlink family */
@@ -202,6 +232,98 @@ error:
        return -1;
 }
 
+int call_wlbtd_sable(const char *trigger)
+{
+       struct sk_buff *skb;
+       void *msg;
+       int rc = 0;
+       unsigned long completion_jiffies = 0;
+       unsigned long max_timeout_jiffies = msecs_to_jiffies(MAX_TIMEOUT);
+
+       SCSC_TAG_INFO(WLBTD, "start:trigger - %s\n", trigger);
+
+       skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+       if (!skb) {
+               SCSC_TAG_ERR(WLBTD, "Failed to construct message\n");
+               goto error;
+       }
+
+       SCSC_TAG_DEBUG(WLBTD, "create message\n");
+       msg = genlmsg_put(skb,
+                       0,              // PID is whatever
+                       0,              // Sequence number (don't care)
+                       &scsc_nlfamily, // Pointer to family struct
+                       0,              // Flags
+                       EVENT_SABLE     // Generic netlink command
+                       );
+       if (!msg) {
+               SCSC_TAG_ERR(WLBTD, "Failed to create message\n");
+               goto error;
+       }
+       /* TODO: change when we get passed proper code as well */
+       SCSC_TAG_DEBUG(WLBTD, "add values to msg\n");
+       rc = nla_put_u16(skb, ATTR_INT, 0xffff);
+       if (rc) {
+               SCSC_TAG_ERR(WLBTD, "nla_put_u16 failed. rc = %d\n", rc);
+               genlmsg_cancel(skb, msg);
+               goto error;
+       }
+
+       rc = nla_put_string(skb, ATTR_STR, trigger);
+       if (rc) {
+               SCSC_TAG_ERR(WLBTD, "nla_put_string failed. rc = %d\n", rc);
+               genlmsg_cancel(skb, msg);
+               goto error;
+       }
+
+       genlmsg_end(skb, msg);
+
+       SCSC_TAG_DEBUG(WLBTD, "finalize & send msg\n");
+       /* genlmsg_multicast_allns() frees skb */
+       rc = genlmsg_multicast_allns(&scsc_nlfamily, skb, 0, 0, GFP_KERNEL);
+
+       if (rc) {
+               if (rc == -ESRCH) {
+                       /* If no one registered to scsc_mcgrp (e.g. in case
+                        * wlbtd is not running) genlmsg_multicast_allns
+                        * returns -ESRCH. Ignore and return.
+                        */
+                       SCSC_TAG_WARNING(WLBTD, "WLBTD not running ?\n");
+                       return rc;
+               }
+               SCSC_TAG_ERR(WLBTD, "Failed to send message. rc = %d\n", rc);
+               return rc;
+       }
+
+       SCSC_TAG_INFO(WLBTD, "waiting for completion\n");
+
+       /* wait for script to finish */
+       completion_jiffies = wait_for_completion_timeout(&script_done,
+                                               max_timeout_jiffies);
+
+       if (completion_jiffies != max_timeout_jiffies) {
+
+               completion_jiffies = max_timeout_jiffies - completion_jiffies;
+               SCSC_TAG_INFO(WLBTD, "log collection done in %dms\n",
+                       (int)jiffies_to_msecs(completion_jiffies));
+       } else
+               SCSC_TAG_ERR(WLBTD, "wait for completion timed out !\n");
+
+       /* reinit so completion can be re-used */
+       reinit_completion(&script_done);
+
+       SCSC_TAG_INFO(WLBTD, "  end:trigger - %s\n", trigger);
+
+       return rc;
+
+error:
+       /* free skb */
+       nlmsg_free(skb);
+
+       return -1;
+}
+EXPORT_SYMBOL(call_wlbtd_sable);
+
 int call_wlbtd(const char *script_path)
 {
        struct sk_buff *skb;
index ef0cd12a76d19e3c7759219132d71d72ff7bb7a4..e54520969919a1c8ae8a98b6fb904466d15d03cf 100644 (file)
@@ -36,6 +36,7 @@ enum events {
 
        EVENT_SCSC,
        EVENT_SYSTEM_PROPERTY,
+       EVENT_SABLE,
 
        /* This must be last! */
        __EVENT_MAX,
@@ -48,4 +49,5 @@ static const struct genl_multicast_group scsc_mcgrp[] = {
 int scsc_wlbtd_init(void);
 int scsc_wlbtd_deinit(void);
 int call_wlbtd(const char *script_path);
+int call_wlbtd_sable(const char *trigger);
 int scsc_wlbtd_get_and_print_build_type(void);