#include "conf.h" #include "net.h" #include "logdump.h" static bool fill_packet(void *_buf, u32 available_len, u32 *_len) { struct kmsg_dumper saved; bool okay; u8 *buf = _buf; u32 len = 0; size_t used_len; do { // Save the dumper to restore it if message does not fit saved = conf->logdump.dumper; okay = kmsg_dump_get_line(&conf->logdump.dumper, false, buf, available_len - len, &used_len); // pr_err("Test: %p, %d, %d, %d\n", buf, available_len, len, used_len); if (!okay) { break; } // used all available space, means message does not fit if (available_len - len == used_len || used_len == 0) { // If this is not the first we can rollback and send the line in the next package // If it is the first, the line is way to long and we send it turncated to make progress. if (len != 0) { // Restore dumper conf->logdump.dumper = saved; // Don't account this line used_len = 0; } // Simulate that we don't have any space anymoe available_len = len; } // Account for written line buf += used_len; len += used_len; } while (len < available_len); *_len = len; return okay; } int avm_coredump_logdump_init(void) { return 0; } void avm_coredump_logdump_exit(void) {} int avm_coredump_logdump_do(void) { u8 *tbuf; u32 available_size; u32 used_size; bool okay; int ret; int pkgs = 0; conf->logdump.dumper.active = true; kmsg_dump_rewind(&conf->logdump.dumper); if (conf->family == AF_INET6) { pr_err(LOG_PREFIX "Sending log dump to %pI6c (port=%d, mac=%pM)...\n", conf->target_ip, conf->logdump_port, conf->target_mac); } else { pr_err(LOG_PREFIX "Sending log dump to %pI4 (port=%d, mac=%pM)...\n", conf->target_ip, conf->logdump_port, conf->target_mac); } do { avm_coredump_net_prepare_pkg(conf->logdump_port, &tbuf, &available_size); okay = fill_packet(tbuf, available_size, &used_size); ret = avm_coredump_net_send_pkg(used_size); if (ret != 0) { goto fail; } pkgs++; } while(okay && used_size > 0); pr_err(LOG_PREFIX "Send %d packages.\n", pkgs); fail: return ret; }