11

I've recently inherited some code at work, this is old 2.4.X linux kernel drivers and I've been tasked with getting them working on a newer kernel 2.6 or greater. I'm running on OpenSUSE 12.1 with a 3.1.10 kernel.

I've updated the original code from register_chrdev() to use class_create()/device_create() calls and I can see my devices show up in /dev correctly. My current issue is that the permissions for my device are being set to r/w for user only:

crw-------  1 root root    244,   0 Aug  7 07:57 gcanain

I know I can "chmod" the file via command line, and or I can set up udev permissions... but is there anyway to do this programmatically, such that when I issue the insmod command, the dev will be mounted with the correct rules in place already?

Are there any APIs that might exist that I can call to do this, any options I'm missing in one of these creation APIs?

Just to clarify, part of the reason I don't want to use udev rules is that I don't know the names of the device drivers ahead of time. The device drivers are spawned in a loop and so the names are appended with a digit, nNumDevs can be pretty much anything:

for (i = 0; i < nNumDevs; i++) {
  strcpy(Modname,GC_ANAIN_MODULE_NAME);
  strcat(Modname,"%d");
  device_create(c1, NULL, MKDEV(nMajor, GC_ANAIN_MINOR_VERSION+i), NULL, Modname, i);
}
Mike
  • 47,263
  • 29
  • 113
  • 177
  • 1
    I think that you should just go ahead and use `udev`. Device permissions are typically the pervue of the local administrator, who may have different ideas about access than the device driver author. You could drop default settings in `/etc/udev/rules.d` or something. – larsks Aug 07 '12 at 13:07
  • Understood, but we (my group) are the admin of the system, so if I wanted everything to have 777, I could do so. Also, I have an issue with using rules.d (updated in the original description), since the names of the device drivers are dynamically created... unless I misunderstand how to use udev. – Mike Aug 07 '12 at 13:32
  • 2
    @Mike: But udev rules can use wildcars to match the name of the devices (`KERNEL=="foo*"`) and they can also match the name of the driver (`DRIVERS=="bar"`). – rodrigo Aug 07 '12 at 14:26
  • @Mike have you solved this problem? i need to do the same for android kernel? – Jeegar Patel Jul 22 '13 at 12:25
  • Could you accept the answer? – Alexis Mar 13 '20 at 05:56

3 Answers3

14

This is the method used by the TTY driver to set permission to 0666 on creation:

static char *tty_devnode(struct device *dev, umode_t *mode)
{
        if (!mode)
                return NULL;
        if (dev->devt == MKDEV(TTYAUX_MAJOR, 0) ||
            dev->devt == MKDEV(TTYAUX_MAJOR, 2))
                *mode = 0666;
        return NULL;
}

static int __init tty_class_init(void)
{
        tty_class = class_create(THIS_MODULE, "tty");
        if (IS_ERR(tty_class))
                return PTR_ERR(tty_class);
        tty_class->devnode = tty_devnode;
        return 0;
}

The devnode attribute in struct class has a parameter pointer mode that will allow you to set permissions.

Beware, mode may be NULL when the device gets destroyed.

Cimbali
  • 11,012
  • 1
  • 39
  • 68
vincent
  • 141
  • 1
  • 2
  • What do we need to be careful? If the device gets destroyed, we don't care about it anymore, right? – Alexis Mar 13 '20 at 05:57
4

Try this: #include <sys/stat.h>

int chmod(const char *path, mode_t mode); OR int fchmod(int fd, mode_t mode);

Source: man -s 2 chmod

askmish
  • 6,464
  • 23
  • 42
1

udev has rules for permissions, you need to create them under /etc/udev/rules.d

First try this:

In the file /etc/udev/udev.conf, add this line:

# My default permissions
default_mode="0660"

If this doesn't work add a rule in /etc/udev/rules.d, more on that here : http://www.reactivated.net/writing_udev_rules.html

TOC
  • 4,326
  • 18
  • 21