Skip site navigation (1)Skip section navigation (2)
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
This is a multipart MIME message.

--==_Exmh_1783049920
Content-Type: text/plain; charset=us-ascii

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.

--==_Exmh_1783049920
Content-Type: text/plain ; name="rfork.diff"; charset=us-ascii
Content-Description: rfork.diff
Content-Disposition: attachment; filename="rfork.diff"

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 *)];

--==_Exmh_1783049920
Content-Type: text/plain ; name="rfork.c"; charset=us-ascii
Content-Description: rfork.c
Content-Disposition: attachment; filename="rfork.c"

#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;
}

--==_Exmh_1783049920--






To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-arch" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?19991028173529.C12031FD6>