|
@@ -21,6 +21,9 @@
|
|
|
#include <linux/un.h>
|
|
|
#include <linux/workqueue.h>
|
|
|
#include <linux/mutex.h>
|
|
|
+#include <linux/fs.h>
|
|
|
+#include <linux/mount.h>
|
|
|
+#include <linux/file.h>
|
|
|
#include <asm/uaccess.h>
|
|
|
#include <asm/switch_to.h>
|
|
|
|
|
@@ -118,90 +121,38 @@ void mconsole_log(struct mc_request *req)
|
|
|
mconsole_reply(req, "", 0, 0);
|
|
|
}
|
|
|
|
|
|
-/* This is a more convoluted version of mconsole_proc, which has some stability
|
|
|
- * problems; however, we need it fixed, because it is expected that UML users
|
|
|
- * mount HPPFS instead of procfs on /proc. And we want mconsole_proc to still
|
|
|
- * show the real procfs content, not the ones from hppfs.*/
|
|
|
-#if 0
|
|
|
void mconsole_proc(struct mc_request *req)
|
|
|
{
|
|
|
struct vfsmount *mnt = current->nsproxy->pid_ns->proc_mnt;
|
|
|
- struct file *file;
|
|
|
- int n;
|
|
|
- char *ptr = req->request.data, *buf;
|
|
|
- mm_segment_t old_fs = get_fs();
|
|
|
-
|
|
|
- ptr += strlen("proc");
|
|
|
- ptr = skip_spaces(ptr);
|
|
|
-
|
|
|
- file = file_open_root(mnt->mnt_root, mnt, ptr, O_RDONLY);
|
|
|
- if (IS_ERR(file)) {
|
|
|
- mconsole_reply(req, "Failed to open file", 1, 0);
|
|
|
- goto out;
|
|
|
- }
|
|
|
-
|
|
|
- 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->read) {
|
|
|
- do {
|
|
|
- loff_t pos;
|
|
|
- set_fs(KERNEL_DS);
|
|
|
- n = vfs_read(file, buf, PAGE_SIZE - 1, &pos);
|
|
|
- file_pos_write(file, pos);
|
|
|
- set_fs(old_fs);
|
|
|
- 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: ;
|
|
|
-}
|
|
|
-#endif
|
|
|
-
|
|
|
-void mconsole_proc(struct mc_request *req)
|
|
|
-{
|
|
|
- char path[64];
|
|
|
char *buf;
|
|
|
int len;
|
|
|
- int fd;
|
|
|
+ struct file *file;
|
|
|
int first_chunk = 1;
|
|
|
char *ptr = req->request.data;
|
|
|
|
|
|
ptr += strlen("proc");
|
|
|
ptr = skip_spaces(ptr);
|
|
|
- snprintf(path, sizeof(path), "/proc/%s", ptr);
|
|
|
|
|
|
- fd = sys_open(path, 0, 0);
|
|
|
- if (fd < 0) {
|
|
|
+ file = file_open_root(mnt->mnt_root, mnt, ptr, O_RDONLY);
|
|
|
+ if (IS_ERR(file)) {
|
|
|
mconsole_reply(req, "Failed to open file", 1, 0);
|
|
|
- printk(KERN_ERR "open %s: %d\n",path,fd);
|
|
|
+ printk(KERN_ERR "open /proc/%s: %ld\n", ptr, PTR_ERR(file));
|
|
|
goto out;
|
|
|
}
|
|
|
|
|
|
buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
|
|
|
if (buf == NULL) {
|
|
|
mconsole_reply(req, "Failed to allocate buffer", 1, 0);
|
|
|
- goto out_close;
|
|
|
+ goto out_fput;
|
|
|
}
|
|
|
|
|
|
- for (;;) {
|
|
|
- len = sys_read(fd, buf, PAGE_SIZE-1);
|
|
|
+ do {
|
|
|
+ loff_t pos;
|
|
|
+ mm_segment_t old_fs = get_fs();
|
|
|
+ set_fs(KERNEL_DS);
|
|
|
+ len = vfs_read(file, buf, PAGE_SIZE - 1, &pos);
|
|
|
+ set_fs(old_fs);
|
|
|
+ file->f_pos = pos;
|
|
|
if (len < 0) {
|
|
|
mconsole_reply(req, "Read of file failed", 1, 0);
|
|
|
goto out_free;
|
|
@@ -211,22 +162,14 @@ void mconsole_proc(struct mc_request *req)
|
|
|
mconsole_reply(req, "\n", 0, 1);
|
|
|
first_chunk = 0;
|
|
|
}
|
|
|
- if (len == PAGE_SIZE-1) {
|
|
|
- buf[len] = '\0';
|
|
|
- mconsole_reply(req, buf, 0, 1);
|
|
|
- } else {
|
|
|
- buf[len] = '\0';
|
|
|
- mconsole_reply(req, buf, 0, 0);
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
+ buf[len] = '\0';
|
|
|
+ mconsole_reply(req, buf, 0, (len > 0));
|
|
|
+ } while (len > 0);
|
|
|
out_free:
|
|
|
kfree(buf);
|
|
|
- out_close:
|
|
|
- sys_close(fd);
|
|
|
- out:
|
|
|
- /* nothing */;
|
|
|
+ out_fput:
|
|
|
+ fput(file);
|
|
|
+ out: ;
|
|
|
}
|
|
|
|
|
|
#define UML_MCONSOLE_HELPTEXT \
|