辅导案例-COMP3301/COMP7308-Assignment 3
COMP3301/COMP7308 Assignment 3 (DRAFT)
• School of Information Technology and Electrical Engineering
• The University of Queensland
• Semester Two, 2019
• Revision: DRAFT $Revision: 243 $
1 OpenBSD Containers
This assignment asks you to implement a portion of the functionality necessary to provide “containers” on
OpenBSD.
Container technologies aim to provide virtualisation at the kernel level instead of at the hardware level.
This is implemented by extending a kernel to partition and isolate certain services to prevent processes in
a container from interacting with processes in another container. Such isolation may require limiting the
visibility of processes and file descriptors in the system, creating independent users and views of the file
system, virtualising the network stack, and guaranteeing access to resources.
Several container technologies exist such as Docker, Solaris Zones, FreeBSD jails, and AIX WPARs.
The tasks in this assignment will be loosely modelled on the design of Solaris Zones as documented in
PSARC/2002/174. The aim will be to implement isolation of processes and several kernel variables in
OpenBSD
This is an individual assignment. You should feel free to discuss aspects of C programming and the
assignment specification with fellow students. You should not actively help (or seek help from) other
students with the actual coding of your assignment solution. It is cheating to look at another student’s
code and it is cheating to allow your code to be seen or shared in printed or electronic form. You should
note that all submitted code may be subject to automated checks for plagiarism and collusion. If we detect
plagiarism or collusion, formal misconduct proceedings will be initiated against you. If you’re having
trouble, seek help from a member of the teaching staff. Don’t be tempted to copy another student’s code.
You should read and understand the statements on student misconduct in the course profile and on the
school web-site: https://www.itee.uq.edu.au/itee-student-misconduct-including-plagiarism
2 Specification
You will add basic support for process and some kernel variable isolation to the OpenBSD kernel and
user land by implementing a simplified zones infrastructure modelled on the Solaris specification and
implementation.
Process isolation is the prevention of a process in one zone being able to see or signal a process running in
another zone.
The exception to this isolation will be the “global” zone, which can view all processes in the system,
including those running in other zones. The ability to create, destroy, and enter zones, and signal processes
in other zones, will be limited to the root user in the global zone.
Support for zones requires the addition of several system calls.
The assignment also requires that several kernel variables accessed via the sysctl(2) system call will be
changed to have per-zone behaviour or values.
1
2.1 Code Style
Your code is to be written according to OpenBSD’s style guide, as per the style(9) man page.
2.2 Interfaces
The following system calls need to be added to the OpenBSD system
2.2.1 zone_create
zoneid_t zone_create(const char *zonename);
zone_create should create a new zone id for use in the system.
On success it should return the zone id that was created.
On failure it should return -1 and set errno accordingly:
EPERM the current program is not in the global zone
EPERM the current user is not root
EEXIST a zone with the specified name already exists
ERANGE too many zones are currently running
EFAULT zonename points to a bad address
ENAMETOOLONG the name of the zone exceeds MAXZONENAMELEN
2.2.2 zone_destroy
int zone_destroy(zoneid_t z);
zone_destroy should delete the specified zone instance.
On success it should return 0.
On failure it should return -1 and set errno accordingly:
EPERM the current program is not in the global zone
EPERM the current user is not root
ESRCH the specified zone does not exist
EBUSY the specified zone is still in use, ie, a process is still running in the zone
2.2.3 zone_enter
int zone_enter(zoneid_t z);
zone_enter moves the current process into the zone.
On success it should return 0.
On failure it should return -1 and set errno accordingly:
EPERM the current program is not in the global zone
EPERM the current user is not root
ESRCH the specified zone does not exist
2
2.2.4 zone_list
int zone_list(zoneid_t *zs, size_t *nzs);
In the global zone zone_list will provide the list of zones in the running system as an array of zoneid_ts.
If run in a non-global zone, the list will only contain the current zone.
The value at nzs will refer to the number of array entries in zs on input.
On success it should return 0 and the value at nzs will be set to the number of zones listed in zs.
On failure it should return -1 and set errno accordingly:
EFAULT zs or nzs point to a bad address
ERANGE if the number at nzs is less than the number of running zones in the system
2.2.5 zone_lookup
zoneid_t zone_lookup(const char *name);
zone_lookup provides the id associated with the name. If run in a non-global zone, only the current zone
may be specified.
On success it will return the zone id that is associated to the name. If name is NULL the id of the process
must be returned.
On failure it should return -1 and set errno accordingly:
ESRCH The specified zone does not exist
ESRCH The specified zone is not visible in a non-global zone
EFAULT name refers to a bad memory address
ENAMETOOLONG the name of the zone exceeds MAXZONENAMELEN
2.2.6 zone_name
int zone_name(zoneid_t z, char *name, size_t namelen);
zone_name provides the name of the zone identified by z. If run in a non-global zone, only the current
zone may be specified. If the zone id z is -1, it will return the name of the current zone.
On success it will return 0 with the name returned in the memory specified by name and namelen.
On failure it should return -1 and set errno accordingly:
ESRCH The specified zone does not exist
ESRCH The specified zone is not visible in a non-global zone
EFAULT name refers to a bad memory address
ENAMETOOLONG The requested name is longer than namelen bytes.
2.2.7 fork(2)
When a process forks, the child must inherit the zone it is running in from its parent.
The only way for a process to change zones is via the zone_enter syscall, which is limited to root processes
in the global zone.
3
2.2.8 kill(2)
The kernel signalling code should be modified to provide the following semantics:
• If any user in a non-global zone tries to signal any process in another zone, it should fail with
ESRCH.
• If a non-root user in the global zone signals a process in another zone, it should fail with EPERM.
• root in the global zone may signal any process in any zone
• Users within a zone should get normal signalling semantics
2.2.9 sysctl(3)
The kernel side of sysctl should modify its handling of CTL_KERN KERN_PROC and KERN_FILE to
filter results.
• the kinfo_proc and kinfo_file structures have been modified to include a ps_zoneid field which
identifies the zone the process is running in
• the global zone does not get a filtered list of processes or files
• non-global zones will get a list of processes or files that exist in their current zone
The following CTL_KERN variables will be modified to have per-zone settings:
KERN_HOSTNAME The global zone will default to an empty hostname value. Non-global zones
will default the host name to the zone name it is created with. The host name value can only be
changed by the root user within a zone.
KERN_DOMAINNAME The domain name value will default to an empty string in both the global
and non-global zones. The domain name value can only be changed by the root user within a zone.
KERN_HOSTID The host identifier will default to 0. The host identifier can only be changed by the
root user within a zone.
KERN_BOOTTIME The boot-time value for non-global zones will be set to the time at which a zone
was created. It is read-only.
The following CTL_KERN variables will be modified to be read-only in non-global zones:
• KERN_MAXCLUSTERS
• KERN_CACHEPCT
• KERN_POOLDEBUG
2.2.10 struct process
struct process represents the kernels state relating to a running program. This type should be extended
to record which zone the process is running in.
2.3 Boilerplate
A diff will be provided that adds header files, programs, and modifications to the system to use and test
the kernel zone functionality. The diff can be applied by running the following:
$ cd /usr/src
$ patch < /path/to/assignment3-boilerplate.diff
Hmm... Looks like a unified diff to me...
The following types and limits will be made available to the system (both kernel and userland) via a
sys/zone.h header file. Data structures and programs have been extended to use these values, and will
be provided as part of a boilerplate diff:
4
2.3.1 zoneid_t
Zones will be uniquely identified in the running system by a numerical identifier using the following type:
typedef int zoneid_t;
2.3.2 MAXZONENAMELEN
Zones will also be uniquely identified by a name in the running system. The MAXZONENAMELEN macro
states what the longest name for a zone may be, including a terminating NUL character.
2.3.3 MAXZONES
The system should be limited to only providing up to MAXZONES at a time.
2.3.4 MAXZONEIDS
While the system is limited to running a MAXZONES number of zones (including the global zone, the limit
on identifiers is higher to avoid rapid reuse.
2.3.5 struct kinfo_proc
struct kinfo_proc is a serialisation of the kernels process and proc structures for userland to consume.
It has been extended to include the id of the zone that the process is running in.
2.3.6 struct kinfo_file
struct kinfo_file is a serialisation of the kernels file descriptor information for userland to consume.
It has been extended to include the id of the zone that the owning process is running in.
2.3.7 libc
libc has been updated to provide stubs for the system calls described above. The system provides a
zones.h file that prototypes the system call stubs.
Programs needing to interact with the kernels zone infrastructure can #include and link to
libc.
2.3.8 Userland Programs
To the zones subsystem, some userland utilities should be modified and implemented.
When appropriate, programs should be modified to accept the following options:
-z zone Limit the scope of the command to the specified zone. The zone may be specified by name, or
by numeric id.
-Z The name of the zone should be added to the programs output.
All changes should be documented in the relevant manual pages.
The following changes should be implemented:
5
2.3.9 ps(1)
• add the -z option
When a zone is specified, the list of processes displayed by ps will be limited to those processes running in
the specified zone.
• add the -Z option
-Z should cause the zones name to be prepended to the columns that are output by ps(1). The column
should be a maximum of 8 characters wide, with its value right aligned. If a zone name exceeds 8
characters, it should be truncated to 7 characters and suffixed with an asterisk (*).
Additionally, “ZONES” may be specified as a column in custom column format specifiers.
2.3.10 pgrep, pkill
• add the -z flag
pgrep and pkill will only match on processes that are running in the specified zone.
2.3.11 fstat
• add the -z option
When a zone is specified, the list of files displayed by fstat will be limited to those owned by processes
running in the specified zone.
• add the -Z option
-Z should cause the USER column to be replaced with a ZONE column that displays the name of the
zone that the process is running inside of.
2.3.12 zone(8)
zone(8) is a new program and will be installed under /usr/sbin.
The usage output is shown below:
usage: zone create zonename
zone destroy zonename|zoneid
zone list
zone id [zonename]
zone name [zoneid]
zone exec zonename|zoneid program ...
The sub-commands map to the system calls described above. Note that the arguments to the id, and
name sub-commands are optional, and default to arguments to the syscalls that look up the information
for the current zone.
6
2.4 Recommendations
2.4.1 APIs
The APIs may be useful in the implementation of the required functionality.
• rwlock(9) - interface to read/write locks
• copy(9) - kernel copy functions
• malloc(9) - kernel memory allocator
• pool(9) - resource-pool manager
• atomic_inc_int(9) - atomic increment operations
• atomic_dec_int(9) - atomic decrement operations
• atomic_cas_uint(9) - atomic compare-and-swap operations
• sysctl(3) - get or set system information
• queue(3) - implementations of singly-linked lists, doubly-linked lists, simple queues, and tail queues
• tree(3) - implementations of splay and red-black trees
• execvp(3) - execute a file
2.5 Constraints
Only the sysctl interfaces used by ps, pgrep, fstat, and kill will be tested. Other mechanisms for interacting
with processes such as ptrace, ktrace, systrace, process groups, sessions, libkvm using /dev/mem or
/dev/kmem will not be tested and do not need to implement isolation between processes in zones.
3 Submission
You are required to implement the changes to the OpenBSD source tree, and submit a diff of them against
an OpenBSD CVS server to your subversion repository in an ass3 directory. You are welcome to store
changes to files in another portion of the tree.
Note that files must be added with CVS before diffs of them can be generated. Diffs against CVS should be
in the unified diff format. Therefore use cvs diff -uNp when generating the diff to commit to subversion.
Submission must be made electronically by committing to your Subversion repository on
source.eait.uq.edu.au. In order to mark your assignment the markers will check out ass3
from your repository. Code checked in to any other part of your repository will not be marked.
As per the source.eait.uq.edu.au usage guidelines, you should only commit a source diff.
The due date for the code submission is the beggining of your prac session.
7
51作业君 51作业君

Email:51zuoyejun

@gmail.com

添加客服微信: ITCSdaixie