blino's website

Free software developer and more

I've been recently playing a bit with VirtualBox to debug my One live systems, and got a bit involved in VirtualBox packaging in the meantime. Our Mandriva package was missing the guest additions, so I added them recently (the packages are x11-driver-input-vboxmouse, x11-driver-video-vboxvideo, dkms-vboxadd, dkms-vboxvfs and virtualbox-guest-additions). They basically allow a better integration of mouse and X11 (clipboard) with the host, and to share files more easily, thanks to a vboxvfs module and a vboxfs mount helper.

But the vboxadd kernel module required some integration, since /dev/vboxadd was not created automatically. Upstream has an initscript to create it, but it's quite a weird trick to parse /proc/devices to get the major and create the device "a la main" with mknod.

A better solution is to make the kernel module send an uevent (with kobject_uevent()) when the device is registered in the kernel module, so that udev creates the device node automatically.

This can be done through the device_create() function (from drivers/base/core.c), but it requires a kernel class as argument, and we don't necessarily need to create one for vboxadd.

A simpler solution is to replace the original char device creation, register_chrdev() (from fs/char_dev.c), by using a misc character device. misc_register() (from drivers/char/misc.c) takes care of the character device registration and of sending the uevent to userspace.

#include <linux/miscdevice.h>

...

static struct miscdevice vbox_dev =
{
    .minor      = MISC_DYNAMIC_MINOR,
    .name       = "vboxadd",
    .fops       = &vbox_fops,
};

...

    if (vbox_major > 0) {
        err = register_chrdev(vbox_major, "vboxadd", &vbox_fops);
    } else {
        err = misc_register(&vbox_dev);
    }

...

    if (vbox_major > 0) {
        unregister_chrdev(vbox_major, "vboxadd");
    } else {
        misc_deregister(&vbox_dev);
    }

The final touch is to make the device node reachable by end-users, which is made easy since Mandriva uses pam_console. pam_console_apply is called for every device node created by udev, so we just need to add a rule to make vboxadd devices owned by the console user (i.e. the user physically logged on the system).

$ cat /etc/security/console.perms.d/60-vboxadd.perms
<vboxadd>=/dev/vboxadd*
<console> 0600 <vboxadd> 0600 root


Latest 2.6.16-2mdk Mandriva kernel has supermount disabled, my patch in bug #23217 will hopefully allow us to have a quick fix.



blosxom Optimised for standards.
Olivier Blin (2005)