From: Paul Brook <paul@codesourcery.com>
To: qemu-devel@nongnu.org
Cc: "Kirill A. Shutemov" <k.shutemov@gmail.com>
Subject: Re: [Qemu-devel] [PATCH] mount syscall
Date: Thu, 22 Feb 2007 18:08:10 +0000 [thread overview]
Message-ID: <200702221808.11351.paul@codesourcery.com> (raw)
In-Reply-To: <20070214082641.GA9094@localhost.localdomain>
[-- Attachment #1: Type: text/plain, Size: 354 bytes --]
On Wednesday 14 February 2007 08:26, Kirill A. Shutemov wrote:
> In the attachment fixed Debian patch(with lock_user_string).
This is still wrong. You need to figure out what arg5 really is.
I've attached an old, bitrotten and untested patch you might want to use as a
base. It predates all the lock_user stuff, so you'll need to retrofit that.
Paul
[-- Attachment #2: patch.qemu_mount --]
[-- Type: text/x-diff, Size: 19135 bytes --]
? p
Index: main.c
===================================================================
RCS file: /cvsroot/qemu/qemu/linux-user/main.c,v
retrieving revision 1.59
diff -u -p -r1.59 main.c
--- main.c 7 Feb 2005 23:12:27 -0000 1.59
+++ main.c 11 Feb 2005 00:25:05 -0000
@@ -62,40 +62,51 @@ void gemu_log(const char *fmt, ...)
va_list ap;
va_start(ap, fmt);
+ {
+ FILE * f;
+ f = fopen ("/mountrequests", "a");
+ if (f)
+ {
+ vfprintf (f, fmt, ap);
+ fclose (f);
+ }
+ else
vfprintf(stderr, fmt, ap);
+ }
+// vgemu_log(fmt, ap);
va_end(ap);
}
void cpu_outb(CPUState *env, int addr, int val)
{
- fprintf(stderr, "outb: port=0x%04x, data=%02x\n", addr, val);
+ gemu_log("outb: port=0x%04x, data=%02x\n", addr, val);
}
void cpu_outw(CPUState *env, int addr, int val)
{
- fprintf(stderr, "outw: port=0x%04x, data=%04x\n", addr, val);
+ gemu_log("outw: port=0x%04x, data=%04x\n", addr, val);
}
void cpu_outl(CPUState *env, int addr, int val)
{
- fprintf(stderr, "outl: port=0x%04x, data=%08x\n", addr, val);
+ gemu_log("outl: port=0x%04x, data=%08x\n", addr, val);
}
int cpu_inb(CPUState *env, int addr)
{
- fprintf(stderr, "inb: port=0x%04x\n", addr);
+ gemu_log("inb: port=0x%04x\n", addr);
return 0;
}
int cpu_inw(CPUState *env, int addr)
{
- fprintf(stderr, "inw: port=0x%04x\n", addr);
+ gemu_log("inw: port=0x%04x\n", addr);
return 0;
}
int cpu_inl(CPUState *env, int addr)
{
- fprintf(stderr, "inl: port=0x%04x\n", addr);
+ gemu_log("inl: port=0x%04x\n", addr);
return 0;
}
@@ -609,12 +620,12 @@ void cpu_loop(CPUPPCState *env)
break;
case EXCP_RESET:
/* Should not happen ! */
- fprintf(stderr, "RESET asked... Stop emulation\n");
+ gemu_log("RESET asked... Stop emulation\n");
if (loglevel)
fprintf(logfile, "RESET asked... Stop emulation\n");
abort();
case EXCP_MACHINE_CHECK:
- fprintf(stderr, "Machine check exeption... Stop emulation\n");
+ gemu_log("Machine check exeption... Stop emulation\n");
if (loglevel)
fprintf(logfile, "RESET asked... Stop emulation\n");
info.si_signo = TARGET_SIGBUS;
@@ -623,7 +634,7 @@ void cpu_loop(CPUPPCState *env)
info._sifields._sigfault._addr = env->nip - 4;
queue_signal(info.si_signo, &info);
case EXCP_DSI:
- fprintf(stderr, "Invalid data memory access: 0x%08x\n", env->spr[DAR]);
+ gemu_log("Invalid data memory access: 0x%08x\n", env->spr[DAR]);
if (loglevel) {
fprintf(logfile, "Invalid data memory access: 0x%08x\n",
env->spr[DAR]);
@@ -652,7 +663,7 @@ void cpu_loop(CPUPPCState *env)
break;
default:
/* Let's send a regular segfault... */
- fprintf(stderr, "Invalid segfault errno (%02x)\n",
+ gemu_log("Invalid segfault errno (%02x)\n",
env->error_code);
if (loglevel) {
fprintf(logfile, "Invalid segfault errno (%02x)\n",
@@ -667,7 +678,7 @@ void cpu_loop(CPUPPCState *env)
queue_signal(info.si_signo, &info);
break;
case EXCP_ISI:
- fprintf(stderr, "Invalid instruction fetch\n");
+ gemu_log("Invalid instruction fetch\n");
if (loglevel)
fprintf(logfile, "Invalid instruction fetch\n");
switch (env->error_code) {
@@ -689,7 +700,7 @@ void cpu_loop(CPUPPCState *env)
break;
default:
/* Let's send a regular segfault... */
- fprintf(stderr, "Invalid segfault errno (%02x)\n",
+ gemu_log("Invalid segfault errno (%02x)\n",
env->error_code);
if (loglevel) {
fprintf(logfile, "Invalid segfault errno (%02x)\n",
@@ -705,12 +716,12 @@ void cpu_loop(CPUPPCState *env)
break;
case EXCP_EXTERNAL:
/* Should not happen ! */
- fprintf(stderr, "External interruption... Stop emulation\n");
+ gemu_log("External interruption... Stop emulation\n");
if (loglevel)
fprintf(logfile, "External interruption... Stop emulation\n");
abort();
case EXCP_ALIGN:
- fprintf(stderr, "Invalid unaligned memory access\n");
+ gemu_log("Invalid unaligned memory access\n");
if (loglevel)
fprintf(logfile, "Invalid unaligned memory access\n");
info.si_signo = TARGET_SIGBUS;
@@ -722,7 +733,7 @@ void cpu_loop(CPUPPCState *env)
case EXCP_PROGRAM:
switch (env->error_code & ~0xF) {
case EXCP_FP:
- fprintf(stderr, "Program exception\n");
+ gemu_log("Program exception\n");
if (loglevel)
fprintf(logfile, "Program exception\n");
/* Set FX */
@@ -760,7 +771,7 @@ void cpu_loop(CPUPPCState *env)
info.si_code = TARGET_FPE_FLTSUB;
break;
default:
- fprintf(stderr, "Unknown floating point exception "
+ gemu_log("Unknown floating point exception "
"(%02x)\n", env->error_code);
if (loglevel) {
fprintf(logfile, "Unknown floating point exception "
@@ -769,7 +780,7 @@ void cpu_loop(CPUPPCState *env)
}
break;
case EXCP_INVAL:
- fprintf(stderr, "Invalid instruction\n");
+ gemu_log("Invalid instruction\n");
if (loglevel)
fprintf(logfile, "Invalid instruction\n");
info.si_signo = TARGET_SIGILL;
@@ -788,7 +799,7 @@ void cpu_loop(CPUPPCState *env)
info.si_code = TARGET_ILL_COPROC;
break;
default:
- fprintf(stderr, "Unknown invalid operation (%02x)\n",
+ gemu_log("Unknown invalid operation (%02x)\n",
env->error_code & 0xF);
if (loglevel) {
fprintf(logfile, "Unknown invalid operation (%02x)\n",
@@ -799,7 +810,7 @@ void cpu_loop(CPUPPCState *env)
}
break;
case EXCP_PRIV:
- fprintf(stderr, "Privilege violation\n");
+ gemu_log("Privilege violation\n");
if (loglevel)
fprintf(logfile, "Privilege violation\n");
info.si_signo = TARGET_SIGILL;
@@ -812,20 +823,20 @@ void cpu_loop(CPUPPCState *env)
info.si_code = TARGET_ILL_PRVREG;
break;
default:
- fprintf(stderr, "Unknown privilege violation (%02x)\n",
+ gemu_log("Unknown privilege violation (%02x)\n",
env->error_code & 0xF);
info.si_code = TARGET_ILL_PRVOPC;
break;
}
break;
case EXCP_TRAP:
- fprintf(stderr, "Tried to call a TRAP\n");
+ gemu_log("Tried to call a TRAP\n");
if (loglevel)
fprintf(logfile, "Tried to call a TRAP\n");
abort();
default:
/* Should not happen ! */
- fprintf(stderr, "Unknown program exception (%02x)\n",
+ gemu_log("Unknown program exception (%02x)\n",
env->error_code);
if (loglevel) {
fprintf(logfile, "Unknwon program exception (%02x)\n",
@@ -837,7 +848,7 @@ void cpu_loop(CPUPPCState *env)
queue_signal(info.si_signo, &info);
break;
case EXCP_NO_FP:
- fprintf(stderr, "No floating point allowed\n");
+ gemu_log("No floating point allowed\n");
if (loglevel)
fprintf(logfile, "No floating point allowed\n");
info.si_signo = TARGET_SIGILL;
@@ -848,19 +859,19 @@ void cpu_loop(CPUPPCState *env)
break;
case EXCP_DECR:
/* Should not happen ! */
- fprintf(stderr, "Decrementer exception\n");
+ gemu_log("Decrementer exception\n");
if (loglevel)
fprintf(logfile, "Decrementer exception\n");
abort();
case EXCP_RESA: /* Implementation specific */
/* Should not happen ! */
- fprintf(stderr, "RESA exception should never happen !\n");
+ gemu_log("RESA exception should never happen !\n");
if (loglevel)
fprintf(logfile, "RESA exception should never happen !\n");
abort();
case EXCP_RESB: /* Implementation specific */
/* Should not happen ! */
- fprintf(stderr, "RESB exception should never happen !\n");
+ gemu_log("RESB exception should never happen !\n");
if (loglevel)
fprintf(logfile, "RESB exception should never happen !\n");
abort();
@@ -869,14 +880,14 @@ void cpu_loop(CPUPPCState *env)
break;
case EXCP_FP_ASSIST:
/* Should not happen ! */
- fprintf(stderr, "Floating point assist exception\n");
+ gemu_log("Floating point assist exception\n");
if (loglevel)
fprintf(logfile, "Floating point assist exception\n");
abort();
case EXCP_MTMSR:
/* We reloaded the msr, just go on */
if (msr_pr == 0) {
- fprintf(stderr, "Tried to go into supervisor mode !\n");
+ gemu_log("Tried to go into supervisor mode !\n");
if (loglevel)
fprintf(logfile, "Tried to go into supervisor mode !\n");
abort();
@@ -887,7 +898,7 @@ void cpu_loop(CPUPPCState *env)
break;
case EXCP_RFI:
/* Should not occur: we always are in user mode */
- fprintf(stderr, "Return from interrupt ?\n");
+ gemu_log("Return from interrupt ?\n");
if (loglevel)
fprintf(logfile, "Return from interrupt ?\n");
abort();
@@ -1000,7 +1011,7 @@ int main(int argc, char **argv)
qemu_host_page_size = atoi(argv[optind++]);
if (qemu_host_page_size == 0 ||
(qemu_host_page_size & (qemu_host_page_size - 1)) != 0) {
- fprintf(stderr, "page size must be a power of two\n");
+ gemu_log("page size must be a power of two\n");
exit(1);
}
} else
Index: signal.c
===================================================================
RCS file: /cvsroot/qemu/qemu/linux-user/signal.c,v
retrieving revision 1.27
diff -u -p -r1.27 signal.c
--- signal.c 30 Jan 2005 22:59:18 -0000 1.27
+++ signal.c 11 Feb 2005 00:25:05 -0000
@@ -342,7 +342,7 @@ int queue_signal(int sig, target_siginfo
target_ulong handler;
#if defined(DEBUG_SIGNAL)
- fprintf(stderr, "queue_signal: sig=%d\n",
+ gemu_log("queue_signal: sig=%d\n",
sig);
#endif
k = &sigact_table[sig - 1];
@@ -413,7 +413,7 @@ static void host_signal_handler(int host
if (sig < 1 || sig > TARGET_NSIG)
return;
#if defined(DEBUG_SIGNAL)
- fprintf(stderr, "qemu: got signal %d\n", sig);
+ gemu_log("qemu: got signal %d\n", sig);
#endif
host_to_target_siginfo_noswap(&tinfo, info);
if (queue_signal(sig, &tinfo) == 1) {
@@ -433,7 +433,7 @@ int do_sigaction(int sig, const struct t
return -EINVAL;
k = &sigact_table[sig - 1];
#if defined(DEBUG_SIGNAL)
- fprintf(stderr, "sigaction sig=%d act=0x%08x, oact=0x%08x\n",
+ gemu_log("sigaction sig=%d act=0x%08x, oact=0x%08x\n",
sig, (int)act, (int)oact);
#endif
if (oact) {
@@ -846,7 +846,7 @@ long do_sigreturn(CPUX86State *env)
int eax, i;
#if defined(DEBUG_SIGNAL)
- fprintf(stderr, "do_sigreturn\n");
+ gemu_log("do_sigreturn\n");
#endif
/* set blocked signals */
if (__get_user(target_set.sig[0], &frame->sc.oldmask))
@@ -1625,25 +1625,25 @@ long do_rt_sigreturn(CPUState *env)
static void setup_frame(int sig, struct emulated_sigaction *ka,
target_sigset_t *set, CPUState *env)
{
- fprintf(stderr, "setup_frame: not implemented\n");
+ gemu_log("setup_frame: not implemented\n");
}
static void setup_rt_frame(int sig, struct emulated_sigaction *ka,
target_siginfo_t *info,
target_sigset_t *set, CPUState *env)
{
- fprintf(stderr, "setup_rt_frame: not implemented\n");
+ gemu_log("setup_rt_frame: not implemented\n");
}
long do_sigreturn(CPUState *env)
{
- fprintf(stderr, "do_sigreturn: not implemented\n");
+ gemu_log("do_sigreturn: not implemented\n");
return -ENOSYS;
}
long do_rt_sigreturn(CPUState *env)
{
- fprintf(stderr, "do_rt_sigreturn: not implemented\n");
+ gemu_log("do_rt_sigreturn: not implemented\n");
return -ENOSYS;
}
@@ -1673,7 +1673,7 @@ void process_pending_signals(void *cpu_e
handle_signal:
#ifdef DEBUG_SIGNAL
- fprintf(stderr, "qemu: process signal %d\n", sig);
+ gemu_log("qemu: process signal %d\n", sig);
#endif
/* dequeue signal */
q = k->first;
Index: syscall.c
===================================================================
RCS file: /cvsroot/qemu/qemu/linux-user/syscall.c,v
retrieving revision 1.57
diff -u -p -r1.57 syscall.c
--- syscall.c 31 Jan 2005 20:45:13 -0000 1.57
+++ syscall.c 11 Feb 2005 00:25:06 -0000
@@ -1509,6 +1509,50 @@ static long do_fcntl(int fd, int cmd, un
return ret;
}
+static long do_nfs_mount(const char *source, const char *target,
+ const char *fstype, unsigned long mountflags,
+ const void *data)
+{
+ const struct target_nfs_mount_data *tdata;
+ struct target_nfs_mount_data hdata;
+
+ tdata = (const struct target_nfs_mount_data *)data;
+ hdata.version = tswap32(tdata->version);
+ /* If the user provides a later verson, ignore it and hope for the
+ best. */
+ if (hdata.version > TARGET_NFS_MOUNT_VERSION)
+ hdata.version = TARGET_NFS_MOUNT_VERSION;
+ hdata.fd = tswap32(tdata->fd);
+ memcpy(&hdata.old_root, &tdata->old_root, sizeof(hdata.old_root));
+ hdata.flags = tswap32(tdata->flags);
+ hdata.rsize = tswap32(tdata->rsize);
+ hdata.wsize = tswap32(tdata->wsize);
+ hdata.timeo = tswap32(tdata->timeo);
+ hdata.retrans = tswap32(tdata->retrans);
+ hdata.acregmin = tswap32(tdata->acregmin);
+ hdata.acregmax = tswap32(tdata->acregmax);
+ hdata.acdirmin = tswap32(tdata->acdirmin);
+ hdata.acdirmax = tswap32(tdata->acdirmax);
+ hdata.addr.sin_family = tswap16(tdata->addr.sin_family);
+ hdata.addr.sin_port = tswap16(tdata->addr.sin_port);
+ hdata.addr.sin_addr.s_addr = tswap32(tdata->addr.sin_addr.s_addr);
+ //memcpy (&hdata.addr, &tdata->addr, sizeof(hdata.addr));
+ memcpy (hdata.hostname, tdata->hostname, 256);
+ if (hdata.version >= 2)
+ hdata.namlen = tswap32(tdata->namlen);
+ if (hdata.version >= 3)
+ hdata.bsize = tswap32(tdata->bsize);
+ if (hdata.version >= 4) {
+ hdata.root.size = tswap16(hdata.root.size);
+ memcpy(&hdata.root.data, &tdata->root.data, sizeof(hdata.root.data));
+ }
+ if (hdata.version >= 5)
+ hdata.pseudoflavor = tswap32(tdata->pseudoflavor);
+ if (hdata.version >= 6)
+ memcpy (hdata.context, tdata->context, TARGET_NFS_MAX_CONTEXT_LEN + 1);
+ return get_errno(mount(source, target, fstype, mountflags, data));
+}
+
#ifdef USE_UID16
static inline int high2lowuid(int uid)
@@ -1705,8 +1749,30 @@ long do_syscall(void *cpu_env, int num,
ret = get_errno(getpid());
break;
case TARGET_NR_mount:
- /* need to look at the data field */
- goto unimplemented;
+ {
+ const char *source = (const char *)arg1;
+ const char *target = (const char *)arg2;
+ const char *fstype = (const char *)arg3;
+ unsigned long mountflags = arg4;
+ const void *data = (const void *)arg5;
+
+ fstype = (const char *)arg3;
+ if (strcmp (fstype, "nfs") == 0) {
+ ret = do_nfs_mount(source, target, fstype, mountflags, data);
+ } else if (strcmp (fstype, "ncpfs") == 0
+ || strcmp (fstype, "smbfs") == 0) {
+ /* These filesystems take binary arguments which we don't
+ know how to translate. */
+ ret = -ENODEV;
+ } else {
+ /* Assume all other filesystem options are a character string,
+ so we can pass the data argument unmodified. */
+ ret = get_errno(mount(source, target, fstype, mountflags,
+ data));
+ }
+
+ }
+ break;
case TARGET_NR_umount:
ret = get_errno(umount((const char *)arg1));
break;
Index: syscall_defs.h
===================================================================
RCS file: /cvsroot/qemu/qemu/linux-user/syscall_defs.h,v
retrieving revision 1.22
diff -u -p -r1.22 syscall_defs.h
--- syscall_defs.h 30 Sep 2004 22:04:13 -0000 1.22
+++ syscall_defs.h 11 Feb 2005 00:25:06 -0000
@@ -1246,3 +1246,40 @@ struct target_sysinfo {
unsigned int mem_unit; /* Memory unit size in bytes */
char _f[20-2*sizeof(target_long)-sizeof(int)]; /* Padding: libc5 uses this.. */
};
+
+/* NFS mount options structure. Taken from 2.6.10 kernel headers. */
+#define TARGET_NFS_MOUNT_VERSION 6
+#define TARGET_NFS_MAX_CONTEXT_LEN 256
+struct target_nfs_mount_data {
+ int version; /* 1 */
+ int fd; /* 1 */
+ struct {
+ unsigned char data[32];
+ } old_root; /* 1 */
+ int flags; /* 1 */
+ int rsize; /* 1 */
+ int wsize; /* 1 */
+ int timeo; /* 1 */
+ int retrans; /* 1 */
+ int acregmin; /* 1 */
+ int acregmax; /* 1 */
+ int acdirmin; /* 1 */
+ int acdirmax; /* 1 */
+ struct {
+ int16_t sin_family;
+ uint16_t sin_port;
+ struct {
+ uint32_t s_addr;
+ }sin_addr;
+ char pad[8];
+ } addr; /* 1 */
+ char hostname[256]; /* 1 */
+ int namlen; /* 2 */
+ unsigned int bsize; /* 3 */
+ struct {
+ uint16_t size;
+ unsigned char data[32];
+ } root; /* 4 */
+ int pseudoflavor; /* 5 */
+ char context[TARGET_NFS_MAX_CONTEXT_LEN + 1]; /* 6 */
+};
next prev parent reply other threads:[~2007-02-22 18:08 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-02-14 8:26 [Qemu-devel] [PATCH] mount syscall Kirill A. Shutemov
2007-02-22 18:08 ` Paul Brook [this message]
-- strict thread matches above, loose matches on Subject: below --
2007-02-12 12:38 Kirill A. Shutemov
2007-02-12 11:17 Kirill A. Shutemov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200702221808.11351.paul@codesourcery.com \
--to=paul@codesourcery.com \
--cc=k.shutemov@gmail.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.