Skip to content

Commit

Permalink
fix(kmod): restore sys/module debug (#343)
Browse files Browse the repository at this point in the history
Signed-off-by: veqcc <ryuta.kambe@tier4.jp>
  • Loading branch information
veqcc authored Jan 31, 2025
1 parent e532099 commit 51addd2
Showing 1 changed file with 245 additions and 8 deletions.
253 changes: 245 additions & 8 deletions kmod/agnocast.c
Original file line number Diff line number Diff line change
Expand Up @@ -456,29 +456,266 @@ static int insert_message_entry(
// =========================================
// "/sys/module/agnocast/status/*"

// NOTE:
// show_xx may overflow when used more than PAGE_SIZE.
// The implementations have few error-handling.

// Example
//
// $ sudo cat /sys/module/agnocast/status/process_list
// process: pid=123, addr=4398046511104, size=67108864
// publisher
// /my_dynamic_topic
// /my_static_topic
// subscription
//
// process: pid=456, addr=4398180728832, size=16777216
// publisher
// subscription
// /my_dynamic_topic
// /my_static_topic
//
// process: pid=789, addr=4398113619968, size=67108864
// publisher
// /my_dynamic_topic
// subscription
// /my_static_topic
static ssize_t show_processes(struct kobject * kobj, struct kobj_attribute * attr, char * buf)
{
// TODO
return 0;
mutex_lock(&global_mutex);

int used_size = 0;
int ret;

struct process_info * proc_info;
int bkt_proc_info;
hash_for_each(proc_info_htable, bkt_proc_info, proc_info, node)
{
ret = scnprintf(
buf + used_size, PAGE_SIZE - used_size, "process: pid=%u, addr=%llu, size=%llu\n",
proc_info->pid, proc_info->shm_addr, proc_info->shm_size);
used_size += ret;

ret = scnprintf(buf + used_size, PAGE_SIZE - used_size, " publisher\n");
used_size += ret;

struct topic_wrapper * wrapper;
int bkt_topic;
hash_for_each(topic_hashtable, bkt_topic, wrapper, node)
{
struct publisher_info * pub_info;
int bkt_pub_info;
hash_for_each(wrapper->topic.pub_info_htable, bkt_pub_info, pub_info, node)
{
if (proc_info->pid == pub_info->pid) {
ret = scnprintf(buf + used_size, PAGE_SIZE - used_size, " %s\n", wrapper->key);
used_size += ret;
}
}
}

ret = scnprintf(buf + used_size, PAGE_SIZE - used_size, " subscription\n");
used_size += ret;

hash_for_each(topic_hashtable, bkt_topic, wrapper, node)
{
struct subscriber_info * sub_info;
int bkt_sub_info;
hash_for_each(wrapper->topic.sub_info_htable, bkt_sub_info, sub_info, node)
{
if (proc_info->pid == sub_info->pid) {
ret = scnprintf(buf + used_size, PAGE_SIZE - used_size, " %s\n", wrapper->key);
used_size += ret;
}
}
}

ret = scnprintf(buf + used_size, PAGE_SIZE - used_size, "\n");
used_size += ret;
}

if (used_size >= PAGE_SIZE) {
dev_warn(agnocast_device, "Exceeding PAGE_SIZE. Truncating output...\n");
mutex_unlock(&global_mutex);
return -ENOSPC;
}

mutex_unlock(&global_mutex);
return used_size;
}

// Example
//
// $ sudo cat /sys/module/agnocast/status/topic_list
// topic: /my_dynamic_topic
// publisher: 15198, 15171,
// subscription: 15237,
//
// topic: /my_static_topic
// publisher: 15171,
// subscription: 15237, 15198,
static ssize_t show_topics(struct kobject * kobj, struct kobj_attribute * attr, char * buf)
{
// TODO
return 0;
mutex_lock(&global_mutex);

int used_size = 0;
int ret;

struct topic_wrapper * wrapper;
int bkt_topic;
hash_for_each(topic_hashtable, bkt_topic, wrapper, node)
{
ret = scnprintf(buf + used_size, PAGE_SIZE - used_size, "topic: %s\n", wrapper->key);
used_size += ret;

ret = scnprintf(buf + used_size, PAGE_SIZE - used_size, " publisher:");
used_size += ret;

struct publisher_info * pub_info;
int bkt_pub_info;
hash_for_each(wrapper->topic.pub_info_htable, bkt_pub_info, pub_info, node)
{
ret = scnprintf(buf + used_size, PAGE_SIZE - used_size, " %d,", pub_info->pid);
used_size += ret;
}

ret = scnprintf(buf + used_size, PAGE_SIZE - used_size, "\n");
used_size += ret;

ret = scnprintf(buf + used_size, PAGE_SIZE - used_size, " subscription:");
used_size += ret;

struct subscriber_info * sub_info;
int bkt_sub_info;
hash_for_each(wrapper->topic.sub_info_htable, bkt_sub_info, sub_info, node)
{
ret = scnprintf(buf + used_size, PAGE_SIZE - used_size, " %d,", sub_info->pid);
used_size += ret;
}

ret = scnprintf(buf + used_size, PAGE_SIZE - used_size, "\n\n");
used_size += ret;
}

if (used_size >= PAGE_SIZE) {
dev_warn(agnocast_device, "Exceeding PAGE_SIZE. Truncating output...\n");
mutex_unlock(&global_mutex);
return -ENOSPC;
}

mutex_unlock(&global_mutex);
return used_size;
}

static char * debug_topic_name;

// Example
// $ echo "/my_dynamic_topic" | sudo tee /sys/module/agnocast/status/topic_info
static ssize_t store_topic_name(
struct kobject * kobj, struct kobj_attribute * attr, const char * buf, size_t count)
{
// TODO
return 0;
mutex_lock(&global_mutex);

if (debug_topic_name) {
kfree(debug_topic_name);
}

debug_topic_name = kstrdup(buf, GFP_KERNEL);
if (!debug_topic_name) {
dev_warn(agnocast_device, "kstrdup failed\n");
}

mutex_unlock(&global_mutex);
return count;
}

// Example
//
// $ sudo cat /sys/module/agnocast/status/topic_info
// topic: /my_dynamic_topic
// publisher: 9495, 9468,
// subscription: 9534,
// entries:
// time=123456, topic_local_id=0, addr=4398118383424, published=1, referencing=[9534,]
// time=123457, topic_local_id=1, addr=4398051231552, published=1, referencing=[]
static ssize_t show_topic_info(struct kobject * kobj, struct kobj_attribute * attr, char * buf)
{
// TODO
return 0;
mutex_lock(&global_mutex);

int used_size = 0;
int ret;

ret = scnprintf(buf + used_size, PAGE_SIZE - used_size, "topic: %s", debug_topic_name);
used_size += ret;

if (!debug_topic_name) {
mutex_unlock(&global_mutex);
return ret;
}

struct topic_wrapper * wrapper;
int bkt_topic;
hash_for_each(topic_hashtable, bkt_topic, wrapper, node)
{
if (strncmp(debug_topic_name, wrapper->key, strlen(wrapper->key)) != 0) continue;

ret = scnprintf(buf + used_size, PAGE_SIZE - used_size, " publisher:");
used_size += ret;

struct publisher_info * pub_info;
int bkt_pub_info;
hash_for_each(wrapper->topic.pub_info_htable, bkt_pub_info, pub_info, node)
{
ret = scnprintf(buf + used_size, PAGE_SIZE - used_size, " %d,", pub_info->pid);
used_size += ret;
}

ret = scnprintf(buf + used_size, PAGE_SIZE - used_size, "\n subscription:");
used_size += ret;

struct subscriber_info * sub_info;
int bkt_sub_info;
hash_for_each(wrapper->topic.sub_info_htable, bkt_sub_info, sub_info, node)
{
ret = scnprintf(buf + used_size, PAGE_SIZE - used_size, " %d,", sub_info->pid);
used_size += ret;
}

ret = scnprintf(buf + used_size, PAGE_SIZE - used_size, "\n entries:\n");
used_size += ret;

struct rb_root * root = &wrapper->topic.entries;
struct rb_node * node;
for (node = rb_first(root); node; node = rb_next(node)) {
struct entry_node * en = container_of(node, struct entry_node, node);

ret = scnprintf(
buf + used_size, PAGE_SIZE - used_size,
" time=%lld, topic_local_id=%u, addr=%lld, published=%d, referencing=[", en->timestamp,
en->publisher_id, en->msg_virtual_address, en->published);
used_size += ret;

for (int i = 0; i < MAX_SUBSCRIBER_NUM; i++) {
if (en->referencing_subscriber_ids[i] == -1) break;

ret = scnprintf(
buf + used_size, PAGE_SIZE - used_size, "%u,", en->referencing_subscriber_ids[i]);
used_size += ret;
}

ret = scnprintf(buf + used_size, PAGE_SIZE - used_size, "]\n");
used_size += ret;
}
}

if (used_size >= PAGE_SIZE) {
dev_warn(agnocast_device, "Exceeding PAGE_SIZE. Truncating output...\n");
mutex_unlock(&global_mutex);
return -ENOSPC;
}

mutex_unlock(&global_mutex);
return used_size;
}

static struct kobject * status_kobj;
Expand Down

0 comments on commit 51addd2

Please sign in to comment.