LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Software > Linux - Kernel
User Name
Password
Linux - Kernel This forum is for all discussion relating to the Linux kernel.

Notices


Reply
  Search this Thread
Old 05-04-2023, 11:15 PM   #1
devsp
LQ Newbie
 
Registered: May 2023
Posts: 3

Rep: Reputation: 0
Linux Kernel Dev - Getting 'Invalid argument' error when using IOCTL


We have created a block driver which traces the IO operations happening on a particular block device say /dev/sdb or /dev/sdc.
It's working, so now I am trying to develop a user space application that will interact with driver (add or remove block device from userspace).
I have created a skeleton and underlying program but facing an error 'invalid argument'.

My userspace program is like this:

char path[SIZE];
printf( "Enter the path of the block device to add or remove: ");
fgets(path, SIZE, stdin);
path[strcspn(path, "\n")] = '\0';

int fd = open( path, O_RDWR );

if( fd < 0 )
{
perror( "Failed to open device" );
exit( EXIT_FAILURE );
}

while( 1 )
{
int input;

printf( "Enter a number [ 0 for add and 1 for remove ]: " );
scanf( "%d", &input );

switch( input )
{
case 0:
if( ioctl( fd, MY_BLOCK_DEVICE_ADD, &path ) < 0 )
{
perror( "Failed to add device" );
exit( EXIT_FAILURE );
}
break;

case 1:
if( ioctl( fd, MY_BLOCK_DEVICE_REMOVE, &path ) < 0 )
{
perror( "Failed to remove device" );
exit( EXIT_FAILURE );
}

break;

case 2:
close(fd);
return 0;
}
}

in '.h' file I have defined custom IOCTL commands -

#define MY_BLOCK_DEVICE_ADD _IOWR('M', 1, char*)
#define MY_BLOCK_DEVICE_REMOVE _IOWR('M', 2, char*)

in driver/module code -

static int device_ioctl( struct block_device *dev, fmode_t mode, unsigned int cmd, unsigned long arg )
{
printk(KERN_INFO "in ioctl\n");
int ret;
char path[SIZE];
switch( cmd )
{
case MY_BLOCK_DEVICE_ADD:
if( copy_from_user( path, (char *)arg, SIZE ) )
{
return -EFAULT;
}

path[strcspn(path, "\n")] = '\0';

register_block_device(path);

printk( KERN_INFO "Device added\n" );
break;

case MY_BLOCK_DEVICE_REMOVE:
if( copy_from_user( path, (char *)arg, SIZE ) )
{
return -EFAULT;
}

unregister_block_device();
printk( KERN_INFO "Device removed\n" );
break;

default:
return -ENOTTY;
}
return 0;
}

Proposed working - We pass IOCTL commands from userspace add/remove device. So, for add ioctl device will be registered with my block driver which will start tracking the changes for ex. /dev/sdb and remove will stop the tracking.
So, do you know how can I solve this error? or if there is better approach plz feel free to give your valuable suggestions.

Last edited by devsp; 05-08-2023 at 04:51 AM.
 
Old 05-05-2023, 08:09 AM   #2
smallpond
Senior Member
 
Registered: Feb 2011
Location: Massachusetts, USA
Distribution: Fedora
Posts: 4,153

Rep: Reputation: 1265Reputation: 1265Reputation: 1265Reputation: 1265Reputation: 1265Reputation: 1265Reputation: 1265Reputation: 1265Reputation: 1265
It would help if you edited your question and used code tags so it is properly formatted and readable. What code is giving the 'Invalid argument' error?
 
Old 05-08-2023, 04:53 AM   #3
devsp
LQ Newbie
 
Registered: May 2023
Posts: 3

Original Poster
Rep: Reputation: 0
Thanks @smallpond. I have edited my question, now code is in red color lines.
And my userspace program is giving 'invalid argument' error.
 
Old 05-08-2023, 12:38 PM   #4
smallpond
Senior Member
 
Registered: Feb 2011
Location: Massachusetts, USA
Distribution: Fedora
Posts: 4,153

Rep: Reputation: 1265Reputation: 1265Reputation: 1265Reputation: 1265Reputation: 1265Reputation: 1265Reputation: 1265Reputation: 1265Reputation: 1265
If you enter "/dev/sdb", you are opening "/dev/sdb" and sending it an ioctl request that it does not understand. It returns EINVAL, because it has no idea what MY_BLOCK_DEVICE_* means. You must pass the path and the request to your own driver, not to /dev/sdb.
 
1 members found this post helpful.
Old 05-30-2023, 09:42 AM   #5
devsp
LQ Newbie
 
Registered: May 2023
Posts: 3

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by smallpond View Post
If you enter "/dev/sdb", you are opening "/dev/sdb" and sending it an ioctl request that it does not understand. It returns EINVAL, because it has no idea what MY_BLOCK_DEVICE_* means. You must pass the path and the request to your own driver, not to /dev/sdb.
Thanks, you were right. I corrected my code and now it is working.
 
  


Reply

Tags
block device, driver, ioctl, kernel



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
message sending failed : Error[22 ] invalid argument .....but each and every argument rakeshranjanjha Linux - Software 2 01-07-2008 11:22 PM
trying to use losetup, ioctl tells me argument is invalid Ephracis Linux - Software 3 03-26-2005 10:11 AM
ioctl FBIOPAN_DISPLAY: Invalid Argument Andry Linux - Hardware 2 12-27-2004 10:55 PM
ioctl FBIOPUT_VSCREENINFO: Invalid argument. vaworx Linux - General 4 12-20-2004 03:00 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - Software > Linux - Kernel

All times are GMT -5. The time now is 02:22 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration