From owner-freebsd-hackers@freebsd.org Tue Feb 2 04:07:54 2016 Return-Path: Delivered-To: freebsd-hackers@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 8D248A978D6 for ; Tue, 2 Feb 2016 04:07:54 +0000 (UTC) (envelope-from mjguzik@gmail.com) Received: from mail-wm0-x242.google.com (mail-wm0-x242.google.com [IPv6:2a00:1450:400c:c09::242]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (Client CN "smtp.gmail.com", Issuer "Google Internet Authority G2" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 190C31C48; Tue, 2 Feb 2016 04:07:54 +0000 (UTC) (envelope-from mjguzik@gmail.com) Received: by mail-wm0-x242.google.com with SMTP id p63so493187wmp.1; Mon, 01 Feb 2016 20:07:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Q5UVUj9RLeQGinQvNojj+g10laQqR5okl6sEhon9WRk=; b=m7JwyibyhhIQz5Fz/EEA7rpXmXKpl75ULnnLve+2FO24c/BNd97bpLVoPB9NFy1cX8 NIi1kaWy6NFoItL+myROxuycO0DgDhxivR1Rh7IW4i39usZz9r1l+SriTXdrHU4iyewM QA77GnAQDiwMHftD5C+c0G2GC384RprsYlLpAcQE2C+gDegfvf/k4JJFKXqEIvWQOz40 qV8O+S49nNY2T3YEL1NS7PxT2U25vYL7VchaEbBWgI8iPbPp8Qo4nf/R3Y5TxZdGmpfg SzxyO57u+LUJe91OlLWCDJDLEEAtdF/u6/cNUjVLZsZDAFx6v3c5vZyGinqtHpO+BzEf 3xqQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Q5UVUj9RLeQGinQvNojj+g10laQqR5okl6sEhon9WRk=; b=ToCzzLK+n9BtTrCoAN+/cjSan5gU5QBrFjtnxyRUDu7OovUQwXsLQSnhpnCCTWWI5y eu55AZblfcHZudLVrN3c+cRuWF8lrIcHBVOgzN0NJLWZ9CE1rqW8SIxR4lSgTEmq099u 69jrwGp53gK6s3EkS50yi0Fcf5HdBEixYvpoOghi5czbRjqPxoTvYmShSnzigq9ZS8tr 8LFMBGOsBtWMy4/qYbbo6FM3ySmkH6QdnU+rpwvAla4mnvmxCFfu7HdB4A6zLfT73sG7 ufNiwIA1BPugZHLAyI4dT7IEM3aqxr6WmOTL+ZFnbJahAXGo07vCXgZ6zbrO7elS7WG5 7kaQ== X-Gm-Message-State: AG10YORT2HB9dRiqXgYot57b6AjpO3RXmayUWUUi1vKaCsqH7sQQUpxV/7cN+viX9am2Qg== X-Received: by 10.28.173.208 with SMTP id w199mr14193707wme.45.1454386072626; Mon, 01 Feb 2016 20:07:52 -0800 (PST) Received: from mguzik.localdomain (ip-62-245-66-110.net.upcbroadband.cz. [62.245.66.110]) by smtp.gmail.com with ESMTPSA id n131sm550333wmf.9.2016.02.01.20.07.51 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 01 Feb 2016 20:07:52 -0800 (PST) From: Mateusz Guzik To: kib@freebsd.org Cc: freebsd-hackers@freebsd.org, Mateusz Guzik Subject: [PATCH 1/2] fork: pass arguments to fork1 in a dedicated structure Date: Tue, 2 Feb 2016 05:07:48 +0100 Message-Id: <1454386069-29657-2-git-send-email-mjguzik@gmail.com> X-Mailer: git-send-email 2.4.3 In-Reply-To: <1454386069-29657-1-git-send-email-mjguzik@gmail.com> References: <20160201103632.GL91220@kib.kiev.ua> <1454386069-29657-1-git-send-email-mjguzik@gmail.com> X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 02 Feb 2016 04:07:54 -0000 From: Mateusz Guzik --- sys/compat/cloudabi/cloudabi_proc.c | 7 +++++- sys/compat/linux/linux_fork.c | 17 ++++++++++---- sys/kern/init_main.c | 6 +++-- sys/kern/kern_fork.c | 46 +++++++++++++++++++++++++------------ sys/kern/kern_kthread.c | 7 ++++-- sys/sys/proc.h | 12 ++++++++-- 6 files changed, 68 insertions(+), 27 deletions(-) diff --git a/sys/compat/cloudabi/cloudabi_proc.c b/sys/compat/cloudabi/cloudabi_proc.c index d917337..010efca 100644 --- a/sys/compat/cloudabi/cloudabi_proc.c +++ b/sys/compat/cloudabi/cloudabi_proc.c @@ -75,12 +75,17 @@ int cloudabi_sys_proc_fork(struct thread *td, struct cloudabi_sys_proc_fork_args *uap) { + struct fork_req fr = {}; struct filecaps fcaps = {}; struct proc *p2; int error, fd; cap_rights_init(&fcaps.fc_rights, CAP_FSTAT, CAP_EVENT); - error = fork1(td, RFFDG | RFPROC | RFPROCDESC, 0, &p2, &fd, 0, &fcaps); + fr.fr_flags = RFFDG | RFPROC | RFPROCDESC; + fr.fr_procp = &p2; + fr.fr_pd_fd = &fd; + fr.fr_pd_fcaps = &fcaps; + error = fork1(td, &fr); if (error != 0) return (error); /* Return the file descriptor to the parent process. */ diff --git a/sys/compat/linux/linux_fork.c b/sys/compat/linux/linux_fork.c index d0f73ad..4cd521b 100644 --- a/sys/compat/linux/linux_fork.c +++ b/sys/compat/linux/linux_fork.c @@ -64,6 +64,7 @@ __FBSDID("$FreeBSD$"); int linux_fork(struct thread *td, struct linux_fork_args *args) { + struct fork_req fr = {}; int error; struct proc *p2; struct thread *td2; @@ -73,8 +74,9 @@ linux_fork(struct thread *td, struct linux_fork_args *args) printf(ARGS(fork, "")); #endif - if ((error = fork1(td, RFFDG | RFPROC | RFSTOPPED, 0, &p2, NULL, 0, - NULL)) != 0) + fr.fr_flags = RFFDG | RFPROC | RFSTOPPED; + fr.fr_procp = &p2; + if ((error = fork1(td, &fr)) != 0) return (error); td2 = FIRST_THREAD_IN_PROC(p2); @@ -97,6 +99,7 @@ linux_fork(struct thread *td, struct linux_fork_args *args) int linux_vfork(struct thread *td, struct linux_vfork_args *args) { + struct fork_req fr = {}; int error; struct proc *p2; struct thread *td2; @@ -106,8 +109,9 @@ linux_vfork(struct thread *td, struct linux_vfork_args *args) printf(ARGS(vfork, "")); #endif - if ((error = fork1(td, RFFDG | RFPROC | RFMEM | RFPPWAIT | RFSTOPPED, - 0, &p2, NULL, 0, NULL)) != 0) + fr.fr_flags = RFFDG | RFPROC | RFMEM | RFPPWAIT | RFSTOPPED; + fr.fr_procp = &p2; + if ((error = fork1(td, &fr)) != 0) return (error); td2 = FIRST_THREAD_IN_PROC(p2); @@ -130,6 +134,7 @@ linux_vfork(struct thread *td, struct linux_vfork_args *args) static int linux_clone_proc(struct thread *td, struct linux_clone_args *args) { + struct fork_req fr = {}; int error, ff = RFPROC | RFSTOPPED; struct proc *p2; struct thread *td2; @@ -170,7 +175,9 @@ linux_clone_proc(struct thread *td, struct linux_clone_args *args) if (args->flags & LINUX_CLONE_VFORK) ff |= RFPPWAIT; - error = fork1(td, ff, 0, &p2, NULL, 0, NULL); + fr.fr_flags = ff; + fr.fr_procp = &p2; + error = fork1(td, &fr); if (error) return (error); diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c index 8d5580b..a63d4e0 100644 --- a/sys/kern/init_main.c +++ b/sys/kern/init_main.c @@ -828,12 +828,14 @@ start_init(void *dummy) static void create_init(const void *udata __unused) { + struct fork_req fr = {}; struct ucred *newcred, *oldcred; struct thread *td; int error; - error = fork1(&thread0, RFFDG | RFPROC | RFSTOPPED, 0, &initproc, - NULL, 0, NULL); + fr.fr_flags = RFFDG | RFPROC | RFSTOPPED; + fr.fr_procp = &initproc; + error = fork1(&thread0, &fr); if (error) panic("cannot fork init: %d\n", error); KASSERT(initproc->p_pid == 1, ("create_init: initproc->p_pid != 1")); diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index e7d7276..3b51b7f 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -101,10 +101,13 @@ struct fork_args { int sys_fork(struct thread *td, struct fork_args *uap) { + struct fork_req fr = {}; int error; struct proc *p2; - error = fork1(td, RFFDG | RFPROC, 0, &p2, NULL, 0, NULL); + fr.fr_flags = RFFDG | RFPROC; + fr.fr_procp = &p2; + error = fork1(td, &fr); if (error == 0) { td->td_retval[0] = p2->p_pid; td->td_retval[1] = 0; @@ -118,16 +121,20 @@ sys_pdfork(td, uap) struct thread *td; struct pdfork_args *uap; { + struct fork_req fr = {}; int error, fd; struct proc *p2; + fr.fr_flags = RFFDG | RFPROC | RFPROCDESC; + fr.fr_procp = &p2; + fr.fr_pd_fd = &fd; + fr.fr_pd_flags = uap->flags; /* * It is necessary to return fd by reference because 0 is a valid file * descriptor number, and the child needs to be able to distinguish * itself from the parent using the return value. */ - error = fork1(td, RFFDG | RFPROC | RFPROCDESC, 0, &p2, - &fd, uap->flags, NULL); + error = fork1(td, &fr); if (error == 0) { td->td_retval[0] = p2->p_pid; td->td_retval[1] = 0; @@ -140,11 +147,13 @@ sys_pdfork(td, uap) int sys_vfork(struct thread *td, struct vfork_args *uap) { - int error, flags; + struct fork_req fr = {}; + int error; struct proc *p2; - flags = RFFDG | RFPROC | RFPPWAIT | RFMEM; - error = fork1(td, flags, 0, &p2, NULL, 0, NULL); + fr.fr_flags = RFFDG | RFPROC | RFPPWAIT | RFMEM; + fr.fr_procp = &p2; + error = fork1(td, &fr); if (error == 0) { td->td_retval[0] = p2->p_pid; td->td_retval[1] = 0; @@ -155,6 +164,7 @@ sys_vfork(struct thread *td, struct vfork_args *uap) int sys_rfork(struct thread *td, struct rfork_args *uap) { + struct fork_req fr = {}; struct proc *p2; int error; @@ -163,7 +173,9 @@ sys_rfork(struct thread *td, struct rfork_args *uap) return (EINVAL); AUDIT_ARG_FFLAGS(uap->flags); - error = fork1(td, uap->flags, 0, &p2, NULL, 0, NULL); + fr.fr_flags = uap->flags; + fr.fr_procp = &p2; + error = fork1(td, &fr); if (error == 0) { td->td_retval[0] = p2 ? p2->p_pid : 0; td->td_retval[1] = 0; @@ -761,8 +773,7 @@ do_fork(struct thread *td, int flags, struct proc *p2, struct thread *td2, } int -fork1(struct thread *td, int flags, int pages, struct proc **procp, - int *procdescp, int pdflags, struct filecaps *fcaps) +fork1(struct thread *td, struct fork_req *fr) { struct proc *p1, *newproc; struct thread *td2; @@ -772,6 +783,10 @@ fork1(struct thread *td, int flags, int pages, struct proc **procp, int error, nprocs_new, ok; static int curfail; static struct timeval lastfail; + int flags, pages; + + flags = fr->fr_flags; + pages = fr->fr_pages; /* Check for the undefined or unimplemented flags. */ if ((flags & ~(RFFLAGS | RFTSIGFLAGS(RFTSIGMASK))) != 0) @@ -795,7 +810,7 @@ fork1(struct thread *td, int flags, int pages, struct proc **procp, return (EINVAL); /* Must provide a place to put a procdesc if creating one. */ - if (procdescp == NULL) + if (fr->fr_pd_fd == NULL) return (EINVAL); } @@ -806,7 +821,7 @@ fork1(struct thread *td, int flags, int pages, struct proc **procp, * certain parts of a process from itself. */ if ((flags & RFPROC) == 0) { - *procp = NULL; + *fr->fr_procp = NULL; return (fork_norfproc(td, flags)); } @@ -845,7 +860,8 @@ fork1(struct thread *td, int flags, int pages, struct proc **procp, * later. */ if (flags & RFPROCDESC) { - error = falloc_caps(td, &fp_procdesc, procdescp, 0, fcaps); + error = falloc_caps(td, &fp_procdesc, fr->fr_pd_fd, 0, + fr->fr_pd_fcaps); if (error != 0) goto fail2; } @@ -933,12 +949,12 @@ fork1(struct thread *td, int flags, int pages, struct proc **procp, lim_cur(td, RLIMIT_NPROC)); } if (ok) { - do_fork(td, flags, newproc, td2, vm2, pdflags); + do_fork(td, flags, newproc, td2, vm2, fr->fr_pd_flags); /* * Return child proc pointer to parent. */ - *procp = newproc; + *fr->fr_procp = newproc; if (flags & RFPROCDESC) { procdesc_finit(newproc->p_procdesc, fp_procdesc); fdrop(fp_procdesc, td); @@ -962,7 +978,7 @@ fail2: vmspace_free(vm2); uma_zfree(proc_zone, newproc); if ((flags & RFPROCDESC) != 0 && fp_procdesc != NULL) { - fdclose(td, fp_procdesc, *procdescp); + fdclose(td, fp_procdesc, *fr->fr_pd_fd); fdrop(fp_procdesc, td); } atomic_add_int(&nprocs, -1); diff --git a/sys/kern/kern_kthread.c b/sys/kern/kern_kthread.c index 2072dc7..970c33f 100644 --- a/sys/kern/kern_kthread.c +++ b/sys/kern/kern_kthread.c @@ -80,6 +80,7 @@ int kproc_create(void (*func)(void *), void *arg, struct proc **newpp, int flags, int pages, const char *fmt, ...) { + struct fork_req fr = {}; int error; va_list ap; struct thread *td; @@ -88,8 +89,10 @@ kproc_create(void (*func)(void *), void *arg, if (!proc0.p_stats) panic("kproc_create called too soon"); - error = fork1(&thread0, RFMEM | RFFDG | RFPROC | RFSTOPPED | flags, - pages, &p2, NULL, 0, NULL); + fr.fr_flags = RFMEM | RFFDG | RFPROC | RFSTOPPED | flags; + fr.fr_pages = pages; + fr.fr_procp = &p2; + error = fork1(&thread0, &fr); if (error) return error; diff --git a/sys/sys/proc.h b/sys/sys/proc.h index f2f4a9d..ac96566 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -907,6 +907,15 @@ struct proc *pfind_locked(pid_t pid); struct pgrp *pgfind(pid_t); /* Find process group by id. */ struct proc *zpfind(pid_t); /* Find zombie process by id. */ +struct fork_req { + int fr_flags; + int fr_pages; + struct proc **fr_procp; + int *fr_pd_fd; + int fr_pd_flags; + struct filecaps *fr_pd_fcaps; +}; + /* * pget() flags. */ @@ -930,8 +939,7 @@ int enterpgrp(struct proc *p, pid_t pgid, struct pgrp *pgrp, int enterthispgrp(struct proc *p, struct pgrp *pgrp); void faultin(struct proc *p); void fixjobc(struct proc *p, struct pgrp *pgrp, int entering); -int fork1(struct thread *, int, int, struct proc **, int *, int, - struct filecaps *); +int fork1(struct thread *, struct fork_req *); void fork_exit(void (*)(void *, struct trapframe *), void *, struct trapframe *); void fork_return(struct thread *, struct trapframe *); -- 2.7.0