I know this is strongly not recommended. But does is possible to do this in kernel space.
Given the file path, can we remove the corresponding file in kernel space?
Maybe it's too late, I'll try to reply. As Tsyvarev said in his comment probably you are looking for the vfs_unlink function that you can find here namei.c.
Before the implementation there is a description, but a simple example can be this one
/*
fcheck's prototype is in linux/fdtable.h and returns a file pointer given a
given a file descriptor
*/
struct file *filp= fcheck(fd);
struct inode *parent_inode = filp->f_path.dentry->d_parent->d_inode;
inode_lock(parent_inode);
vfs_unlink(parent_inode, filp->f_path.dentry, NULL);
inode_unlock(parent_inode);
I hope it's can be useful to someone.
Related
On Linux, sched.h contains the definition of
int sched_rr_get_interval(pid_t pid, struct timespec * tp);
to get the time slice of a process. However the file shipping with OS X El Capitan doesn't hold that definition.
Is there an alternative for this on OS X?
The API's related to this stuff are pretty byzantine and poorly documented, but here's what I've found.
First, the datatypes related to RR scheduling seem to be in /usr/include/mach/policy.h, around line 155. There's this struct:
struct policy_rr_info {
...
integer_t quantum;
....
};
The quantum is, I think, the timeslice (not sure of units.) Then grepping around for this or related types defined in the same place, I found the file /usr/include/mach/mach_types.def, which says that the type struct thread_policy_t contains a field policy_rr_info_t on line 203.
Next, I found in /usr/include/mach/thread_act.h the public function thread_policy_get, which can retrieve information about a thread's policy into a struct thread_policy_t *.
So, working backwards. I think (but haven't tried at all) that you can
Use the thread_policy_get() routine to return information about the thread's scheduling state into a thread_policy_t
That struct seems to have a policy_rr_info_t sub-substructure
That sub-structure should have a quantum field.
That field appears to be the timeslice, but I don't know about the units.
There are no man pages for this part of the API, but this Apple Developer page explains at least a little bit about how to use this API.
Note that this is all gleaned from just grepping the various kernel headers, and I've definitely not tried to use any of these APIs in any actual code.
Below I have mentioned my small code and following are my queries regarding it -
1.I have opened /usr/src/linux-headers-3.13.0-32/include/linux/sched.h and I found the declaration of struct task_struct there , but when I try to declare an instance i.e variable of task_struct in the main function which includes the sched.h header , then also it is not able to identify the task_struct , Why ? , Why it is so
2. Even when I copied the complete code of that header file within my code i.e my .c file outside main class then the compiler shows error to include many other header files which was not a problem when I haven't copied the code of sched.h in my .c file
The Error being displayed by compiler in first case is - storage size of ‘temp’ isn’t known
My code is ( The code is just a representational view to tell my concept of Question)
#include<linux/sched.h>
int main(void)
{
struct task_struct temp;
printf("%d",temp.pid);
return 0;
}
Since the concepts are clear still something is lacking, Kindly share your suggestions.
My Linux system (Ubuntu 14.04) doesn't make struct task_struct available to user code:
$ rgrep 'task_struct' /usr/include
/usr/include/linux/hdreg.h:} task_struct_t;
/usr/include/linux/capability.h:struct task_struct;
The 2nd match (struct task_struct;) is just a forward-declaration of the type. Without the { ... } in the type declaration, it's just a forward-declaration, and in C (and C++) it's not possible to use a forward-declaration of a struct to create a variable of that type. That's why you are getting the storage size of ... isn't known error.
If you want to create a variable of type struct task_struct, you need to get its type declaration from another .h file, which has it with { ... }. You may have to install a package containing kernel headers for this. Please refer to your Linux distribution's documentation about finding and installing packages. Once the package is installed, you can use gcc -I /usr/.../... to specify directory names for gcc to look for .h files.
Most programs (including all userland programs, excluding the kernel itself and excluding kernel modules) don't need to create a variable of type struct task_struct though. If you explain in your question what you want to use struct task_struct for, you'll probably get a recommendation to accomplish your goal without using struct task_struct.
If you just want to print the PID of the current process, here is how to do it without struct task_struct:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main() {
printf("%lld\n", (long long)getpid());
return 0;
}
Linux kernel headers are not designed to be included directly by user space programs. Even when you do this, this doesn't mean all content of such header is accessible to your code because of __KERNEL__ definitions which prevent this to happen. Linux kernel still tries to make it possible though for user code to use kernel headers so sometimes it is possible to do this, but you should stick to use kernel headers in kernel code and use C library otherwise.
This article may help.
Use it like this, sched.h is part of GNU
You can use like this:
#define _GNU_SOURCE
#ifndef __USE_GNU
#define __USE_GNU
#endif
#include <sched.h>
Now you can use all functions of sched.h
"struct task_struct" is undoubtedly present inside "linux/sched.h" . I suspect that you are building the module , in the wrong way , even your representational code looks like you are approaching the problem in user-space c programming style.
you should understand that Linux code is different from user space c programs in various aspects most basic being that it doesn't have a conventional "main" function as an entry point , but registration based mechanisms.You can read about building kernel modules from https://tldp.org/LDP/lkmpg/2.6/html/x181.html
I am writing a kernel module where I implement some functions that are going to be used from another modules I have modified. When testing the system crashes. I get a "scheduling while atomic" error.
After debugging, I realized that the system crashes when a atomic_set() is called. It means that I am calling an atomic function from a non-atomic function? can't I use atomic_set() in this case? What should I use instead?
Also, as I said, I modified some original kernel files for calling my function. How could I know if where I am working is atomic code or not?
EDIT: Adding the actual code
In net/netfilter/ipvs/ip_vs_core.c line 451, I call my function:
my_callback(svc, skb);
Then, in another file I have:
int my_callback(struct ip_vs_service *svc, struct sk_buff *skb)
{
int swto;
printk(KERN_INFO "callback called \n");
swto = swtoing(svc);
return swto;
}
My swtoing() function is a bit long, but I had debugged a lot, and have figured out that the system does not crash if I comment a line within swtoing() with a atomic_set()...
Any help?
EDIT 2: More info
I realized that the kernel modules I am modifying are FULL of spin_locks and stuff like that... So I think (forgive me if I am wrong) that I must do something in the functions that I am creating, in order to keep the locking/atomic stuff... but I don't know what :(
You can use in_atomic macro but is has some restrictions. See the comment.
first post here so be nice ;)
Is it possible to store a FILE * in a struct, i see no reason why not but the following code wont compile, i can't seem to store a reference to file pointer either.
typedef struct fileType
{
FILE * file;
char fileName[MAX_FILENAME_LEN];
unsigned linesRead;
unsigned nextBufLine; /* next line to be inserted/removed in the buffer */
pthread_mutex_t * mtxFile; /* mutex controlling access to this file */
}FileType;
My compiler doesn't seem to recognise the type 'FILE' throwing this error at that line, and of course i have included stdio.h in the header
error: expected specifier-qualifier-list before '(' token
Basically I'm writing a program which spawns a a series of child process, taking turns to read lines from a file and inserting them into a circular buffer where they are read by a another set of child processes, encrypted and written to a new file (line by line). It is a requirement that the parent open and closes the file.
I'm permitted to use globals for this but want to avoid it if possible, thanks for any replies. =]
Do you have a macro somewhere which is redefining FILE or file as something else?
If you include <stdio.h> it should be fine to have a FILE* member in your struct.
There isn't anything wrong with storing a FILE* in a struct, and given that the error message mentions a '(' I suspect the problem could potentially be in some other part of your code (since there isn't a left parenthese in the code you posted). If you post more of the code we might be able to help you better. Given what you have there my only other thought is that you missed an include for the pthread_mutex_t
What data type is it? char , int ...
unsigned linesRead;
unsigned nextBufLine;
In the 2nd edition of "The C Programming Language" by Kernighan and Ritchie they implement a simplified version of the UNIX command ls (section 8.6 "Example - Listing Directories", p. 179). For this purpose they create the following interface which provides a system-independent access to the name and inode number of the files stored in a directory.
#define NAME_MAX 14 /* longest filename component; */
/* system dependent */
typedef struct { /* portable director-entry */
long ino; /* inode number */
char name[NAME_MAX+1]; /* name + '\0' terminator */
} Dirent;
typedef struct { /* minimal DIR: no buffering, etc. */
int fd; /* file descriptor for directory */
Dirent d; /* the directory entry */
} DIR;
DIR *opendir(char *dirname);
Dirent *readdir(DIR *dfd);
void closedir(DIR *dfd);
Then they implement this interface for Version 7 and System V UNIX systems.
opendir() basically uses the system
call open() to open a directory and
malloc() to allocate space for a
DIR structure. The file descriptor
returned by open() is then stored
in the variable fd of that DIR.
Nothing is stored in the Dirent
component.
readdir() uses the system call
read() to get the next
(system-dependent) directory entry of
an opened directory and copies the so
obtained inode number and filename
into a static Dirent structure (to
which a pointer is returned). The
only information needed by
readdir() is the file descriptor
stored in the DIR structure.
Now to my question: What is the point of having a DIR structure? If my understanding of this program is correct, the Dirent component of DIR is never used, so why not replace the whole structure with a file descriptor and directly use open() and close()?
Thanks.
Ps: I am aware that on modern UNIX systems read() can no longer be used on directories (I have tried out this program on Ubuntu 10.04), but I still want to make sure that I have not overlooked something important in this example.
From K&R:
Regrettably, the format and precise contents of a directory are not the same on all
versions of the system. So we will divide the task into two pieces to try to isolate
the non-portable parts. The outer level defines a structure called a Dirent and three routines opendir, readdir, and closedir to provide system-independent access to the name and inode number in a directory entry.
So the reason is portability. They want to define an interface that can survive on systems that have different stat structs or nonstandard open() and close(). They go on to build a bunch of reusable tools around it, which don't even care if they're on a Unix-like system. That's the point of wrappers.
Maybe it's not used because they started out by defining their data structures (with a Dirent inside DIR) but ended up not using it. Keeping data structures grouped like that is good design.
It is so they don't have to allocate memory for the Dirent structure that is returned by readdir. This way they can reuse the Dirent between subsiquent calls to readdir.