About IOCTL system call - linux

The prototype of IOCTL system call in linux is
int ioctl(struct inode *, struct file *, unsigned int, unsigned long);
All other file operations like read(),write(),llseek(),mmap() etc.. have only struct file * as argument. But, why IOCTL call needs struct inode * to be passed.
Is there any specific use of it?

Which kernel version you are taking about, now ioctl doesn't has the inode pointer as its parameter. Previously there used to be, but I think from 2.6.36 kernel onwards it has been removed.

The prototype of ioctl is, at least according to the manpage, int ioctl(int d, int request, ...);. The ... bit is important - variadic arguments, meaning the remaining arguments depend on the first ones, much like printf. Any use for a struct inode * would stem from the specific ioctl request you're making.

Related

Getting ENOTTY on ioctl for a Linux Kernel Module

I have the following chardev defined:
.h
#define MAJOR_NUM 245
#define MINOR_NUM 0
#define IOCTL_MY_DEV1 _IOW(MAJOR_NUM, 0, unsigned long)
#define IOCTL_MY_DEV2 _IOW(MAJOR_NUM, 1, unsigned long)
#define IOCTL_MY_DEV3 _IOW(MAJOR_NUM, 2, unsigned long)
module .c
static long device_ioctl(
struct file* file,
unsigned int ioctl_num,
unsigned long ioctl_param)
{
...
}
static int device_open(struct inode* inode, struct file* file)
{
...
}
static int device_release(struct inode* inode, struct file* file)
{
...
}
struct file_operations Fops = {
.open=device_open,
.unlocked_ioctl= device_ioctl,
.release=device_release
};
static int __init my_dev_init(void)
{
register_chrdev(MAJOR_NUM, "MY_DEV", &Fops);
...
}
module_init(my_dev_init);
My user code
ioctl(fd, IOCTL_MY_DEV1, 1);
Always fails with same error: ENOTTY
Inappropriate ioctl for device
I've seen similar questions:
i.e
Linux kernel module - IOCTL usage returns ENOTTY
Linux Kernel Module/IOCTL: inappropriate ioctl for device
But their solutions didn't work for me
ENOTTY is issued by the kernel when your device driver has not registered a ioctl function to be called. I'm afraid your function is not well registered, probably because you have registered it in the .unlocked_ioctl field of the struct file_operations structure.
Probably you'll get a different result if you register it in the locked version of the function. The most probable cause is that the inode is locked for the ioctl call (as it should be, to avoid race conditions with simultaneous read or write operations to the same device)
Sorry, I have no access to the linux source tree for the proper name of the field to use, but for sure you'll be able to find it yourself.
NOTE
I observe that you have used macro _IOW, using the major number as the unique identifier. This is probably not what you want. First parameter for _IOW tries to ensure that ioctl calls get unique identifiers. There's no general way to acquire such identifiers, as this is an interface contract you create between application code and kernel code. So using the major number is bad practice, for two reasons:
Several devices (in linux, at least) can share the same major number (minor allocation in linux kernel allows this) making it possible for a clash between devices' ioctls.
In case you change the major number (you configure a kernel where that number is already allocated) you have to recompile all your user level software to cope with the new device ioctl ids (all of them change if you do this)
_IOW is a macro built a long time ago (long ago from the birth of linux kernel) that tried to solve this problem, by allowing you to select a different character for each driver (but not dependant of other kernel parameters, for the reasons pointed above) for a device having ioctl calls not clashing with another device driver's. The probability of such a clash is low, but when it happens you can lead to an incorrect machine state (you have issued a valid, working ioctl call to the wrong device)
Ancient unix (and early linux) kernels used different chars to build these calls, so, for example, tty driver used 'T' as parameter for the _IO* macros, scsi disks used 'S', etc.
I suggest you to select a random number (not appearing elsewhere in the linux kernel listings) and then use it in all your devices (probably there will be less drivers you write than drivers in the kernel) and select a different ioctl id for each ioctl call. Maintaining a local ioctl file with the registered ioctls this way is far better than trying to guess a value that works always.
Also, a look at the definition of the _IO* macros should be very illustrative :)

What is the precise definition of the structure passed to the STAT system call?

