辅导案例-COMP3301/COMP7308
COMP3301/COMP7308 2019 Assignment 2 (DRAFT)• DRAFT• Revision : 2321 Process Accounting Pseudo Device DriverThis assignment asks you to write a device driver for the OpenBSD kernel that implements a replacementfor the current process accounting facility.Process accounting is a facility that allows administrators to audit the system resource utilisation ofcommands run by users.Process accounting in OpenBSD is currently implemented via the acct(2) system call that enables ordisables of logging of commands to a file, the accton(8) utility for calling the syscall, and the sa(8) andlastcom(8) utilities for processing said file. The format of the file is described in the acct(5) manualpage.A pseudo device driver is an actual driver, but not one that implements support for physical hardware. Itprovides a virtual, software only, service for user programs to use.Device special file are entries in a filesystem that refer to a set of functions in the kernel that implementfile behaviour such as open, read, write, and close.Examples of pseudo device drivers that provide device special files are zero(4), null(4), tun(4), andtap(4).This is an individual assignment. You should feel free to discuss aspects of C programming and theassignment specification with fellow students. You should not actively help (or seek help from) otherstudents with the actual coding of your assignment solution. It is cheating to look at another student’scode and it is cheating to allow your code to be seen or shared in printed or electronic form. You shouldnote that all submitted code may be subject to automated checks for plagiarism and collusion. If we detectplagiarism or collusion, formal misconduct proceedings will be initiated against you. If you’re havingtrouble, 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 theschool web-site: https://www.itee.uq.edu.au/itee-student-misconduct-including-plagiarism2 SpecificationsThis assigment specifies the replacement of the acct(2) system call with a pseudo device driver thatprovides a device special file that produces messages analogous to the entries written to the accountingfile.The acct(4) driver will provide a superset of the functionality that is provided by the current systemcall. The system call only records information about the process when it exits, but the driver will alsoreport information about process forks and execs.2.1 Code StyleYour code is to be written according to OpenBSD’s style guide, as per the style(9) man page.12.2 CompilationYour code is to be built as part of the kernel on an amd64 OpenBSD 6.5 or -current system.The changes to the kernel necessary to configure an acct(4) driver so it can be compiled will be suppliedas a diff available from Blackboard. The diff can be applied by running the following:dlg@r630 ~$ cd /usr/src/sysdlg@r630 sys$ patch < /path/to/assignment2-boilerplate.diffHmm... Looks like a unified diff to me...The driver must be implemented in a single file, and placed in sys/dev/acct.c next to the sys/dev/acct.hprovided by the diff described above.2.3 MessagesThe messages that a program reads from the device driver are represented as a set of structs. The kerneldriver populates the structs when the relevant events occur in the kernel, and makes them available for aprogram to read.The structure of the messages the driver should produce is provided in sys/dev/acct.h.2.3.1 Common FieldsAll messages from the driver start with a common set of fields that are contained in struct acct_common.The other messages all contain struct acct_common as their first field.The first three fields of the common structure refer to the message itself, rather than the process themessage is about. The ac_type field contains a number representing the type of the current message, eg, avalue of 0 or ACCT_MSG_FORK states that the message is about a process forking and should be interpretedas the associated message structure.The ac_len field contains the number of bytes used for this message, including the ac_type and ac_lenfields.ac_seq is a simple wrapping counter that increments for every message that the driver generates. If thedriver receives notification from the rest of the kernel that an event has occurred (eg, acct_fork() iscalled when a process forks), but is unable to generate a message about it, the sequence number shouldstill be incremented so that the userland consumer of the messages will know that an event has been lost.The counter should be reset to 0 when the acct(4) device is opened.The remaining common fields should be set for the process the message is about.2.3.2 exit messageThe exit message corresponds with struct acct_exit. The information in this message corresponds withthe information described in acct(5). acct(2) may be used as a reference when filling in the informationin this message.2.3.3 fork eventThe fork message corresponds with struct acct_fork, and is generated when a process forks a new child.The information in the message should be based on the parent of the new process, apart from ac_cpidwhich contains the process ID of the new child. Note that acct_fork is given a pointer to the child, notthe parent.22.3.4 exec eventThe exec message corresponds with struct acct_exec, and is geneated when a process calls exec(). Itexists to record the new name of the binary the program is executing.2.4 Driver entry pointsacct.c must provide the following functions to support the integration into the kernel, and to providethe required interface for userland to access the driver.2.4.1 Kernel entry pointsThe kernel is patched to call 3 functions when a process forks, execs, or exits. Those functions areacct_fork(), acct_exec(), and acct_exit() respectively. All these functions take a struct process* as their only argument, and do not return anything to the caller.2.4.2 Userland entry pointsacctattach() is called when the kernel starts running for the driver to configure any state needed for itto operate.acctopen() is called when a program attempts to open a device file with the corresponding major numberto this driver. It should allow only the 0th minor to be opened, opened exclusively, and only opened forreading. Read/write or write only opens of the device should fail with EPERM. The sequence number forgenerated messages should be reset to 0 on every open.acctclose() should clean up any state associated with the open driver.acctioctl() should support FIONREAD, and FIONBIO as per the ioctl(2) manpage. FIONASYNC shouldnot be implemented.acctread() dequeues a a single message, and copies as much of that one message as possible to userland.It should support non-blocking reads.acctwrite() should return EOPNOTSUPP as the driver does not support being written to by a userlandprocess.The driver should support non-blocking I/O (well, just O) by implementing acctpoll() andacctkqfilter().3 SubmissionYou are required to implement the acct(4) driver by writing your code in a single file, sys/dev/acct.c.This file in the OpenBSD source tree will be committed to your SVN repo as ass2/acct.c.Submission must be made electronically by committing to your Subversion repository onsource.eait.uq.edu.au. In order to mark your assignment the markers will check out ass2/acct.cfrom 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 source code and Makefiles.The due date for the code submission is the beggining of your prac session, either 10am on Wednesdaythe 19th, or 2pm on Thursday the 20th of September 2018. Note that no submissions can be made morethan 120 hours past the deadline under any circumstances.33.1 RecommendationsThe following kernel functionality may or may not be useful in the implementation of this assigment:• malloc(9) - kernel memory allocator• pool(9) - resource pool manager• TAILQ_INIT(3) - doubly-linked list macros• KASSERT(9) - kernel assert routines• uiomove(9) - move (copy) data described by a struct uio• mutex(9) - kernel mutex implementation• rwlock(9) - kernel read/write lock implementation• tsleep(9), and wakeup(9) - process context sleep and wakeupThe majority of the OpenBSD kernel still runs under a Big Giant lock, known as the kernel lock, whichcan be used to provide implicit serialisation of code in this driver. The kernel lock is taken and releasedwith KERNEL_LOCK() and KERNEL_UNLOCK() respectively, or if it is assumed to be held, may be assertedwith KERNEL_ASSERT_LOCKED().4 TestingA tool will be provided that reads from the special file and parses the messages as per sys/dev/acct.h.4