Module Name:    src
Committed By:   martin
Date:           Fri Sep 20 11:00:21 UTC 2024

Modified Files:
        src/distrib/sets/lists/comp [netbsd-10]: mi
        src/share/man/man9 [netbsd-10]: Makefile
Added Files:
        src/share/man/man9 [netbsd-10]: versioningsyscalls.9

Log Message:
Pull up following revision(s) (requested by rin in ticket #887):

        share/man/man9/versioningsyscalls.9: revision 1.1
        share/man/man9/versioningsyscalls.9: revision 1.2
        share/man/man9/versioningsyscalls.9: revision 1.3
        share/man/man9/versioningsyscalls.9: revision 1.4
        share/man/man9/versioningsyscalls.9: revision 1.5
        share/man/man9/versioningsyscalls.9: revision 1.6
        share/man/man9/versioningsyscalls.9: revision 1.7
        share/man/man9/Makefile: revision 1.467
        distrib/sets/lists/comp/mi: revision 1.2435
        distrib/sets/lists/comp/mi: revision 1.2436

Document how system call versioning is done. From this summer's compat-linux
GSoC, by Theodore Preduta.

fix typo
versioningsyscalls(9): markup fixes

While here, fix the pasto for the new ino_t and time_t size.

Forgot to commit the expanded userland portion

versioningsyscalls(9): wrap long line in the example

versioningsyscalls.9: fix typo

explain what the current and new numbering practice are.

s/and/an/


To generate a diff of this commit:
cvs rdiff -u -r1.2425.2.7 -r1.2425.2.8 src/distrib/sets/lists/comp/mi
cvs rdiff -u -r1.465.2.4 -r1.465.2.5 src/share/man/man9/Makefile
cvs rdiff -u -r0 -r1.7.4.2 src/share/man/man9/versioningsyscalls.9

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/distrib/sets/lists/comp/mi
diff -u src/distrib/sets/lists/comp/mi:1.2425.2.7 src/distrib/sets/lists/comp/mi:1.2425.2.8
--- src/distrib/sets/lists/comp/mi:1.2425.2.7	Fri Sep 20 10:27:10 2024
+++ src/distrib/sets/lists/comp/mi	Fri Sep 20 11:00:20 2024
@@ -1,4 +1,4 @@
-#	$NetBSD: mi,v 1.2425.2.7 2024/09/20 10:27:10 martin Exp $
+#	$NetBSD: mi,v 1.2425.2.8 2024/09/20 11:00:20 martin Exp $
 #
 # Note: don't delete entries from here - mark them as "obsolete" instead.
 ./etc/mtree/set.comp				comp-sys-root
@@ -12915,6 +12915,7 @@
 ./usr/share/man/cat9/vdead_check.0		comp-sys-catman		.cat
 ./usr/share/man/cat9/vdevgone.0			comp-sys-catman		.cat
 ./usr/share/man/cat9/veriexec.0			comp-sys-catman		.cat
+./usr/share/man/cat9/versioningsyscalls.0	comp-sys-catman		.cat
 ./usr/share/man/cat9/vfinddev.0			comp-sys-catman		.cat
 ./usr/share/man/cat9/vflush.0			comp-sys-catman		.cat
 ./usr/share/man/cat9/vflushbuf.0		comp-sys-catman		.cat
@@ -21228,6 +21229,7 @@
 ./usr/share/man/html9/vdead_check.html		comp-sys-htmlman	html
 ./usr/share/man/html9/vdevgone.html		comp-sys-htmlman	html
 ./usr/share/man/html9/veriexec.html		comp-sys-htmlman	html
+./usr/share/man/html9/versioningsyscalls.html	comp-sys-htmlman	html
 ./usr/share/man/html9/vfinddev.html		comp-sys-htmlman	html
 ./usr/share/man/html9/vflush.html		comp-sys-htmlman	html
 ./usr/share/man/html9/vflushbuf.html		comp-sys-htmlman	html
@@ -29774,6 +29776,7 @@
 ./usr/share/man/man9/vdead_check.9		comp-sys-man		.man
 ./usr/share/man/man9/vdevgone.9			comp-sys-man		.man
 ./usr/share/man/man9/veriexec.9			comp-sys-man		.man
+./usr/share/man/man9/versioningsyscalls.9	comp-sys-man		.man
 ./usr/share/man/man9/vfinddev.9			comp-sys-man		.man
 ./usr/share/man/man9/vflush.9			comp-sys-man		.man
 ./usr/share/man/man9/vflushbuf.9		comp-sys-man		.man

Index: src/share/man/man9/Makefile
diff -u src/share/man/man9/Makefile:1.465.2.4 src/share/man/man9/Makefile:1.465.2.5
--- src/share/man/man9/Makefile:1.465.2.4	Fri Sep 20 10:27:11 2024
+++ src/share/man/man9/Makefile	Fri Sep 20 11:00:20 2024
@@ -1,4 +1,4 @@
-#       $NetBSD: Makefile,v 1.465.2.4 2024/09/20 10:27:11 martin Exp $
+#       $NetBSD: Makefile,v 1.465.2.5 2024/09/20 11:00:20 martin Exp $
 
 #	Makefile for section 9 (kernel function and variable) manual pages.
 
@@ -67,7 +67,8 @@ MAN+=	secmodel_suser.9 \
 	usbd_status.9 usbdi.9 usbnet.9 \
 	userret.9 ustore.9 \
 	uvm.9 uvm_hotplug.9 uvm_km.9 uvm_map.9 \
-	vattr.9 veriexec.9 vcons.9 vfs.9 vfs_hooks.9 vfsops.9 vfssubr.9 \
+	vattr.9 veriexec.9 vcons.9 versioningsyscalls.9 \
+	vfs.9 vfs_hooks.9 vfsops.9 vfssubr.9 \
 	video.9 vme.9 vnfileops.9 vnode.9 vnodeops.9 vnsubr.9 vmem.9  \
 	wapbl.9 wdc.9 workqueue.9 \
 	wsbell.9 wscons.9 wsdisplay.9 wsfont.9 wskbd.9 wsmouse.9 \

Added files:

Index: src/share/man/man9/versioningsyscalls.9
diff -u /dev/null src/share/man/man9/versioningsyscalls.9:1.7.4.2
--- /dev/null	Fri Sep 20 11:00:21 2024
+++ src/share/man/man9/versioningsyscalls.9	Fri Sep 20 11:00:20 2024
@@ -0,0 +1,374 @@
+.\"	$NetBSD: versioningsyscalls.9,v 1.7.4.2 2024/09/20 11:00:20 martin Exp $
+.\"
+.\" Copyright (c) 2023 The NetBSD Foundation, Inc.
+.\" All rights reserved.
+.\"
+.\" This code is derived from software contributed to The NetBSD Foundation
+.\" by Theodore Preduta.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+.\" PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.Dd May 20, 2024
+.Dt VERSIONINGSYSCALLS 9
+.Os
+.
+.Sh NAME
+.Nm versioningsyscalls
+.Nd guide on versioning syscalls
+.
+.Sh DESCRIPTION
+.Nx
+has the ability to change the ABI of a syscall whilst retaining backwards
+compatibility with existing code.
+This means that existing code keeps working the same way as before, and
+new code can use new features and/or functionality.
+In the past this has allowed
+.Ft dev_t
+to move from 16 bits to 32 bits,
+.Ft ino_t
+and
+.Ft time_t
+to move from 32 bits to 64 bits,
+and adding fields to
+.Ft struct kevent
+without disturbing existing binaries.
+To achieve this both kernel and userland changes are required.
+.Pp
+In the kernel, a new syscall is added with a new ABI, and the old syscall
+is retained and moved to a new location that holds the compatibility syscalls
+.Pq Pa src/sys/compat .
+Kernels can be compiled with or without backwards compatibility syscalls.
+See the
+.Dv COMPAT_ Ns Ar XX
+options in
+.Xr options 4 .
+.Pp
+In userland, the original syscall stub is moved into
+.Pa src/lib/libc/compat
+retaining the same symbol name and ABI.
+The new stub is added to libc, and in the header file the syscall symbol is
+made to point to the new name with the new ABI.
+.Pp
+This is done via symbol renaming instead of ELF versioned symbols for
+historical reasons.
+.Nx
+has retained binary compatibility with most syscalls since
+.Nx 0.9
+with the exception of Scheduler Activation syscalls which are not being
+emulated because of the cost and safety of doing so.
+.Pp
+To avoid confusion, the following words are used to disambiguate which version
+of the system call is being described.
+.Bl -tag -offset indent -width Em
+.It Em old
+Any previous versions of the syscall, which have already been versioned and
+superseded by the current version of the syscall.
+.It Em current
+The version of the syscall currently in use.
+.It Em next
+The version of the syscall that will become standard in the next release.
+.El
+.Pp
+Additionally,
+.Ar CNUM
+always represents the last
+.Nx
+release where the current
+version of the system call is the default, multiplied by ten and retaining a
+leading zero.
+For example
+.Nx 0.9
+has
+.Dv COMPAT_09
+whereas
+.Nx 10.0
+has
+.Dv COMPAT_100 .
+.
+.Sh VERSIONING THE SYSCALL
+This section describes what needs to be modified to add the new version of the
+syscall.
+It assumes the current version of the syscall is
+.Fn my_syscall "struct my_struct *ms"
+and that
+.Ft my_struct
+will be versioned.
+If not versioning a struct, passages that mention
+.Ft my_struct
+can be ignored.
+.Pp
+The syscall version suffix
+.Dv VNUM
+indicates the first release of
+.Nx
+the system call will appear in.
+The compat version 
+.Dv CNUM
+is the last version of
+.Nx the old system call was used.
+Typically VNUM = CNUM + 1 .
+.Pp
+For example if you are versioning
+.Xr getcontext 2
+just after
+.Nx 11 
+was released, and the original system call was called
+.Fn getcontext ,
+the system call will become
+.Fn __getcontext12
+and the compat entry point will become
+.Fn compat_11_getcontext .
+.Pp
+Next time
+.Xr getcontext 2
+needs versioning, for example just after
+.Nx 15
+was released, it will become
+.Fn __getcontext16
+and the compat entry will become
+.Fn compat_15___getcontext12 .
+.Pp
+Please note that the historical practice up to
+.Nx 11
+has been that the syscall suffix matched the version when the syscall
+was last used.
+.
+.Ss Versioning structs
+To version
+.Ft struct my_struct ,
+first make a copy of
+.Ft my_struct
+renamed to
+.Ft my_structCNUM
+in an equivalent header in
+.Pa sys/compat/sys .
+After that, you can freely modify
+.Ft my_struct
+as desired.
+.
+.Ss Versioning the entry point
+The stub for the next version of the syscall will be
+.Fn __my_syscallVNUM ,
+and will have entry point
+.Fn sys___my_syscallVNUM .
+.
+.Ss Modifying syscalls.conf
+.Pa sys/kern/syscalls.conf
+may need to be modified to contain
+.Li compat_CNUM
+in the
+.Va compatopts
+variable.
+.
+.Ss Modifying syscalls.master
+First, add the next syscall to
+.Pa sys/kern/syscalls.master
+keeping
+.Fn my_syscall
+as the name, and set the (optional) compat field of the declaration to
+.Ar CNUM .
+.Pp
+Next, modify the current version of the syscall, and replace the type
+field
+.Pq usually just Li STD
+with
+.Dv COMPAT_CNUM MODULAR compat_CNUM .
+.Pp
+The keyword
+.Dv MODULAR
+indicates that the system call can be part of a kernel module.
+Even if the system call was not part of a module before, now it will be part
+of the
+.Dv COMPAT_CNUM
+module.
+.Pp
+Finally, if applicable, replace the types of the current and old versions of the
+syscall with the compat type.
+.Pp
+Overall, the final diff should look like
+.Bd -literal
+- 123 STD                           { int|sys||my_syscall(struct my_struct *ms); }
++ 123 COMPAT_CNUM MODULAR compat_CNUM { int|sys||my_syscall(struct my_structCNUM *ms); }
+\&...
++ 456 STD               	    { int|sys|VNUM|my_syscall(struct my_struct *ms); }
+.Ed
+.
+.Ss Modifying Makefile.rump
+If the current syscall is rump,
+.Pa sys/rump/Makefile.rump
+must contain
+.Ar CNUM
+in the
+.Dv RUMP_NBCOMPAT
+variable.
+.
+.Ss Regenerating the system calls
+If versioning structs, then modify
+.Pa sys/kern/makesyscalls.sh
+by adding an entry for
+.Ft struct my_structCNUM
+type to
+.Va uncompattypes .
+.Pp
+The
+.Va uncompattypes
+map is used in
+.Xr rump 7
+system call table generation, to map from the versioned types to the original
+names since
+.Xr rump 7
+wants to have a non-versioned copy of the system call table.
+.Pp
+Then regenerate the syscall tables in the usual way, first by running
+.Pa sys/kern/makesyscalls.sh ,
+then if the system call is rump, doing a build in
+.Pa sys/rump
+and then running
+.Pa sys/rump/makerumpsyscalls.sh
+passing it the path to the result of the build you just did as its first
+argument.
+.
+.Sh KERNEL COMPATIBILITY
+This section covers maintaining compatibility at the kernel level, by
+adding an entry point for the current syscall in an appropriate compat
+module.
+For the purposes of this section, we assume the current
+syscall has entry point
+.Fn sys_my_syscall
+and lives inside
+.Pa sys/kern/my_file.c .
+.
+.Ss Creating the compat current syscall
+The compat version of the current syscall has entry point
+.Fn compat_CNUM_sys_my_syscall ,
+and should be implemented in
+.Pa sys/compat/common/my_file_CNUM.c
+with the same semantics as the current syscall.
+Often this involves translating the arguments to the next syscall,
+and then calling that syscall's entry point.
+.
+.Ss Adding it to the compat module
+.Pa sys/compat/common/my_file_CNUM.c
+must contain an array of
+.Ft struct syscall_package
+that declares the mapping between syscall number and entry point,
+terminating in a zero element (see sample diff below).
+.Pp
+Additionally,
+.Pa sys/compat/common/my_file_CNUM.c
+must contain two functions,
+.Fn my_file_CNUM_init
+and
+.Fn my_file_CNUM_fini
+that are used to initialize/clean up anything related to this syscall.
+At the minimum they must make calls to
+.Fn syscall_establish
+and
+.Fn syscall_disestablish
+respectively, adding and removing the syscalls.
+The stubs for these functions should be located in
+.Pa sys/compat/common/compat_mod.h .
+.Pp
+Overall,
+.Pa sys/compat/common/my_file_CNUM.c
+must at the minimum contain
+.Bd -literal -offset indent
+static const struct syscall_package my_file_CNUM_syscalls[] = {
+        { SYS_compat_CNUM_my_syscall, 0,
+            (sy_call_t *)compat_CNUM_sys_my_syscall },
+        { 0, 0, NULL },
+};
+
+int
+compat_CNUM_my_syscall(...)
+{ /* Compat implementation goes here. */ }
+
+int
+my_file_CNUM_init(void)
+{ return syscall_establish(NULL, my_file_CNUM_syscalls); }
+
+int
+my_file_CNUM_fini(void)
+{ return syscall_disestablish(NULL, my_file_CNUM_syscalls); }
+.Ed
+.Pp
+Finally,
+.Pa sys/compat/common/compat_CNUM_mod.c
+needs to be modified to have its
+.Fn compat_CNUM_init
+and
+.Fn compat_CNUM_fini
+functions call
+.Fn my_file_CNUM_init
+and
+.Fn my_file_CNUM_fini
+respectively.
+.
+.Ss Modifying old compat syscalls
+If the current syscall has already been versioned, you might need to
+modify the old compat syscalls in
+.Pa sys/compat/common
+to either use the next syscall or the current compat syscall.
+Note that compat code can be made to depend on compat code for more
+recent releases.
+.Sh USERLAND COMPATIBILITY
+With the exception of the libraries described below, making the rest
+of userland work will just involve recompiling, and perhaps changing a
+constant or a
+.Li #define .
+.
+.Ss libc
+A userland version of any old and current versions of the syscall must be
+implemented.
+For the current syscall with stub
+.Fn my_syscall struct\ my_struct\ *ms
+in
+.Pa sys/sys/my_header.h ,
+an implementation of
+.Fn my_syscall
+must be written in
+.Pa lib/libc/compat/sys/compat_my_syscall.c .
+.Pp
+Additionally, a call to
+.Fn __warn_references
+must be added in
+.Pa lib/libc/compat/sys/compat_my_syscall.c
+to warn of any uses of the compat syscall and mention how to use the next
+version of the syscall.
+In almost all cases the instructions on how to use the next version of the
+syscall will be
+.Dq include <sys/my_header.h> to generate correct reference .
+.Pp
+Overall,
+.Pa lib/libc/compat/sys/compat_my_syscall.c
+must at the minimum include
+.Bd -literal -offset indent
+#include <sys/compat/my_header.h>
+
+__warn_references(my_syscall,
+    "warning: reference to compatibility my_syscall();"
+    " message on how to use the next my_syscall()");
+
+int
+my_syscall()
+{ /* Compat implementation goes here. */ }
+.Ed

Reply via email to