Where can I find the precise definition of the structure that the STAT family of system calls expects?
Note that I'm referring to the raw system calls one would call in assembly, (System calls number 4, 5, and 6 on x86_64), and not the wrappers that are normally provided by libc.
The man page, stat(2), and what I could manage dig out of both the linux and glibc source code gave confusing and contradicting results (different structure field ordering, Extra fields, padding).
I'm certain that I'm at fault for not looking where I should, but I can't seem to find the information I'm after. Which led me to post this question.
Clarification: What I seek is the exact definition of the stat structure as returned by the system call on any given architecture. I am aware that I can determine this information experimentally. Experimentation is limited to my specific architecture. Furthermore, I expect something as crucial as a data structure used in Linux's ABI to be documented somewhere. I want to know where.
The question here does not have the information requested in this post. Please unmark this post as a duplicate.
struct stat definition strictly depends on your architecture. E.g. for x86_64 you can find it in arch/x86/include/uapi/asm/stat.h.
In user-space you can find the same structure in /usr/include/asm/stat.h file.
Here is the definition for x86_64:
struct stat {
__kernel_ulong_t st_dev;
__kernel_ulong_t st_ino;
__kernel_ulong_t st_nlink;
unsigned int st_mode;
unsigned int st_uid;
unsigned int st_gid;
unsigned int __pad0;
__kernel_ulong_t st_rdev;
__kernel_long_t st_size;
__kernel_long_t st_blksize;
__kernel_long_t st_blocks; /* Number 512-byte blocks allocated. */
__kernel_ulong_t st_atime;
__kernel_ulong_t st_atime_nsec;
__kernel_ulong_t st_mtime;
__kernel_ulong_t st_mtime_nsec;
__kernel_ulong_t st_ctime;
__kernel_ulong_t st_ctime_nsec;
__kernel_long_t __unused[3];
};

How to read VFS attributes in Linux

I have some question.
I try to read some VFS attributes, for example s_magic value in struct super_block.
but I cant read s_magic.
This is my code.
#include<stdio.h>
#include<fcntl.h>
#include<unistd.h>
#include<linux/fs.h>
int main()
{
int fd;
char boot[1024];
struct super_block sb;
fd = open("/dev/fd", O_RDONLY);
read(fd, boot, 1024);
read(fd, &sb, sizeof(struct super_block);
printf("%x\n", sb.s_magic);
close(fd);
return 0;
}
so, This code does't work with some error.
In this error, storage size of ‘sb’ isn’t known and invalid application of ‘sizeof’ to incomplete type ‘struct super_block’
Thank you.
That's because your linux/fs.h does not contain super_block declaration. That's because you want to include linux/fs.h from Linux kernel but actually include linux/fs.h from Linux userspace. Supply -I <include path> option to gcc like this
gcc -I /usr/src/kernels/$(uname -r)/include
BUT!
You will get a million of errors because you can't just include kernel headers in your userspace program - you don't have all type and struct definitions.
The kernel headers are not written with user space in mind, and they
can change at any time. The proper way for user-space applications to
interface with the kernel is by way of the C library, which provides
its own structures and, when necessary, translates them into whatever
the current kernel expects. This separation helps to keep user-space
programs from breaking when the kernel changes.
(source http://lwn.net/Articles/113349/)
So you have to revise your code.
P.S. I've given you and explanation why your code is not working, but I don't know how you can read super_block in userspace. You better ask another question regarding filesystem superblock API.

Linux: Difference between inode and file_inode(file)?

in source/arch/x86/kernel/msr.c, the msr_open callback for the character device uses the following construct to extract the minor number of the character device file used:
static int msr_open(struct inode *inode, struct file *file)
{
unsigned int cpu = iminor(file_inode(file));
[...]
}
My question is:
Why not directly call iminor with the first argument of the function, like:
unsigned int cpu = iminor(inode);
The construct is used in other callbacks (e.g. read and write) as well,, where the inode is not passed as an argument, so I guess this is due to copy/paste, or is there a deeper meaning to it?
An inode is a data structure on a traditional Unix-style file system such as UFS or ext3. An inode stores basic information about a regular file, directory, or other file system object.
- http://www.cyberciti.biz/tips/understanding-unixlinux-filesystem-inodes.html
Same deal.

copy_to_user and copy_from_user with structs

I have a simple question: when i have to copy a structure's content from userspace to kernel space for example with an ioctl call (or viceversa) (for simplicity code hasn't error check):
typedef struct my_struct{
int a;
char b;
} my_struct;
Userspace:
my_struct s;
s.a = 11;
s.b = 'X';
ioctl(fd, MY_CMD, &s);
Kernelspace:
int my_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
...
my_struct ks;
copy_from_user(&ks, (void __user *)arg, sizeof(ks));
...
}
i think that size of structure in userspace (variable s) and kernel space (variable ks) could be not the same (without specify the __attribute__((packed))). So is a right thing specifing the number of byte in copy_from_user with sizeof macro? I see that in kernel sources there are some structures that are not declared as packed so, how is ensured the fact that the size will be the same in userspace and kernelspace?
Thank you all!
Why should the layout of a struct be different in kernel space from user space? There is no reason for the compiler to layout data differently.
The exception is if userspace is a 32bit program running on a 64bit kernel. See http://www.x86-64.org/pipermail/discuss/2002-June/002614.html for a tutorial how to deal with this.
The userspace structure should come from kernel header, so struct definition should be the same in user and kernel space. Do you have any real example ?
Of course, if you play with different packing options on two side of an ABI, whatever it is, you are in trouble. The problem here is not sizeof.
If your question is : does packing options affect binary interface, the answer is yes.
If your question is, how can I solve a packing mismatch, please provide more information

Resources