Date: Thu, 28 Oct 1999 10:35:29 -0700 From: Jake Burkholder <jake@checker.org> To: arch@freebsd.org Subject: rfork patch, please comment Message-ID: <19991028173529.C12031FD6@io.yi.org>
next in thread | raw e-mail | index | archive | help
[-- Attachment #1 --]
Hi,
I've made a patch that adds linux 'clone' style support
to rfork, and I'd like to hear opinions on whether this
is an ok way to do it.
It consists of adding varargs to rfork, and passing in
a new stack pointer and return address, so the two processes
don't try to use the same stack on return.
Should this just be tacked on to rfork?
Should a new system call be added? (tfork? ffork? lfork? <shudder> clone?)
Are 2 arguments enough? do we want to also pass in a sigparent?
Am I on the wrong track completely, and should this just be
added to libc ala Matt Dillon's ffork example?
Is this portable enough? (Does anyone know what the corresponding
cpu_set_rfork_handler() for alpha should look like?)
I had problems with
251 STD BSD { int rfork(int flags, void (*func)(void*), void *stack); }
in syscalls.master, so I bogusly made it void *func .
Does this need a typedef?
(Maybe this should go to hackers, the audience here seemed smaller
and more friendly :) ).
I'm using a recent -current, I don't know how this will apply to
anything else. Recompile kernel, and then cd /usr/src; make includes.
Thank you.
[-- Attachment #2 --]
Index: include/unistd.h
===================================================================
RCS file: /home/ncvs/src/include/unistd.h,v
retrieving revision 1.27
diff -c -r1.27 unistd.h
*** unistd.h 1999/07/16 06:28:51 1.27
--- unistd.h 1999/10/28 15:24:19
***************
*** 165,171 ****
int readlink __P((const char *, char *, int));
int reboot __P((int));
int revoke __P((const char *));
! pid_t rfork __P((int));
int rresvport __P((int *));
int ruserok __P((const char *, int, const char *, const char *));
char *sbrk __P((int));
--- 165,171 ----
int readlink __P((const char *, char *, int));
int reboot __P((int));
int revoke __P((const char *));
! pid_t rfork __P((int, ...));
int rresvport __P((int *));
int ruserok __P((const char *, int, const char *, const char *));
char *sbrk __P((int));
Index: sys/alpha/alpha/vm_machdep.c
===================================================================
RCS file: /home/ncvs/src/sys/alpha/alpha/vm_machdep.c,v
retrieving revision 1.22
diff -c -r1.22 vm_machdep.c
*** vm_machdep.c 1999/09/20 19:08:47 1.22
--- vm_machdep.c 1999/10/28 16:28:33
***************
*** 231,236 ****
--- 231,247 ----
p->p_addr->u_pcb.pcb_context[2] = (u_long) arg;
}
+ void
+ cpu_set_rfork_handler(p, func, stack)
+ struct proc *p;
+ void (*func) __P((void *));
+ void *stack;
+ {
+ /* XXX help! I'm guessing here. */
+ p->p_md.md_tf->tf_regs[FRAME_RA] = (u_long) func;
+ p->p_md.md_tf->tf_regs[FRAME_SP] = (u_long) stack;
+ }
+
/*
* cpu_exit is called as the last action during exit.
* We release the address space of the process, block interrupts,
Index: sys/i386/i386/vm_machdep.c
===================================================================
RCS file: /home/ncvs/src/sys/i386/i386/vm_machdep.c,v
retrieving revision 1.128
diff -c -r1.128 vm_machdep.c
*** vm_machdep.c 1999/10/11 14:50:03 1.128
--- vm_machdep.c 1999/10/28 15:30:35
***************
*** 205,210 ****
--- 205,220 ----
}
void
+ cpu_set_rfork_handler(p, func, stack)
+ struct proc *p;
+ void (*func) __P((void *));
+ void *stack;
+ {
+ p->p_md.md_regs->tf_eip = (int) func;
+ p->p_md.md_regs->tf_esp = (int) stack;
+ }
+
+ void
cpu_exit(p)
register struct proc *p;
{
Index: sys/kern/init_sysent.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/init_sysent.c,v
retrieving revision 1.73
diff -c -r1.73 init_sysent.c
*** init_sysent.c 1999/10/12 09:33:51 1.73
--- init_sysent.c 1999/10/28 15:40:06
***************
*** 2,8 ****
* System call switch table.
*
* DO NOT EDIT-- this file is automatically generated.
! * $FreeBSD: src/sys/kern/init_sysent.c,v 1.73 1999/10/12 09:33:51 marcel Exp $
* created from FreeBSD: src/sys/kern/syscalls.master,v 1.66 1999/10/12 09:29:53 marcel Exp
*/
--- 2,8 ----
* System call switch table.
*
* DO NOT EDIT-- this file is automatically generated.
! * $FreeBSD$
* created from FreeBSD: src/sys/kern/syscalls.master,v 1.66 1999/10/12 09:29:53 marcel Exp
*/
***************
*** 271,277 ****
{ 0, (sy_call_t *)nosys }, /* 248 = nosys */
{ 0, (sy_call_t *)nosys }, /* 249 = nosys */
{ 3, (sy_call_t *)minherit }, /* 250 = minherit */
! { 1, (sy_call_t *)rfork }, /* 251 = rfork */
{ 3, (sy_call_t *)openbsd_poll }, /* 252 = openbsd_poll */
{ 0, (sy_call_t *)issetugid }, /* 253 = issetugid */
{ 3, (sy_call_t *)lchown }, /* 254 = lchown */
--- 271,277 ----
{ 0, (sy_call_t *)nosys }, /* 248 = nosys */
{ 0, (sy_call_t *)nosys }, /* 249 = nosys */
{ 3, (sy_call_t *)minherit }, /* 250 = minherit */
! { 3, (sy_call_t *)rfork }, /* 251 = rfork */
{ 3, (sy_call_t *)openbsd_poll }, /* 252 = openbsd_poll */
{ 0, (sy_call_t *)issetugid }, /* 253 = issetugid */
{ 3, (sy_call_t *)lchown }, /* 254 = lchown */
Index: sys/kern/kern_fork.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_fork.c,v
retrieving revision 1.66
diff -c -r1.66 kern_fork.c
*** kern_fork.c 1999/10/11 15:19:08 1.66
--- kern_fork.c 1999/10/28 16:28:50
***************
*** 129,135 ****
error = fork1(p, uap->flags, &p2);
if (error == 0) {
! p->p_retval[0] = p2 ? p2->p_pid : 0;
p->p_retval[1] = 0;
}
return error;
--- 129,141 ----
error = fork1(p, uap->flags, &p2);
if (error == 0) {
! if (p2) {
! p->p_retval[0] = p2->p_pid;
! if (uap->flags & RFMEM)
! cpu_set_rfork_handler(p2, uap->func, uap->stack);
! } else {
! p->p_retval[0] = 0;
! }
p->p_retval[1] = 0;
}
return error;
Index: sys/kern/syscalls.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/syscalls.c,v
retrieving revision 1.66
diff -c -r1.66 syscalls.c
*** syscalls.c 1999/10/12 09:33:51 1.66
--- syscalls.c 1999/10/28 15:40:06
***************
*** 2,8 ****
* System call names.
*
* DO NOT EDIT-- this file is automatically generated.
! * $FreeBSD: src/sys/kern/syscalls.c,v 1.66 1999/10/12 09:33:51 marcel Exp $
* created from FreeBSD: src/sys/kern/syscalls.master,v 1.66 1999/10/12 09:29:53 marcel Exp
*/
--- 2,8 ----
* System call names.
*
* DO NOT EDIT-- this file is automatically generated.
! * $FreeBSD$
* created from FreeBSD: src/sys/kern/syscalls.master,v 1.66 1999/10/12 09:29:53 marcel Exp
*/
Index: sys/kern/syscalls.master
===================================================================
RCS file: /home/ncvs/src/sys/kern/syscalls.master,v
retrieving revision 1.66
diff -c -r1.66 syscalls.master
*** syscalls.master 1999/10/12 09:29:53 1.66
--- syscalls.master 1999/10/28 15:39:52
***************
*** 380,386 ****
249 UNIMPL NOHIDE nosys
; syscall numbers initially used in OpenBSD
250 STD BSD { int minherit(void *addr, size_t len, int inherit); }
! 251 STD BSD { int rfork(int flags); }
252 STD BSD { int openbsd_poll(struct pollfd *fds, u_int nfds, \
int timeout); }
253 STD BSD { int issetugid(void); }
--- 380,386 ----
249 UNIMPL NOHIDE nosys
; syscall numbers initially used in OpenBSD
250 STD BSD { int minherit(void *addr, size_t len, int inherit); }
! 251 STD BSD { int rfork(int flags, void *func, void *stack); }
252 STD BSD { int openbsd_poll(struct pollfd *fds, u_int nfds, \
int timeout); }
253 STD BSD { int issetugid(void); }
Index: sys/sys/proc.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/proc.h,v
retrieving revision 1.90
diff -c -r1.90 proc.h
*** proc.h 1999/10/11 20:33:16 1.90
--- proc.h 1999/10/28 15:24:40
***************
*** 401,406 ****
--- 401,407 ----
void exit1 __P((struct proc *, int)) __dead2;
void cpu_fork __P((struct proc *, struct proc *));
void cpu_set_fork_handler __P((struct proc *, void (*)(void *), void *));
+ void cpu_set_rfork_handler __P((struct proc *, void (*)(void *), void *));
int fork1 __P((struct proc *, int, struct proc **));
int trace_req __P((struct proc *));
void cpu_wait __P((struct proc *));
Index: sys/sys/syscall-hide.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/syscall-hide.h,v
retrieving revision 1.60
diff -c -r1.60 syscall-hide.h
*** syscall-hide.h 1999/10/12 09:33:52 1.60
--- syscall-hide.h 1999/10/28 15:40:06
***************
*** 2,8 ****
* System call hiders.
*
* DO NOT EDIT-- this file is automatically generated.
! * $FreeBSD: src/sys/sys/syscall-hide.h,v 1.60 1999/10/12 09:33:52 marcel Exp $
* created from FreeBSD: src/sys/kern/syscalls.master,v 1.66 1999/10/12 09:29:53 marcel Exp
*/
--- 2,8 ----
* System call hiders.
*
* DO NOT EDIT-- this file is automatically generated.
! * $FreeBSD$
* created from FreeBSD: src/sys/kern/syscalls.master,v 1.66 1999/10/12 09:29:53 marcel Exp
*/
Index: sys/sys/syscall.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/syscall.h,v
retrieving revision 1.64
diff -c -r1.64 syscall.h
*** syscall.h 1999/10/12 09:33:52 1.64
--- syscall.h 1999/10/28 15:40:06
***************
*** 2,8 ****
* System call numbers.
*
* DO NOT EDIT-- this file is automatically generated.
! * $FreeBSD: src/sys/sys/syscall.h,v 1.64 1999/10/12 09:33:52 marcel Exp $
* created from FreeBSD: src/sys/kern/syscalls.master,v 1.66 1999/10/12 09:29:53 marcel Exp
*/
--- 2,8 ----
* System call numbers.
*
* DO NOT EDIT-- this file is automatically generated.
! * $FreeBSD$
* created from FreeBSD: src/sys/kern/syscalls.master,v 1.66 1999/10/12 09:29:53 marcel Exp
*/
Index: sys/sys/syscall.mk
===================================================================
RCS file: /home/ncvs/src/sys/sys/syscall.mk,v
retrieving revision 1.18
diff -c -r1.18 syscall.mk
*** syscall.mk 1999/10/12 09:33:53 1.18
--- syscall.mk 1999/10/28 15:40:06
***************
*** 1,6 ****
# FreeBSD system call names.
# DO NOT EDIT-- this file is automatically generated.
! # $FreeBSD: src/sys/sys/syscall.mk,v 1.18 1999/10/12 09:33:53 marcel Exp $
# created from FreeBSD: src/sys/kern/syscalls.master,v 1.66 1999/10/12 09:29:53 marcel Exp
MIASM = \
syscall.o \
--- 1,6 ----
# FreeBSD system call names.
# DO NOT EDIT-- this file is automatically generated.
! # $FreeBSD$
# created from FreeBSD: src/sys/kern/syscalls.master,v 1.66 1999/10/12 09:29:53 marcel Exp
MIASM = \
syscall.o \
Index: sys/sys/sysproto.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/sysproto.h,v
retrieving revision 1.53
diff -c -r1.53 sysproto.h
*** sysproto.h 1999/10/12 09:33:53 1.53
--- sysproto.h 1999/10/28 15:40:06
***************
*** 2,8 ****
* System call prototypes.
*
* DO NOT EDIT-- this file is automatically generated.
! * $FreeBSD: src/sys/sys/sysproto.h,v 1.53 1999/10/12 09:33:53 marcel Exp $
* created from FreeBSD: src/sys/kern/syscalls.master,v 1.66 1999/10/12 09:29:53 marcel Exp
*/
--- 2,8 ----
* System call prototypes.
*
* DO NOT EDIT-- this file is automatically generated.
! * $FreeBSD$
* created from FreeBSD: src/sys/kern/syscalls.master,v 1.66 1999/10/12 09:29:53 marcel Exp
*/
***************
*** 726,731 ****
--- 726,733 ----
};
struct rfork_args {
int flags; char flags_[PAD_(int)];
+ void * func; char func_[PAD_(void *)];
+ void * stack; char stack_[PAD_(void *)];
};
struct openbsd_poll_args {
struct pollfd * fds; char fds_[PAD_(struct pollfd *)];
[-- Attachment #3 --]
#include <unistd.h>
#include <stdio.h>
void child(void *arg) {
int *i = arg;
for(;;)
++(*i);
}
int main(int ac, char **av) {
char *p, stack[4096];
int i = 0;
p = stack + sizeof(stack) - sizeof(int);
*(int **)p = &i;
p -= sizeof(int *);
rfork(RFPROC | RFMEM, child, p);
for(;;) {
fprintf(stderr, "%d\n", i);
sleep(1);
}
return 0;
}
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?19991028173529.C12031FD6>
