For a homework assignment, I have to modify the linux kernel.
I am working on a virtual machine, and I added a system call to the kernel, which I called get_unique_id. Here is the code for get_unique_id.c :
#include <linux/linkage.h>
#include <asm/uaccess.h>
asmlinkage long sys_get_unique_id(int * uuid)
{
// static because we want its state to persist between calls
static int uid = 0;
++uid;
// assign new uid value to user-provided mem location
// returns non-zero if success or -EFAULT otherwise
int ret = put_user(uid, uuid);
return ret;
}
I also added this line to syscalls.h :
asmlinkage long sys_get_unique_id(int * uuid);
This line to syscall_32.tbl :
383 i386 get_unique_id sys_get_unique_id
And finally this line to syscall_64.tbl :
548 common get_unique_id sys_get_unique_id
After recompiling and reloading the kernel, I wrote a little C program to test my system call, here is the code for the C test file :
// get_unique_id_test.c
#include <stdio.h>
#include <limits.h>
#include "syscalls_test.h"
int main(void)
{
// initialize the ints we want
int id1;
int id2;
// check the id's are unique and that no error occured
for (int i = INT_MIN; i < INT_MAX - 1; i += 2) {
long ret1 = get_unique_id(&id1);
long ret2 = get_unique_id(&id2);
if (ret1 != 0)
printf("ERROR: get_unique_id returned: %ld\n", ret1);
if (ret2 != 0)
printf("ERROR: get_unique_id returned: %ld\n", ret2);
if (id2 != id1 + 1)
printf("ERROR: successive id's did not increment properly: id1 = %d, id2 = %d\n", id1, id2);
}
return 0;
}
And its header file :
// syscalls_test.h
#include <errno.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>
#define __NR_get_unique_id 383
inline long get_unique_id(int * uuid)
{
return syscall(__NR_get_unique_id, uuid) ? errno : 0;
}
Unfortunately, while trying to compile the C test file with the following command : gcc -std=c99 get_unique_id_test.c -o get_unique_id_test, I get the following error :
In file included from get_unique_id_test.c:4:0:
syscalls_test.h: In function ‘get_unique_id’:
syscalls_test.h:10:5: warning: implicit declaration of function ‘syscall’ [-Wimplicit-function-declaration]
return syscall(__NR_get_unique_id, uuid) ? errno : 0;
^
syscalls_test.h: In function ‘get_unique_id’:
syscalls_test.h:10:5: warning: implicit declaration of function ‘syscall’ [-Wimplicit-function-declaration]
return syscall(__NR_get_unique_id, uuid) ? errno : 0;
^
/tmp/cc1euZ3r.o: In function `main':
get_unique_id_test.c:(.text+0x22): undefined reference to `get_unique_id'
get_unique_id_test.c:(.text+0x34): undefined reference to `get_unique_id'
collect2: error: ld returned 1 exit status
It appears gcc cannot find the function get_unique_id(int * uuid), which is declared in syscalls_test.h, and the syscall function, which should be declared, I believe, in syscall.h, right ?
I don't understand why this happens. Does anybody have an idea ?
EDIT : my problems were solved using a3f's solution (see below) PLUS moving the #include "syscalls_test.h" at the very top of the file, as he said in the comments. Thank you very much.
#define _GNU_SOURCEto the top of yoursyscalls_test.hsys_get_unique_idis not thread-safe; multiple threads could call it simultaneously and get the same value. You could fix this withatomic_t.