summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjdike <jdike>2003-09-08 16:26:19 +0000
committerjdike <jdike>2003-09-08 16:26:19 +0000
commit6149b82b1256bb2be4a3042b1c1371dc42fad931 (patch)
tree29261e5892a00f5f861a9de8da34b3f2e05db556
parent7cc33a3d271c346196e12672e5114d911304663b (diff)
downloaduml-history-6149b82b1256bb2be4a3042b1c1371dc42fad931.tar.gz
Added the proc command.
A bit of code cleanup.
-rw-r--r--arch/um/drivers/mconsole_kern.c89
-rw-r--r--arch/um/drivers/mconsole_user.c23
-rw-r--r--arch/um/include/mconsole.h5
3 files changed, 104 insertions, 13 deletions
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
index f587abb..2292f5d 100644
--- a/arch/um/drivers/mconsole_kern.c
+++ b/arch/um/drivers/mconsole_kern.c
@@ -15,6 +15,8 @@
#include "linux/sysrq.h"
#include "linux/tqueue.h"
#include "linux/module.h"
+#include "linux/file.h"
+#include "linux/fs.h"
#include "linux/proc_fs.h"
#include "asm/irq.h"
#include "asm/uaccess.h"
@@ -79,7 +81,8 @@ void mconsole_interrupt(int irq, void *dev_id, struct pt_regs *regs)
fd = (int) dev_id;
while (mconsole_get_request(fd, &req)){
- if(req.cmd->as_interrupt) (*req.cmd->handler)(&req);
+ if(req.cmd->context == MCONSOLE_INTR)
+ (*req.cmd->handler)(&req);
else {
new = kmalloc(sizeof(req), GFP_ATOMIC);
if(new == NULL)
@@ -117,6 +120,90 @@ void mconsole_log(struct mc_request *req)
mconsole_reply(req, "", 0, 0);
}
+void mconsole_proc(struct mc_request *req)
+{
+ struct nameidata nd;
+ struct file_system_type *proc;
+ struct super_block *super;
+ struct file *file;
+ int n, err;
+ char *ptr = req->request.data, *buf;
+
+ ptr += strlen("proc");
+ while(isspace(*ptr)) ptr++;
+
+ proc = get_fs_type("proc");
+ if(proc == NULL){
+ mconsole_reply(req, "procfs not registered", 1, 0);
+ goto out;
+ }
+
+ super = get_anon_super(proc, NULL, NULL);
+ if(super == NULL){
+ mconsole_reply(req, "Failed to get procfs superblock", 1, 0);
+ goto out_put;
+ }
+
+ if(super->s_root == NULL){
+ super = (*proc->read_super)(super, NULL, 0);
+ if(super == NULL){
+ mconsole_reply(req, "Failed to read superblock", 1, 0);
+ goto out_put;
+ }
+ }
+ up_write(&super->s_umount);
+
+ nd.dentry = super->s_root;
+ nd.mnt = NULL;
+ nd.flags = O_RDONLY + 1;
+ nd.last_type = LAST_ROOT;
+
+ err = link_path_walk(ptr, &nd);
+ if(err){
+ mconsole_reply(req, "Failed to look up file", 1, 0);
+ goto out_kill;
+ }
+
+ file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);
+ if(IS_ERR(file)){
+ mconsole_reply(req, "Failed to open file", 1, 0);
+ goto out_kill;
+ }
+
+ buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+ if(buf == NULL){
+ mconsole_reply(req, "Failed to allocate buffer", 1, 0);
+ goto out_fput;
+ }
+
+ if((file->f_op != NULL) && (file->f_op->read != NULL)){
+ do {
+ n = (*file->f_op->read)(file, buf, PAGE_SIZE - 1,
+ &file->f_pos);
+ if(n >= 0){
+ buf[n] = '\0';
+ mconsole_reply(req, buf, 0, (n > 0));
+ }
+ else {
+ mconsole_reply(req, "Read of file failed",
+ 1, 0);
+ goto out_free;
+ }
+ } while(n > 0);
+ }
+ else mconsole_reply(req, "", 0, 0);
+
+ out_free:
+ kfree(buf);
+ out_fput:
+ fput(file);
+ out_kill:
+ kill_super(super);
+ out_put:
+ /* put_filesystem(proc); */
+ out: ;
+}
+
#define UML_MCONSOLE_HELPTEXT \
"Commands: \n\
version - Get kernel version \n\
diff --git a/arch/um/drivers/mconsole_user.c b/arch/um/drivers/mconsole_user.c
index f9fcbc6..08c1074 100644
--- a/arch/um/drivers/mconsole_user.c
+++ b/arch/um/drivers/mconsole_user.c
@@ -18,17 +18,18 @@
#include "umid.h"
static struct mconsole_command commands[] = {
- { "version", mconsole_version, 1 },
- { "halt", mconsole_halt, 0 },
- { "reboot", mconsole_reboot, 0 },
- { "config", mconsole_config, 0 },
- { "remove", mconsole_remove, 0 },
- { "sysrq", mconsole_sysrq, 1 },
- { "help", mconsole_help, 1 },
- { "cad", mconsole_cad, 1 },
- { "stop", mconsole_stop, 0 },
- { "go", mconsole_go, 1 },
- { "log", mconsole_log, 1 },
+ { "version", mconsole_version, MCONSOLE_INTR },
+ { "halt", mconsole_halt, MCONSOLE_PROC },
+ { "reboot", mconsole_reboot, MCONSOLE_PROC },
+ { "config", mconsole_config, MCONSOLE_PROC },
+ { "remove", mconsole_remove, MCONSOLE_PROC },
+ { "sysrq", mconsole_sysrq, MCONSOLE_INTR },
+ { "help", mconsole_help, MCONSOLE_INTR },
+ { "cad", mconsole_cad, MCONSOLE_INTR },
+ { "stop", mconsole_stop, MCONSOLE_PROC },
+ { "go", mconsole_go, MCONSOLE_INTR },
+ { "log", mconsole_log, MCONSOLE_INTR },
+ { "proc", mconsole_proc, MCONSOLE_PROC },
};
/* Initialized in mconsole_init, which is an initcall */
diff --git a/arch/um/include/mconsole.h b/arch/um/include/mconsole.h
index 14ccb3a..9fbe308 100644
--- a/arch/um/include/mconsole.h
+++ b/arch/um/include/mconsole.h
@@ -41,11 +41,13 @@ struct mconsole_notify {
struct mc_request;
+enum mc_context { MCONSOLE_INTR, MCONSOLE_PROC };
+
struct mconsole_command
{
char *command;
void (*handler)(struct mc_request *req);
- int as_interrupt;
+ enum mc_context context;
};
struct mc_request
@@ -78,6 +80,7 @@ extern void mconsole_cad(struct mc_request *req);
extern void mconsole_stop(struct mc_request *req);
extern void mconsole_go(struct mc_request *req);
extern void mconsole_log(struct mc_request *req);
+extern void mconsole_proc(struct mc_request *req);
extern int mconsole_get_request(int fd, struct mc_request *req);
extern int mconsole_notify(char *sock_name, int type, const void *data,