Custom fs with libfuse and file ownership - fuse

When user create file, create callback will be called:
int (*create) (const char *, mode_t, struct fuse_file_info *);
see link for details https://github.com/libfuse/libfuse/blob/74596e2929c9b9b065f90d04ab7a2232652c64c4/include/fuse.h#L609
But where are no info about what user want to create a file, means file will be always created with owner user that fuse process run from.
For example I started fuse process as a root, but create file from my user:
$ echo $USERNAME
myuser
$ echo 'f' > f
$ ll
$ ll
total 4,0K
-rw-r--r-- 1 root root

You can get the uid and gid of the calling user using the global fuse context:
struct fuse_context *cxt = fuse_get_context();
if (cxt)
uid = cxt->uid;
gid = cxt->gid;
From fuse.h:
/** Extra context that may be needed by some filesystems
*
* The uid, gid and pid fields are not filled in case of a writepage
* operation.
*/
struct fuse_context {
/** Pointer to the fuse object */
struct fuse *fuse;
/** User ID of the calling process */
uid_t uid;
/** Group ID of the calling process */
gid_t gid;
/** Process ID of the calling thread */
pid_t pid;
/** Private filesystem data */
void *private_data;
/** Umask of the calling process */
mode_t umask;
};

Related

In Linux is there a standard call to resolve a pathname to an inode?

Making a kernel module to link an inode to a directory. Beginner so on the learning curve. The plan is to resolve the directory to an inode, find its superblock and then get the inode from the file with iget_locked, finally link that inode into the dentry of the target directory and increment its link count.
syscall stat will take a pathname as input and dump a stat struct.
int stat(const char *pathname, struct stat *statbuf);
The inode to the file can be find as a member of the struct:
struct stat {
dev_t st_dev; /* ID of device containing file */
ino_t st_ino; /* Inode number */
mode_t st_mode; /* File type and mode */
nlink_t st_nlink; /* Number of hard links */
uid_t st_uid; /* User ID of owner */
gid_t st_gid; /* Group ID of owner */
dev_t st_rdev; /* Device ID (if special file) */
off_t st_size; /* Total size, in bytes */
blksize_t st_blksize; /* Block size for filesystem I/O */
blkcnt_t st_blocks; /* Number of 512B blocks allocated */
/* Since Linux 2.6, the kernel supports nanosecond
precision for the following timestamp fields.
For the details before Linux 2.6, see NOTES. */
struct timespec st_atim; /* Time of last access */
struct timespec st_mtim; /* Time of last modification */
struct timespec st_ctim; /* Time of last status change */
#define st_atime st_atim.tv_sec /* Backward compatibility */
#define st_mtime st_mtim.tv_sec
#define st_ctime st_ctim.tv_sec
};
Referring to manpage stat(2). Hope this answers your question.

Linux process data structure

According to GNU website the linux shell uses the following data structure for a process :
typedef struct process
{
struct process *next; /* next process in pipeline */
char **argv; /* for exec */
pid_t pid; /* process ID */
char completed; /* true if process has completed */
char stopped; /* true if process has stopped */
int status; /* reported status value */
} process;
Why can't the shell use the task_struct data structure for a process when it is already present in the kernel. Why use a separate data structure ?

Creating a process in Linux with a different mount namespace

