14.2 Building Modules With Static Probes

Note

The following example requires that you link the module against a UEK version that supports the DTrace modules, which can be either UEK R5 or UEK R4 for Oracle Linux 7 or UEK R4 for Oracle Linux 6.

A bug in the current implementation means that a module containing SDT probes must be built from two or more source files.

The following Kbuild and Makefile are used to build the example pseudo driver module revdev.ko and a test program named testrevdev.

Kbuild Example

bj-m            += revdev.o

revdev-y        := rev_dev.o rev_mod.o

Makefile Example

Note

All of the command lines in the Makefile, such as those beginning with gcc in the following example, must start with tabs.

KERNEL_DIR = /lib/modules/`uname -r`/build

modules:: testrevdev

install:: modules_install

testrevdev: testrevdev.c
  gcc -o testrevdev testrevdev.c

%::
        $(MAKE) -C $(KERNEL_DIR) M=`pwd` $@

The source file for testrevdev is testrevdev.c.

testrevdev.c Example

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define DEVICE_FILE "/dev/revdev"

int main() {
    char buf[81];
    int i, fd, n;

    if ((fd = open(DEVICE_FILE, O_RDWR)) != 0) {
        perror("open");
        exit(1);
    }

    i=0;
    while (1) {
        (i++)%20;
        printf("Write: ");
        scanf(" %80[^\n]", buf);
        n = strlen(buf);
	if (!strncmp(buf, "exit", 4))
            break;
	else if (!strncmp(buf, "ioctl", 5))
            ioctl(fd,128,i);
        else {
            write(fd, buf, n);
            read(fd, buf, n);
            buf[n]='\0';
            printf(" Read: %s\n", buf);
        }
    }

    close(fd);
    exit(0);
}

When run, testrevdev reads a string that you enter, writes the string to the revdev device, and then reads the reversed string from the device.

If the input string begins with ioctl, the program calls ioctl on the open file descriptor, which invokes the device's unlocked_ioctl routine. An input string that begins with exit terminates the program.

To build the module and test program, use the make command:

# make
make -C /lib/modules/`uname -r`/build M=`pwd` modules
make[1]: Entering directory `/usr/src/kernels/4.1.12-version.el6uek.x86_64'
  CC [M]  /root/revdev/rev_dev.o
  CC [M]  /root/revdev/rev_mod.o
  SDTSTB  /root/revdev/revdev.sdtstub.S
  AS [M]  /root/revdev/revdev.sdtstub.o
  LD [M]  /root/revdev/revdev.o
  Building modules, stage 2.
  MODPOST 1 modules
  SDTINF  /root/revdev/revdev.sdtinfo.c
  CC      /root/revdev/revdev.mod.o
  CTF
  LD [M]  /root/revdev/revdev.ko
make[1]: Leaving directory `/usr/src/kernels/4.1.12-version.el6uek.x86_64'