2012-12-24 15:36:14 +04:00
|
|
|
#ifndef __CR_PROC_PARSE_H__
|
|
|
|
#define __CR_PROC_PARSE_H__
|
2012-01-13 20:54:08 +04:00
|
|
|
|
2012-04-05 15:43:00 +04:00
|
|
|
#include <sys/types.h>
|
2013-01-09 17:02:47 +04:00
|
|
|
#include "asm/types.h"
|
2012-07-11 09:22:38 +04:00
|
|
|
#include "image.h"
|
2012-04-05 15:43:00 +04:00
|
|
|
#include "list.h"
|
2014-07-10 17:00:28 +04:00
|
|
|
#include "cgroup.h"
|
2012-04-05 15:43:00 +04:00
|
|
|
|
2013-02-15 17:33:06 +04:00
|
|
|
#include "protobuf/eventfd.pb-c.h"
|
|
|
|
#include "protobuf/eventpoll.pb-c.h"
|
|
|
|
#include "protobuf/signalfd.pb-c.h"
|
|
|
|
#include "protobuf/fsnotify.pb-c.h"
|
2014-06-30 21:58:05 +04:00
|
|
|
#include "protobuf/timerfd.pb-c.h"
|
2012-07-17 07:24:54 +04:00
|
|
|
|
2012-01-15 20:24:13 +04:00
|
|
|
#define PROC_TASK_COMM_LEN 32
|
|
|
|
#define PROC_TASK_COMM_LEN_FMT "(%31s"
|
2012-01-13 20:54:08 +04:00
|
|
|
|
ctrools: Rewrite task/threads stopping engine is back
This commit brings the former "Rewrite task/threads stopping engine"
commit back. Handling it separately is too complex so better try
to handle it in-place.
Note some tests might fault, it's expected.
---
Stopping tasks with STOP and proceeding with SEIZE is actually excessive --
the SEIZE if enough. Moreover, just killing a task with STOP is also racy,
since task should be given some time to come to sleep before its proc
can be parsed.
Rewrite all this code to SEIZE task and all its threads from the very beginning.
With this we can distinguish stopped task state and migrate it properly (not
supported now, need to implement).
This thing however has one BIG problem -- after we SEIZE-d a task we should
seize
it's threads, but we should do it in a loop -- reading /proc/pid/task and
seizing
them again and again, until the contents of this dir stops changing (not done
now).
Besides, after we seized a task and all its threads we cannot scan it's children
list once -- task can get reparented to init and any task's child can call clone
with CLONE_PARENT flag thus repopulating the children list of the already seized
task (not done also)
This patch is ugly, yes, but splitting it doesn't help to review it much, sorry
:(
Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
2012-02-01 19:45:31 +04:00
|
|
|
struct proc_pid_stat_small {
|
|
|
|
int pid;
|
|
|
|
char comm[PROC_TASK_COMM_LEN];
|
|
|
|
char state;
|
2012-03-01 19:04:31 +04:00
|
|
|
int ppid;
|
2012-04-11 22:09:12 +04:00
|
|
|
int pgid;
|
|
|
|
int sid;
|
ctrools: Rewrite task/threads stopping engine is back
This commit brings the former "Rewrite task/threads stopping engine"
commit back. Handling it separately is too complex so better try
to handle it in-place.
Note some tests might fault, it's expected.
---
Stopping tasks with STOP and proceeding with SEIZE is actually excessive --
the SEIZE if enough. Moreover, just killing a task with STOP is also racy,
since task should be given some time to come to sleep before its proc
can be parsed.
Rewrite all this code to SEIZE task and all its threads from the very beginning.
With this we can distinguish stopped task state and migrate it properly (not
supported now, need to implement).
This thing however has one BIG problem -- after we SEIZE-d a task we should
seize
it's threads, but we should do it in a loop -- reading /proc/pid/task and
seizing
them again and again, until the contents of this dir stops changing (not done
now).
Besides, after we seized a task and all its threads we cannot scan it's children
list once -- task can get reparented to init and any task's child can call clone
with CLONE_PARENT flag thus repopulating the children list of the already seized
task (not done also)
This patch is ugly, yes, but splitting it doesn't help to review it much, sorry
:(
Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
2012-02-01 19:45:31 +04:00
|
|
|
};
|
|
|
|
|
2012-01-13 20:54:08 +04:00
|
|
|
struct proc_pid_stat {
|
2012-01-14 01:48:29 +04:00
|
|
|
int pid;
|
2012-01-15 20:24:13 +04:00
|
|
|
char comm[PROC_TASK_COMM_LEN];
|
2012-01-14 01:48:29 +04:00
|
|
|
char state;
|
|
|
|
int ppid;
|
|
|
|
int pgid;
|
|
|
|
int sid;
|
|
|
|
int tty_nr;
|
|
|
|
int tty_pgrp;
|
|
|
|
unsigned int flags;
|
|
|
|
unsigned long min_flt;
|
|
|
|
unsigned long cmin_flt;
|
|
|
|
unsigned long maj_flt;
|
|
|
|
unsigned long cmaj_flt;
|
|
|
|
unsigned long utime;
|
|
|
|
unsigned long stime;
|
|
|
|
long cutime;
|
|
|
|
long cstime;
|
|
|
|
long priority;
|
|
|
|
long nice;
|
|
|
|
int num_threads;
|
|
|
|
int zero0;
|
|
|
|
unsigned long long start_time;
|
|
|
|
unsigned long vsize;
|
|
|
|
long mm_rss;
|
|
|
|
unsigned long rsslim;
|
|
|
|
unsigned long start_code;
|
|
|
|
unsigned long end_code;
|
|
|
|
unsigned long start_stack;
|
|
|
|
unsigned long esp;
|
|
|
|
unsigned long eip;
|
|
|
|
unsigned long sig_pending;
|
|
|
|
unsigned long sig_blocked;
|
|
|
|
unsigned long sig_ignored;
|
|
|
|
unsigned long sig_handled;
|
|
|
|
unsigned long wchan;
|
|
|
|
unsigned long zero1;
|
|
|
|
unsigned long zero2;
|
|
|
|
int exit_signal;
|
|
|
|
int task_cpu;
|
|
|
|
unsigned int rt_priority;
|
|
|
|
unsigned int policy;
|
|
|
|
unsigned long long delayacct_blkio_ticks;
|
|
|
|
unsigned long gtime;
|
|
|
|
long cgtime;
|
|
|
|
unsigned long start_data;
|
|
|
|
unsigned long end_data;
|
|
|
|
unsigned long start_brk;
|
2012-01-23 15:18:31 +04:00
|
|
|
unsigned long arg_start;
|
|
|
|
unsigned long arg_end;
|
|
|
|
unsigned long env_start;
|
|
|
|
unsigned long env_end;
|
2012-01-22 20:22:40 +04:00
|
|
|
int exit_code;
|
2012-01-13 20:54:08 +04:00
|
|
|
};
|
|
|
|
|
2012-01-27 21:37:13 +04:00
|
|
|
#define PROC_CAP_SIZE 2
|
|
|
|
|
|
|
|
struct proc_status_creds {
|
|
|
|
unsigned int uids[4];
|
|
|
|
unsigned int gids[4];
|
|
|
|
|
2013-12-12 10:03:07 +04:00
|
|
|
u32 cap_inh[PROC_CAP_SIZE];
|
|
|
|
u32 cap_prm[PROC_CAP_SIZE];
|
|
|
|
u32 cap_eff[PROC_CAP_SIZE];
|
|
|
|
u32 cap_bnd[PROC_CAP_SIZE];
|
2012-01-27 21:37:13 +04:00
|
|
|
};
|
|
|
|
|
2012-08-09 16:27:30 +04:00
|
|
|
struct mount_info;
|
|
|
|
struct fstype {
|
|
|
|
char *name;
|
2013-12-04 19:51:10 +04:00
|
|
|
int code;
|
2012-08-09 16:27:30 +04:00
|
|
|
int (*dump)(struct mount_info *pm);
|
|
|
|
int (*restore)(struct mount_info *pm);
|
2013-12-04 19:51:25 +04:00
|
|
|
int (*parse)(struct mount_info *pm);
|
2012-08-09 16:27:30 +04:00
|
|
|
};
|
|
|
|
|
2014-06-09 17:26:17 +04:00
|
|
|
struct ext_mount;
|
2012-06-27 20:57:30 +04:00
|
|
|
struct mount_info {
|
2012-05-04 13:38:00 +04:00
|
|
|
int mnt_id;
|
|
|
|
int parent_mnt_id;
|
|
|
|
unsigned int s_dev;
|
2012-06-27 20:57:29 +04:00
|
|
|
char *root;
|
2014-04-16 14:48:00 +04:00
|
|
|
/*
|
2014-08-06 12:04:22 +04:00
|
|
|
* During dump mountpoint contains path with dot at the
|
|
|
|
* beginning. It allows to use openat, statat, etc without
|
|
|
|
* creating a temporary copy of the path.
|
|
|
|
*
|
|
|
|
* On restore mountpoint is prepended with so called ns
|
|
|
|
* root path -- it's a place in fs where the namespace
|
|
|
|
* mount tree is constructed. Check mnt_roots for details.
|
2014-08-05 17:20:25 +04:00
|
|
|
* The ns_mountpoint contains path w/o this prefix.
|
2014-04-16 14:48:00 +04:00
|
|
|
*/
|
2012-06-27 20:57:29 +04:00
|
|
|
char *mountpoint;
|
2014-08-05 17:20:25 +04:00
|
|
|
char *ns_mountpoint;
|
2012-05-13 08:30:06 +04:00
|
|
|
unsigned flags;
|
|
|
|
int master_id;
|
|
|
|
int shared_id;
|
2012-08-09 16:27:30 +04:00
|
|
|
struct fstype *fstype;
|
2012-06-27 20:57:29 +04:00
|
|
|
char *source;
|
|
|
|
char *options;
|
2014-06-16 18:40:04 +04:00
|
|
|
union {
|
|
|
|
bool mounted;
|
|
|
|
bool dumped;
|
|
|
|
};
|
2013-12-25 16:54:36 +04:00
|
|
|
bool need_plugin;
|
2013-12-25 16:54:53 +04:00
|
|
|
int is_file;
|
2014-04-21 18:23:15 +04:00
|
|
|
bool is_ns_root;
|
2012-06-27 20:57:30 +04:00
|
|
|
struct mount_info *next;
|
2014-04-21 18:23:36 +04:00
|
|
|
struct ns_id *nsid;
|
2012-06-27 20:57:34 +04:00
|
|
|
|
2014-06-09 17:26:17 +04:00
|
|
|
struct ext_mount *external;
|
|
|
|
|
2012-06-27 20:57:34 +04:00
|
|
|
/* tree linkage */
|
|
|
|
struct mount_info *parent;
|
mounts: find mounts, which are propagated from a current one (v2)
A few sentences, which are required for understanging this patch
2a) A shared mount can be replicated to as many mountpoints and all the
replicas continue to be exactly same.
2b) A slave mount is like a shared mount except that mount and umount
events only propagate towards it.
2c) A private mount does not forward or receive propagation.
All rules is there Documentation/filesystems/sharedsubtree.txt
If it's a first mount in a group, all group members should be
bind-mounted from this one.
Each mount propagates to all members of parent's group. The group can
contains a few slaves.
Mounts, which have propagated to slaves, are unmounted, because we can't
be sure, that they propagated in real life. For example:
mount --bind --make-slave /share /slave1
mount --bind --make-slave /share /slave2
mount /share/test
umount /slave2/test
mount --make-share /slave1/test
mount --bind --make-share /slave1/test /slave2/test
41 40 0:33 / /share rw,relatime shared:28 - tmpfs xxx rw
42 40 0:33 / /slave1 rw,relatime master:28 - tmpfs xxx rw
43 40 0:33 / /slave2 rw,relatime master:28 - tmpfs xxx rw
44 41 0:34 / /share/test rw,relatime shared:29 - tmpfs xxx rw
46 42 0:34 / /slave1/test rw,relatime shared:30 master:29 - tmpfs xxx rw
45 43 0:34 / /slave2/test rw,relatime shared:30 master:29 - tmpfs xxx rw
/slave1/test and /slave2/test depend on each other and minimum one of them
doesn't propagate from /share/test
v2: use false and true for bool
Signed-off-by: Andrey Vagin <avagin@openvz.org>
Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
2013-08-29 18:54:00 +04:00
|
|
|
struct mount_info *bind;
|
2012-06-27 20:57:34 +04:00
|
|
|
struct list_head children;
|
|
|
|
struct list_head siblings;
|
2013-08-29 18:55:38 +04:00
|
|
|
|
mounts: find mounts, which are propagated from a current one (v2)
A few sentences, which are required for understanging this patch
2a) A shared mount can be replicated to as many mountpoints and all the
replicas continue to be exactly same.
2b) A slave mount is like a shared mount except that mount and umount
events only propagate towards it.
2c) A private mount does not forward or receive propagation.
All rules is there Documentation/filesystems/sharedsubtree.txt
If it's a first mount in a group, all group members should be
bind-mounted from this one.
Each mount propagates to all members of parent's group. The group can
contains a few slaves.
Mounts, which have propagated to slaves, are unmounted, because we can't
be sure, that they propagated in real life. For example:
mount --bind --make-slave /share /slave1
mount --bind --make-slave /share /slave2
mount /share/test
umount /slave2/test
mount --make-share /slave1/test
mount --bind --make-share /slave1/test /slave2/test
41 40 0:33 / /share rw,relatime shared:28 - tmpfs xxx rw
42 40 0:33 / /slave1 rw,relatime master:28 - tmpfs xxx rw
43 40 0:33 / /slave2 rw,relatime master:28 - tmpfs xxx rw
44 41 0:34 / /share/test rw,relatime shared:29 - tmpfs xxx rw
46 42 0:34 / /slave1/test rw,relatime shared:30 master:29 - tmpfs xxx rw
45 43 0:34 / /slave2/test rw,relatime shared:30 master:29 - tmpfs xxx rw
/slave1/test and /slave2/test depend on each other and minimum one of them
doesn't propagate from /share/test
v2: use false and true for bool
Signed-off-by: Andrey Vagin <avagin@openvz.org>
Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
2013-08-29 18:54:00 +04:00
|
|
|
struct list_head mnt_bind; /* circular list of derivatives of one real mount */
|
2013-08-29 18:55:38 +04:00
|
|
|
struct list_head mnt_share; /* circular list of shared mounts */
|
|
|
|
struct list_head mnt_slave_list;/* list of slave mounts */
|
|
|
|
struct list_head mnt_slave; /* slave list entry */
|
|
|
|
struct mount_info *mnt_master; /* slave is on master->mnt_slave_list */
|
2013-08-29 18:52:43 +04:00
|
|
|
|
|
|
|
struct list_head postpone;
|
2013-12-04 17:23:33 +04:00
|
|
|
|
|
|
|
void *private; /* associated filesystem data */
|
2012-05-04 13:38:00 +04:00
|
|
|
};
|
|
|
|
|
2013-04-10 01:26:59 +04:00
|
|
|
extern struct mount_info *mnt_entry_alloc();
|
|
|
|
extern void mnt_entry_free(struct mount_info *mi);
|
2012-06-27 20:57:34 +04:00
|
|
|
|
2013-03-01 20:11:51 +04:00
|
|
|
struct vm_area_list;
|
|
|
|
|
2014-04-21 18:23:36 +04:00
|
|
|
extern struct mount_info *parse_mountinfo(pid_t pid, struct ns_id *nsid);
|
2012-02-17 01:39:36 +04:00
|
|
|
extern int parse_pid_stat(pid_t pid, struct proc_pid_stat *s);
|
|
|
|
extern int parse_pid_stat_small(pid_t pid, struct proc_pid_stat_small *s);
|
2013-03-01 20:11:51 +04:00
|
|
|
extern int parse_smaps(pid_t pid, struct vm_area_list *vma_area_list, bool use_map_files);
|
2014-02-07 13:32:21 +04:00
|
|
|
extern int parse_self_maps_lite(struct vm_area_list *vms);
|
2012-02-17 01:39:36 +04:00
|
|
|
extern int parse_pid_status(pid_t pid, struct proc_status_creds *);
|
2012-01-14 01:48:29 +04:00
|
|
|
|
2014-08-25 23:19:54 +04:00
|
|
|
struct inotify_wd_entry {
|
|
|
|
InotifyWdEntry e;
|
|
|
|
FhEntry f_handle;
|
|
|
|
struct list_head node;
|
|
|
|
};
|
|
|
|
|
2014-08-25 23:19:56 +04:00
|
|
|
struct fanotify_mark_entry {
|
|
|
|
FanotifyMarkEntry e;
|
|
|
|
FhEntry f_handle;
|
|
|
|
struct list_head node;
|
|
|
|
union {
|
|
|
|
FanotifyInodeMarkEntry ie;
|
|
|
|
FanotifyMountMarkEntry me;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2014-08-25 23:19:58 +04:00
|
|
|
struct eventpoll_tfd_entry {
|
|
|
|
EventpollTfdEntry e;
|
|
|
|
struct list_head node;
|
|
|
|
};
|
|
|
|
|
2012-07-11 09:22:38 +04:00
|
|
|
union fdinfo_entries {
|
2012-07-17 07:24:54 +04:00
|
|
|
EventfdFileEntry efd;
|
2012-08-02 12:25:18 +04:00
|
|
|
SignalfdEntry sfd;
|
2014-08-25 23:19:54 +04:00
|
|
|
struct inotify_wd_entry ify;
|
2014-08-25 23:19:56 +04:00
|
|
|
struct fanotify_mark_entry ffy;
|
2014-08-25 23:19:58 +04:00
|
|
|
struct eventpoll_tfd_entry epl;
|
2014-06-30 21:58:05 +04:00
|
|
|
TimerfdEntry tfy;
|
2012-07-11 09:22:38 +04:00
|
|
|
};
|
|
|
|
|
2014-08-25 23:19:54 +04:00
|
|
|
extern void free_inotify_wd_entry(union fdinfo_entries *e);
|
2014-08-25 23:19:56 +04:00
|
|
|
extern void free_fanotify_mark_entry(union fdinfo_entries *e);
|
2014-08-25 23:19:58 +04:00
|
|
|
extern void free_event_poll_entry(union fdinfo_entries *e);
|
2014-08-25 23:19:54 +04:00
|
|
|
|
2014-04-09 03:34:53 +04:00
|
|
|
struct fdinfo_common {
|
|
|
|
off64_t pos;
|
|
|
|
int flags;
|
2014-04-09 03:34:54 +04:00
|
|
|
int mnt_id;
|
2014-04-09 03:34:53 +04:00
|
|
|
};
|
|
|
|
|
2012-07-11 09:22:38 +04:00
|
|
|
extern int parse_fdinfo(int fd, int type,
|
|
|
|
int (*cb)(union fdinfo_entries *e, void *arg), void *arg);
|
2014-01-30 13:41:53 +04:00
|
|
|
extern int parse_fdinfo_pid(int pid, int fd, int type,
|
|
|
|
int (*cb)(union fdinfo_entries *e, void *arg), void *arg);
|
2013-02-18 17:54:49 +04:00
|
|
|
extern int parse_cpuinfo_features(int (*handler)(char *tok));
|
2013-01-17 16:09:32 +08:00
|
|
|
extern int parse_file_locks(void);
|
2012-07-11 09:22:38 +04:00
|
|
|
|
2013-09-23 14:33:30 +04:00
|
|
|
struct pid;
|
|
|
|
extern int parse_threads(int pid, struct pid **_t, int *_n);
|
|
|
|
|
2014-04-21 18:23:49 +04:00
|
|
|
extern int check_mnt_id(void);
|
|
|
|
|
2014-05-08 16:30:30 +04:00
|
|
|
/*
|
|
|
|
* This struct describes a group controlled by one controller.
|
|
|
|
* The @name is the controller name or 'name=...' for named cgroups.
|
|
|
|
* The @path is the path from the hierarchy root.
|
|
|
|
*/
|
|
|
|
|
|
|
|
struct cg_ctl {
|
|
|
|
struct list_head l;
|
|
|
|
char *name;
|
|
|
|
char *path;
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Returns the list of cg_ctl-s sorted by name
|
|
|
|
*/
|
|
|
|
|
|
|
|
extern int parse_task_cgroup(int pid, struct list_head *l, unsigned int *n);
|
|
|
|
extern void put_ctls(struct list_head *);
|
|
|
|
|
2014-07-10 17:00:28 +04:00
|
|
|
int parse_cgroups(struct list_head *cgroups, unsigned int *n_cgroups);
|
|
|
|
|
2014-08-19 22:31:07 -07:00
|
|
|
/* callback for AUFS support */
|
|
|
|
extern int aufs_parse(struct mount_info *mi);
|
|
|
|
|
2012-12-25 22:40:24 +04:00
|
|
|
#endif /* __CR_PROC_PARSE_H__ */
|