uid-Another Problem in writing to /proc/loadavg file

From: sena
Date: Mon Jan 12 2004 - 23:04:24 EST


Hi Robin,

Though I was able to run my code and get good results as a kernel module (This was everytime only one set of results per loading of the module).

Anyway I felt that it was hanging on a bit while values being calculated. (It looks like the host computer sends some messages to the users)

Thinking everything was well, I then integrated it to the kernel code with those extra loops of mine, this time there was nothing written to /proc/loadavg file.

First I thought that this was because the long list(5) of USER's UIDs I am saving in that file. (only 5)

Anyway it looks like that is not the real problem as I do calculate every 5 seconds and that seems to be enough time.


Robin for further Real testing I thought of first running it as a kernel module. Then this code has to be called every 5 seconds and will have to be scheduled as a task.?


I made the following attempt.

I have 2 questions for you.

What is this error about? THE ERROR WAS sched.o: unresolved symbol proc_unregister

Thanks
Sena Seneviratene
Computer Engineering Lab
Sydney University


sched.c
/* The necessary header files */

/* Standard in kernel modules */
#include <linux/kernel.h> /* We're doing kernel work */
#include <linux/module.h> /* Specifically, a module */

/* Deal with CONFIG_MODVERSIONS */
#if CONFIG_MODVERSIONS==1
#define MODVERSIONS
#include <linux/modversions.h>
#endif

/* Necessary because we use the proc fs */
#include <linux/proc_fs.h>

/* We scheduale tasks here */
#include <linux/tqueue.h>

/* We also need the ability to put ourselves to sleep * and wake up later */
#include <linux/sched.h>

/* In 2.2.3 /usr/include/linux/version.h includes a * macro for this, but 2.0.35 doesn't - so I add it * here if necessary. */
#ifndef KERNEL_VERSION
#define KERNEL_VERSION(a,b,c) ((a)*65536+(b)*256+(c))
#endif



/* The number of times the timer interrupt has been * called so far */
static int TimerIntrpt = 0;


/* This is used by cleanup, to prevent the module from * being unloaded while intrpt_routine is still in * the task queue */
static struct wait_queue *WaitQ = NULL;

static void intrpt_routine(void *);


/* The task queue structure for this task, from tqueue.h */
static struct tq_struct Task = {
NULL, /* Next item in list - queue_task will do * this for us */
0, /* A flag meaning we haven't been inserted * into a task queue yet */
intrpt_routine, /* The function to run */
NULL /* The void* parameter for that function */
};

/*IN THIS FUNCTION LOAD AVERAGE CALCULATIONS BE INCLUDED*/
static void intrpt_routine(void *irrelevant)
{
/* Increment the counter */
TimerIntrpt++;

/* If cleanup wants us to die */
if (WaitQ != NULL) wake_up(&WaitQ); /* Now cleanup_module can return */
else
/* Put ourselves back in the task queue */
queue_task(&Task, &tq_timer); }




/* Put data into the proc fs file. */
int procfile_read(char *buffer, char **buffer_location, off_t offset, int buffer_length, int zero)
{
int len; /* The number of bytes actually used */

static char my_buffer[80];

static int count = 1;

if (offset > 0)
return 0;

/* Fill the buffer and get its length */
len = sprintf(my_buffer, "Timer was called %d times so far\n", TimerIntrpt);
count++;

/* Tell the function which called us where the * buffer is */
*buffer_location = my_buffer;

/* Return the length */
return len;
}


struct proc_dir_entry Our_Proc_File = {
0, /* Inode number - ignore, it will be filled by * proc_register_dynamic */
5, /* Length of the file name */
"sched", /* The file name */
S_IFREG | S_IRUGO, /* File mode - this is a regular file which can
* be read by its owner, its group, and everybody
* else */
1, /* Number of links (directories where * the file is referenced) */
0, 0, /* The uid and gid for the file - we give * it to root */
80, /* The size of the file reported by ls. */
NULL, /* functions which can be done on the * inode (linking, removing, etc.) - we don't * support any. */
procfile_read, /* The read function for this file, the function called
* when somebody tries to read something from it. */
NULL /* We could have here a function to fill the * file's inode, to enable us to play with * permissions, ownership, etc. */
};


/* Initialize the module - register the proc file */
int init_module()
{
/* Put the task in the tq_timer task queue, so it * will be executed at next timer interrupt */
queue_task(&Task, &tq_timer);

/* Success if proc_register_dynamic is a success, * failure otherwise */
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,2,0)
return proc_register(&proc_root, &Our_Proc_File);
#else
return proc_register_dynamic(&proc_root, &Our_Proc_File);
#endif
}


/* Cleanup */
void cleanup_module()
{
/* Unregister our /proc file */
proc_unregister(&proc_root, Our_Proc_File.low_ino);
/* Sleep until intrpt_routine is called one last * time. This is necessary, because otherwise we'll * deallocate the memory holding intrpt_routine and
* Task while tq_timer still references them. * Notice that here we don't allow signals to * interrupt us. *
* Since WaitQ is now not NULL, this automatically * tells the interrupt routine it's time to die. */
sleep_on(&WaitQ);
}



-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/