I'm trying to create a process that has a different mnt namespace from his parent.
For that, I use the following code:
static int childFunc(void *arg){
if (mount("/","/myfs", "sysfs", 0, NULL) == -1)
errExit("mount");
printf("Starting new bash. Child PID is %d\n",getpid());
execle("/bin/bash",NULL);
printf("Shouldn't arrive here.\n");
return 0; /* Child terminates now */
}
#define STACK_SIZE (1024 * 1024) /* Stack size for cloned child */
int main(int argc, char *argv[]){
char *stack; /* Start of stack buffer */
char *stackTop; /* End of stack buffer */
pid_t pid;
/* Allocate stack for child */
stack = malloc(STACK_SIZE);
if (stack == NULL)
errExit("malloc");
stackTop = stack + STACK_SIZE; /* Assume stack grows downward */
/* Create child that has its own MNT namespaces*/
pid = clone(childFunc, stackTop, CLONE_NEWNS | SIGCHLD, argv[1]);
if (pid == -1)
errExit("clone");
printf("clone() returned %ld\n", (long) pid);
sleep(1);
if (waitpid(pid, NULL, 0) == -1) /* Wait for child */
errExit("waitpid");
printf("child has terminated\n");
exit(EXIT_SUCCESS);
}
When running it, I do get a bash shell, running in a different MNT namespace.
In order to verify it, I execute in another shell sudo ls -l /proc/<child_pid>/ns, and I indeed see that the child process has a different namespace from the rest of the processes in the system.
However, if I execute mount from both of the shells - I get the same FSTAB output, and the line myfs on /myfs type sysfs (rw,relatime) appears in both of them.
What is the explanation for that?
You need to mark the the existing mounts as "private" before creating the new namespace:
mount --make-rprivate /

Where do_fork() defines the "prio" field for the newly allocated task_struct?

That includes other fields like static_prio and policy. I know that by definition the child process inherits them from the father, but where does it happens in the code of do_fork() ?
The “prio” field for the newly allocated task_struct is defined in sched_fork() function.
The call flow for sched_fork() function is fork() -> sys_fork() -> do_fork() -> copy_process() -> sched_fork().
for your reference here is the sched_fork() function below. ( kernel version 3.7.5 )
void sched_fork(struct task_struct *p)
{
unsigned long flags;
int cpu = get_cpu();
__sched_fork(p);
/*
* We mark the process as running here. This guarantees that
* nobody will actually run it, and a signal or other external
* event cannot wake it up and insert it on the runqueue either.
*/
p->state = TASK_RUNNING;
/*
* Make sure we do not leak PI boosting priority to the child.
*/
p->prio = current->normal_prio;
/*
* Revert to default priority/policy on fork if requested.
*/
if (unlikely(p->sched_reset_on_fork)) {
if (task_has_rt_policy(p)) {
p->policy = SCHED_NORMAL;
p->static_prio = NICE_TO_PRIO(0);
p->rt_priority = 0;
} else if (PRIO_TO_NICE(p->static_prio) < 0)
p->static_prio = NICE_TO_PRIO(0);
p->prio = p->normal_prio = __normal_prio(p);
set_load_weight(p);
/*
* We don't need the reset flag anymore after the fork. It has
* fulfilled its duty:
*/
p->sched_reset_on_fork = 0;
}
.....
......
}

What is cron job's server usage?

Alright,
I'm thinking of creating a webscript that depends on cronjob.. I'm wondering, would it ever make any server damages for the amount of crontabs ?
lets say i have 50 crontabs to be done everyday, would it ever hurt the server ?
if no, what's the max amount of crontabs to be added in a linux server # 512MB memory
When you create a new job the cron daemon call the function job_add (job.c), this function alloc the memory to the job and add it to the tail of the job list.
The job is allocated on the heap, so theorically you're limited just by the RAM installed on your machine.
Some notes from the CRON code:
The job structure:
typedef struct _job {
struct _job *next;
entry *e;
user *u;
} job;
Each user crontab entry is defined by:
typedef struct _entry {
struct _entry *next;
uid_t uid;
gid_t gid;
char **envp;
char *cmd;
bitstr_t bit_decl(minute, MINUTE_COUNT);
bitstr_t bit_decl(hour, HOUR_COUNT);
bitstr_t bit_decl(dom, DOM_COUNT);
bitstr_t bit_decl(month, MONTH_COUNT);
bitstr_t bit_decl(dow, DOW_COUNT);
int flags;
#define DOM_STAR 0x01
#define DOW_STAR 0x02
#define WHEN_REBOOT 0x04
} entry;
And the user struct:
typedef struct _user {
struct _user *next, *prev; /* links */
char *name;
time_t mtime; /* last modtime of crontab */
entry *crontab; /* this person's crontab */
} user;
You can see that this structs does not cosume a lot of memory.
If you're curious about how the implementation of cron work, you can see the code here : cron ubuntu source.

Resources