'ioctl' signature for device mapper - linux

The question may seem naive, but I'm new to kernel/driver programming. I created a device mapper over a block device, which is working fine. It's constructor/destructor and map methods are called.
Now, I'm trying to write an ioctl for this mapper. When ioctl is written for a device, it has the following signature:
int ioctl(int d, /* other args */);
A file structure/descriptor is expected in ioctl. This can be easily used by application process as it has access to file.
But the ioctl for device mapper has the following signature ( in struct target_type):
typedef int (*dm_ioctl_fn) (struct dm_target *ti, unsigned int cmd,
unsigned long arg);
How can user application get access to device mapper with ioctl without having knowledge of struct dm_target ?

-Ioctl which stand for Input Output control is a system call used in linux to implement system calls which are not be available in the
kernel by default.
-The major use of this is in case of handling some specific operations of a device for which the kernel does not have a system call by default. For eg: Ejecting the media from a "CD" drive. An ioctl command is implemented to give the eject system call to the cd drive.
-ioctl(fd, cmd , INPARAM or OUTPARAM);
|
3rd argument is INPARAM or OUTPARAM i.e we don't have to read a device, then how how to interact with device ? use ioctl.
-open ioctl.h and check you will get more information
#define "ioctl name" __IOX("magic number","command number","argument type")
static long char_dev_ioctl( struct file *filp, unsigned int cmd, unsigned long arg)
{
/* verify argument using access_ok() */
/* impliment support of ioctl commands */
}

Related

Writing a Sysfs module

I'm attempting to learn how to write a sysfs module, and am confused at the basic initialization. In this document looking at the kobject.h file, there are several different functions related to creating a sysfs entry.
From the looks of it, the function "kobject_init_and_add" seems like the right thing to use, which takes the following:
90 int kobject_init_and_add(struct kobject *kobj,
91 struct kobj_type *ktype, struct kobject *parent,
92 const char *fmt, ...);
struct kobject and struct kobj_type are straightforward enough, but I don't understand what the *parent kobject and *fmt cstring are supposed to be.
Further, after initializing these objects, I would need to remove them at the exit_module function, but there are two options that seem possible: kobject_del and kobject_puts. What are the differences between these?
Part of my confusion comes from the fact that while googling for the answer, I see tutorials which says to use functions like kobject_register instead, but that function doesn't actually exist.
Yes there are lot of example on mainline kernel which you can refers for your implementatin. For Your doubts I am adding the some example code"
Module Probe/init function
static struct kobject *module_kobject;
module_kobject=kobject_create_and_add("module_status",NULL);
sysfs_create_group(module_kobject,&module_attr);
Module Remove/exit function
sysfs_remove_group(module_kobject,&module_attr);
kobject_put(module_kobject);
If you want to expose more than one attribute on the user space; than you need to define the group as well
static struct attribute_group module_attr={
.attrs = module_attribute,
};
There is some more implementation and function you may need like:
static ssize_t module_show_status(struct kobject *kobj,struct kobj_attribute *attr,char *buf);
static ssize_t module_store__status(struct kobject *kobj,struct kobj_attribute *attr,const char *buf,size_t len);
I think you can start your sysfs module implementation based on the above code and Feel free for any help.
There are many kernel modules that create sysfs entries. For example,
http://lxr.free-electrons.com/source/net/bridge/br_sysfs_br.c
This module uses kobject_create_and_add(), which gets as a parameter a kobject instance, created by sysfs_create_group(). I believe that looking into such module, and trying to code step by step, following the patterns in that module, can help. Also look in
http://lxr.free-electrons.com/source/Documentation/kobject.txt
Rami Rosen

dev_err() function definition

I can see that dev_*() family of functions such as dev_err() are given as prototype in include/linux/device.h, but no where I could find its definition. I have visited sites like lxr.free-electrons, but without success. Used tags in the source code of linux kernel, even then failed.
What I am trying to find is how the dev_err(const struct device *dev, const char *fmt, ...) is able to get the device information such as pci bus, etc from just giving const struct device *dev as argument to print in logs.
Description of the device is constructed in function create_syslog_header, defined in drivers/base/core.c. The function just extracts some fields from struct device object, and emits them via snprintf() into the string.
The function dev_err is implemented via define_dev_printk_level macro in the same file (drivers/base/core.c).

Allow non-root users ioctl access to /dev/mytest file in linux module

My project contains two things: kernel module & app, that are communicating via ioctl using /dev/mytest file.
Currently, app is required to be run as root to access /dev/mytest file. Is it possible to allow non-users to iteract with this file without sudo?
As i understood, file_operations structure property .owner = THIS_MODULE has nothing about /dev/mytest file and is associated only with driver file.
I create /dev/mytest using class_create & device_create functions in kernel module. So, perhaps i should specify some special device_create parameters? Or how i can achieve it?
In a modern kernel, you can do something like
myclass = class_create(THIS_MODULE, "my_class_name");
/* error handling if class_create fails */
myclass->devnode = mydevnode;
where your devnode function is something like
static char *mydevnode(struct device *dev, umode_t *mode)
{
if (mode)
*mode = 0666; /* or whatever permissions you want */
return NULL; /* could override /dev name here too */
}
then if you use device_create to create your driver special file, the kernel will call mydevnode to create the file, and you can override the file permissions there.

Declare multiple devices in a driver module

I have to declare multiple devices inside the open call. Now is there a way I could fix the minor nos to 0,1,2,3 so that I can just extract that from filp->f_dentry->inode and put that in the array of struct scull_dev[] everytime I make an open read write or close call and then life becomes easy :P. Or is their a way to make life easier ?
If I understand what you need, you shouldn't have ever to access your devices directly except for initialization and cleanup. Take a look at:
http://www.cs.uni.edu/~diesburg/courses/dd/code/scull/pipe.c
In open function, you can get the current device you need to open via:
struct scull_pipe *dev;
dev = container_of(inode->i_cdev, struct scull_pipe, cdev);
You can see in other functions how the device is accessed via arguments that kernel is passing to these functions. For example:
static ssize_t scull_p_write(struct file *filp, const char __user *buf, size_t count,
loff_t *f_pos)
{
struct scull_pipe *dev = filp->private_data;

Why device exist in /proc/devices evethough module is unloaded

I am writing a simple charcter driver scull based on ldd. For my sample character driver, evethough module is unloaded device with major number exist in /proc/devices. How to remove that?
My module exit function has
void scull_exit(void)
{
unregister_chrdev(Major, "scull1");
cdev_del(my_cdev);
printk(KERN_ALERT "Good Bye\n");
}
I could see the old device with its major number when I load new module after unloading the same.
cdev_del takes a pointer, ensure that your my_cdev is a
pointer.
void cdev_del(struct cdev *);
It is cdev_del, first and unregister_chrdev later, it seems you
have done it the other way, use cdev_del first and then unregister_chrdev_region
You have mixed up old notation of unregister_chrdev and new notation of cdev_del.
either unregister_chrdev should be used when you use register_chrdev for registering
OR
"cdev_init/cdev_add after register_chrdev_region" should be used in conjunction with "cdev_del before unregister_chrdev_region"
struct cdev has an owner field that should be set to THIS_MODULE. Make sure it is set

Resources