I am creating a message queue with the following snippet by following The Linux Programming Interface.
if((mq_open("/my_message_queue", O_CREAT, O_RDWR, NULL)) == -1) {
perror("mq creation failed");
}
Running this snippet I get an error: "permission denied". I wanted to check and see if I had created the queue previously and not destroyed it, so I used ipcs. However, ipcs does not show any active message queues. I have never used the POSIX IPC libraries in my development environment before (Ubuntu 18.04). Is some set up I must do to allow my user process to create a message queue? Am I using the API incorrectly?
From the man page:
The oflag argument specifies flags that control the operation of the call. (Definitions of the flags values can be obtained by including <fcntl.h>.) Exactly one of the following must be specified in oflag:
O_RDONLY Open the queue to receive messages only.
O_WRONLY Open the queue to send messages only.
O_RDWR Open the queue to both send and receive messages.
You have none of those three values in your code. Or rather you do, but it's in the mode argument, not the oflag one, where the corresponding number has a completely different meaning. That third argument is the filesystem permission bits used when creating the queue (just like the third argument to open() when creating a new file), not the mode the queue is opened in.
EACCES: The queue exists, but the caller does not have permission to
open it in the specified mode.
ipcs won't show you queues that you can't read. That it doesn't show you the queue is consistent with mq_open returning a permission error.
TLPI describes mount -t mqueue to a directory of your choosing. You can then use ls(1) on that directory to see the queues, and even interrogate the queues' states by reading the "files" in that directory.
My guess is the queue exists and belongs to root....
POSIX states :
... The name argument conforms to the construction rules for a pathname, except that the interpretation of <slash> characters other than the leading <slash> character in name is implementation-defined ...
On Linux, the name /my/message_queue is incorrect. Linux requires the name to start with /, but it can contain no other / characters.
Per the Linux mq_overview.7 man page:
Message queues are created and opened using mq_open(3); this function
returns a message queue descriptor (mqd_t), which is used to refer to
the open message queue in later calls. Each message queue is
identified by a name of the form /somename; that is, a null-
terminated string of up to NAME_MAX (i.e., 255) characters consisting
of an initial slash, followed by one or more characters, none of
which are slashes.
Related
I've got several USB to 422 adapters in my test system. I've used FTProg to give each adapter a specific name: Sensor1, Sensor2, etc. They will all be plugged in at power on. I don't want to hard code each adapter to a specific ttyUSBx. I want the drivers to figure out which tty it needs to use. I'm developing in C for a linux system. My first thought was to something like this in my startup code.
system("dmesg | find_usb.py");
The python script would find the devices since each one has a unique Product Description. Then using the usb tree to associate each device with its ttyUSBx. The script would then create /tmp/USBDevs which would just be a simple device:tty pairing that would be easy for the C code to search.
I've been told...DoN't UsE sYsTeM...use posix_spawn(). But I'm having problems getting the output of dmesg piped to my python script. This isn't working
char *my_args[] = {"dmesg", "|", "find_usb.py", NULL};
pid_t pid;
int status;
status = posix_spawn(&pid, "/bin/dmesg", NULL, NULL, my_args, NULL);
if(status == 0){
if(waitpid(pid, &status, 0) != -1);{
printf("posix_spawn exited: %i", status);
}
I've been trying to figure out how to do this with posix_spawn_file_actions(), but I'm not allowed to hit the peak of the 'Ballmer Curve' at work.
Thanks in advance
Instead of using /dev/ttyUSB* devices, write udev rules to generate named symlinks to the devices. For a brief how-to, see here. Basically, you'll have an udev rule for each device, ending with say SYMLINK+=Sensor-name, and in your program, use /dev/Sensor-name for each sensor. (I do recommend using Sensor- prefix, noting the initial Capital letter, as all device names are currently lowercase. This avoids any clashes with existing devices.)
These symlinks will then only exist when the matching device is plugged in, and will point to the correct device (/dev/ttyUSB* in this case). When the device is removed, udev automagically deletes the symlink also. Just make sure your udev rule identifies the device precisely (not just vendor:device, but serial number also). I'd expect the rule to look something like
SUBSYSTEM=="tty", ATTRS{idVendor}=="VVVV", ATTRS{idProduct}=="PPPP", ATTRS{serial}=="SSSSSSSS", SYMLINK+="Sensor-name"
where VVVV is the USB Vendor ID (four hexadecimal digits), PPPP is the USB Product ID (four hexadecimal digits), and SSSSSSSS is the serial number string. You can see these values using e.g. udevadm info -a -n /dev/ttyUSB* when the device is plugged in.
If you still insist on parsing dmesg output, using your own script is a good idea.
You could use FILE *handle = popen("dmesg | find_usb.py", "r"); and read from handle like it was a file. When complete, close the handle using int exitstatus = pclose(handle);. See man popen and man pclose for the details, and man 2 wait for the WIFEXITED(), WEXITSTATUS(), WIFSIGNALED(), WTERMSIG() macros you'll need to use to examine exitstatus (although in your case, I suppose you can just ignore any errors).
If you do want to use posix_spawn() (or roughly equivalently, fork() and execvp()), you'd need to set up at least one pipe (to read the output of the spawned command) – two if you spawn/fork+exec both dmesg and your Python script –, and that gets a bit more complicated. See man pipe for details on that. Personally, I would rewrite the Python script so that it executes dmesg itself internally, and only outputs the device name(s). With posix_spawn(), you'd init a posix_file_actions_t, with three actions: _adddup2() to duplicate the write end of the pipe to STDOUT_FILENO, and two _addclose()s to close both ends of the pipe. However, I myself prefer to use fork() and exec() instead, somewhat similar to the example by Glärbo in this answer.
I'm writing a small c program to make tape status and seek requests via
ioctl(int fd, long int request, &io_buf)
but after trial and plenty of error, ioctl is returning -1 with the errno message "Invalid Argument"
I'm on Linux and running my program as sudo. The device I want to issue requests to is an optical drive, connected via SCSI. I've tried tape status and seek requests by passing requests (MTIOCGET or MTIOCTOP, respectively) to ioctl.
Code snippet for tape status function where fd is the file descriptor of the device returned by open() and mtgetbuf is an instance of the mtget struct from sys/mtio.h
stat = ioctl(fd, MTIOCGET, &mtgetbuf);
if (stat == -1)
{
perror("error on ioctl MTIOCGET request: ")
return EXIT_FAILURE;
}
Similar code snippet for seek tape function except mtopbuf is an instance of the mtop structure and MTSEEK is the defined op code for the seek operation, also in sys/mtio.h
mtopbuf.mt_op = MTSEEK;
stat = ioctl(fd, MTIOCTOP, &mtopbuf);
if (stat == -1)
{
perror("error on ioctl MTIOCGET request: ")
return EXIT_FAILURE;
}
Instead of invalid argument error messages and a return of -1, I would have expected a successful return from ioctl and the respective structure instances, mtgetbuf and mtopbuf, to have their members populated with data provided by the device.
I.e. A successful ioctl() command with the MTIOCGET request would return into the mtgetbuf mt_type member a value of either MT_ISSCSI1, MT_ISSCSI2, or MT_ISUNKNOWN (I don't believe it is any of the other defined values for other vendor-specific devices).
Note: I'm aware of the linux/mtio.h header file and I have tried including that in place of sys/mtio.h but the outcome is the same.
I've recently had success issuing requests to a block device using the SCSI Generic Linux driver (SG). There are three header files (below) that have provided op codes, structures used to pass and retrieve data from the device, among other information.
SCSI SG Header files:
/usr/include/scsi/scsi.h
/usr/include/scsi/scsi_ioctl.h
/usr/include/scsi/sg.h
A combination of online resources were instrumental in understanding how to package, send, and receive requests:
1) The TLDP SCSI Generic (sg) HOW-TO guide is a font of information on communicating to SCSI devices via the SG driver. A link to it is provided here. It explains in detail various commands that can be issued, how to package the commands by creating an instance of the sg_io_hdr_t structure, as well as a programming example to send a SCSI INQUIRY command which returns basic vendor information of the device. There are also status and sense codes for error handling and understanding unsuccessful SCSI requests.
2) Seagate's SCSI Command Reference Manual was helpful at times to understand the structure of bytes/bits in a SCSI command. Typically the op code occupied the first byte and the remaining bytes were zeros. The op codes in this reference manual were defined between those three header files mentioned above.
I have been able to send successful INQUIRY and GET_SG_VERSION_NUMBER requests and most likely have been able to send SEEK(6), READ_CAPACITY(10), and REZERO_UNIT commands. I say most likely because -1/errno values are not being returned and no information is being passed back into the sense buffer which is an indication of warnings/errors (either SCSI, host adapter, or driver status codes).
Hope this answers OPs question.
I would like to know the mechanism in which the Linux Kernel knows which file descriptor (e.g. /dev/input/eventX) to write the input to. For example, I know that when the user clicks the mouse, an interrupt occurs, which gets handled by the driver and propagated to the Linux input core via input_event (drivers/input/input.c), which eventually gets written to the appropriate file in /dev/input/. Specifically, I want to know which source files I need to go through to see how the kernel knows which file to write to based on the information given about the input event. My goal is to see if I can determine the file descriptors corresponding to specific input event codes before the kernel writes them to the /dev/input/eventX character files.
You may go through two files:
drivers/input/input.c
drivers/input/evdev.c
In evdev.c, evdev_init() will call input_register_handler() to initialize input_handler_list.
Then in an input device driver, after initialize input_dev, it will call:
input_register_device(input_dev)
-> get device kobj path, like /devices/soc/78ba000.i2c/i2c-6/6-0038/input/input2
-> input_attach_handler()
-> handler->connect(handler, dev, id);
-> evdev_connect()
In evdev_connect(), it will do below:
1. dynamic allocate a minor for a new evdev.
2. dev_set_name(&evdev->dev, "event%d", dev_no);
3. call input_register_handle() to connect input_dev and evdev->handle.
4. create a cdev, and call device_add().
After this, you will find input node /dev/input/eventX, X is value of dev_no.
I will give a detailed exp of the program and lead to the issue regarding the use of netlink socket communication.
The last paragraph asks the actual question I need an answer for, so you might wanna start by peeking it first.
Disclaimer before I start:
- I have made an earlier search before asking here and did not find complete solution / alternative to my issue.
- I know how to initialize a module and insert it to kernel.
- I know to handle communication between module and user-space without using netlink sockets. Meaning using struct file_operations func pointers assignments to later be invoked by the module program whenever a user attempts to read/write etc. and answer to the user using copy_to_user / copy_from_user.
- This topic refers to Linux OS, Mint 17 dist.
- Language is C
Okay, so I am building a system with 3 components:
1. user.c : user application (user types commands here)
2. storage.c : storage device ('virtual' disk-on-key)
3. device.ko : kernel module (used as proxy between 1. and 2.)
The purpose of this system is to be able (as a user) to:
- Copy files to the virtual disk-on-key device (2) - like an "upload" from local directory that belongs to the user.
- Save files from the virtual device on local directory - like "download" from the device storage to the user directory.
Design:
Assuming programs (1),(2) are compiled and running + (3) has successfully inserted using the bash command ' sudo insmod device.ko ' , the following should work like this (simulation ofc):
Step 1 (in user.c) -> user types 'download file.txt'
Step 2 (in device.ko) -> the device recognizes the user have tried to 'write' to it (actually user just passing the string "download file.txt") and invokes the 'write' implementation of the method we set on struct file_operation earlier on module_init().
The device (kernel module) now passes the data (string with a command) to the storage.c application, expecting an answer to later be retrieved to the user.c application.
Step 3 (in storage.c) -> now, lets say this program performs a busy-wait loop of 'readmsg()' and that's how a request from module event is triggered and recognized, the storage device now recognizes that the module has sent a request (string with a command \ data). Now, the storage programs shall perform an implementation of some function 'X' to send the data requested using sendmsg() somewhere inside the function.
Now, here comes the issue.
Usually, on all of the examples I've looked on web, the communication between the kernel-module and a user-space (or the storage.c program in our case) using netlink is triggered by the user-space and not vice versa. Meaning that the sendmsg() function from the user-space invokes the 'request(struct sk_buff *skb)' method (which is set on the module_init() part as following:
struct netlink_kernel_cfg cfg = {
.input = request // when storage.c sends something, it invokes the request function
};
so when the storage.c performs something like:
sendmsg(sock_fd,&msg,0); // send a msg to the module
the module invokes and runs the:
static void request(struct sk_buff *skb) {
char *msg ="Hello from kernel";
msg_size=strlen(msg);
netlink_holder=(struct nlmsghdr*)skb->data;
printk(KERN_INFO "Netlink received msg payload:%s\n",(char*)nlmsg_data(netlink_holder));
pid = netlink_holder->nlmsg_pid; // pid of sending process
skb_out = nlmsg_new(msg_size,0);
if(!skb_out){
printk(KERN_ERR "Failed to allocate new skb\n");
return;
}
netlink_holder=nlmsg_put(skb_out,0,0,NLMSG_DONE,msg_size,0); // add a new netlink message to an skb. more info: http://elixir.free-electrons.com/linux/v3.2/source/include/net/netlink.h#L491
NETLINK_CB(skb_out).dst_group = 0; // not in multicast group
strncpy(nlmsg_data(netlink_holder),msg,msg_size); // assign data as char* (variable msg)
result=nlmsg_unicast(sock_netlink,skb_out,pid); // send data to storage. more info: http://elixir.free-electrons.com/linux/latest/source/include/net/netlink.h#L598
if(result<0)
printk(KERN_INFO "Error while sending bak to user\n");
}
and from all that big chunk, the only thing that im interesting in is actually doing this:
result=nlmsg_unicast(sock_netlink,skb_out,pid); // send data to storage.
BUT I can't use nlmsg_unicast() without having the strcut sk_buff* which is provided automatically for me whenever there's an invoke from storage.c !
To sum up everything:
How do I send a msg from the device.ko (kernel module) to the user-space withtout having to wait for request to invoke / rely on the provided strcut sk_buff parameter from the earlier shown 'request()' method ?
Hope this sums up the point.
Thanks.
The only question here is that you need the user-space program connected to kernel-space first to get the pid of your user-program.
After get the pid, you can manually construct the skb_out and send it out through netlink_unicast or nlmsg_unicast.
The pid is always needed, you can set it as static and let your user-space program connect to your device.ko to make a long-maintained link.
Although this question is asked at 2017, I believe OP has already found the answer :D
So I am supposed to achieve following behavior.
This project you are asked to add a new field to the task descriptor. The name and type of the field is: int casper;
If casper=0 : The process is visible to all, i.e. it is listed in the /proc file system and it can be seen using “ps”, “pstree”, “top”, ...
If casper=1 : The process is visible only to processes which have the same user id, i.e. for all other processes, it is NOT listed in the /proc file system and it can NOT be seen using “ps”, “pstree”, “top”, ...
If casper=2 : The process is visible only to processes which are in the same group, i.e. for all other processes, it is NOT listed in the /proc file system and it can NOT be seen using “ps”, “pstree”, “top”, ...
If casper=3 : The process is invisible for all, i.e. it is NOT listed in the /proc file system and it can NOT be seen using “ps”, “pstree”, “top”, ...
I have already modified task_struct definition and its default value for init process and added necessary stuff to fork sys call
I did some research but couldnt find an obvious way to do this. So I assumed that /proc is created per request so I can get the task_struct of the process that requested it and populate the /proc according to that. Am I on the right track?
Yes, it's. /proc is a vritual filesystem generated by the kernel upon request. Check the following article for more details: Linux VFS