Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(kmod): restore sys/module debug #343

Merged
merged 1 commit into from
Jan 31, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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