[Devel] [PATCH] fused: save logrotate option to fstab

2017-08-17 Thread Dmitry Monakhov
currently one may run 'vstorage-mount -s' with -L option, but
it will affect only current mount w/o reflection to fstab opts.
In fact mount.fuse.vstorage already has parser for logrotate option, so
this patch makes this feature fully supported.

Signed-off-by: Dmitry Monakhov 
---
 pcs/clients/fused/fused.c | 14 --
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/pcs/clients/fused/fused.c b/pcs/clients/fused/fused.c
index b73da80..5c4a84e 100644
--- a/pcs/clients/fused/fused.c
+++ b/pcs/clients/fused/fused.c
@@ -176,6 +176,8 @@ static char *make_fstab_options(
int timeout,
char *logfile,
int loglevel,
+   unsigned long rotate_num,
+   unsigned long long rotate_size,
unsigned long mntflags,
char *username,
char *groupname,
@@ -197,6 +199,9 @@ static char *make_fstab_options(
res += fstab_add_option(, "logfile=%s", logfile);
if (loglevel != LOG_LEVEL_SRV_DEFAULT)
res += fstab_add_option(, "loglevel=%u", 
(unsigned)loglevel);
+   if (rotate_num || rotate_size)
+   res += fstab_add_option(, "logrotate=%lux%llu", rotate_num, 
rotate_size);
+
if (g_read_cache.params.pathname)
res += fstab_add_option(, "cache=%s", 
g_read_cache.params.pathname);
if (g_read_cache.params.total_sz_mb > 0)
@@ -501,6 +506,7 @@ int main(int argc, char** argv)
unsigned long mntflags = 0;
int ch, res = -1;
int pipefd[2];
+   int rotate_opt = 0;
unsigned long rotate_num = 10;
unsigned long long rotate_size = 100LL * 1024LL * 1024LL;
int after_exec = 0;
@@ -595,6 +601,7 @@ int main(int argc, char** argv)
case 'L':
if (parse_logrotate_diskspace(optarg, _num, 
_size) < 0)
usage(NULL);
+   rotate_opt = 1;
break;
case 'd':
pcs_log_level = strtoul(optarg, , 10);
@@ -678,8 +685,11 @@ int main(int argc, char** argv)
usage("Invalid read cache parameters");
 
if (fstab_modify) {
-   fstab_options = make_fstab_options(timeout, logfile, 
pcs_log_level, mntflags,
-   username, groupname, mode, nodef, mntparams);
+   fstab_options = make_fstab_options(timeout, logfile, 
pcs_log_level,
+  rotate_opt ? rotate_num : 0,
+  rotate_opt ? rotate_size : 0,
+  mntflags,  username, 
+  groupname, mode, nodef, 
mntparams);
if (!fstab_options) {
pcs_log(LOG_ERR, PCS_FUSED_MSG_PREFIX"failed to make 
fstab options");
exit(252);
-- 
1.8.3.1

___
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel


[Devel] [PATCH v2 21/27] proc connector: pass VE to event fillers

2017-08-17 Thread Stanislav Kinsburskiy
Precursor patch. VE will be used later to get proper pid and user namespaces
for correct event generation.

Signed-off-by: Stanislav Kinsburskiy 
---
 drivers/connector/cn_proc.c |   36 +++-
 1 file changed, 19 insertions(+), 17 deletions(-)

diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c
index ff99f06..b66fde8 100644
--- a/drivers/connector/cn_proc.c
+++ b/drivers/connector/cn_proc.c
@@ -64,6 +64,7 @@ static struct cn_msg *cn_msg_fill(__u8 *buffer, struct 
ve_struct *ve,
  struct task_struct *task,
  int what, int cookie,
  bool (*fill_event)(struct proc_event *ev,
+struct ve_struct *ve,
 struct task_struct *task,
 int cookie))
 {
@@ -85,7 +86,7 @@ static struct cn_msg *cn_msg_fill(__u8 *buffer, struct 
ve_struct *ve,
ev->timestamp_ns = timespec_to_ns();
ev->what = what;
 
-   return fill_event(ev, task, cookie) ? msg : NULL;
+   return fill_event(ev, ve, task, cookie) ? msg : NULL;
 }
 
 static int proc_event_num_listeners(struct ve_struct *ve)
@@ -98,6 +99,7 @@ static int proc_event_num_listeners(struct ve_struct *ve)
 static void proc_event_connector(struct task_struct *task,
 int what, int cookie,
 bool (*fill_event)(struct proc_event *ev,
+   struct ve_struct *ve,
struct task_struct *task,
int cookie))
 {
@@ -116,8 +118,8 @@ static void proc_event_connector(struct task_struct *task,
cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
 }
 
-static bool fill_fork_event(struct proc_event *ev, struct task_struct *task,
-   int unused)
+static bool fill_fork_event(struct proc_event *ev, struct ve_struct *ve,
+   struct task_struct *task, int unused)
 {
struct task_struct *parent;
 
@@ -136,8 +138,8 @@ void proc_fork_connector(struct task_struct *task)
proc_event_connector(task, PROC_EVENT_FORK, 0, fill_fork_event);
 }
 
-static bool fill_exec_event(struct proc_event *ev, struct task_struct *task,
-   int unused)
+static bool fill_exec_event(struct proc_event *ev, struct ve_struct *ve,
+   struct task_struct *task, int unused)
 {
ev->event_data.exec.process_pid = task_pid_nr_ns(task, _pid_ns);
ev->event_data.exec.process_tgid = task_tgid_nr_ns(task, _pid_ns);
@@ -149,8 +151,8 @@ void proc_exec_connector(struct task_struct *task)
proc_event_connector(task, PROC_EVENT_EXEC, 0, fill_exec_event);
 }
 
-static bool fill_id_event(struct proc_event *ev, struct task_struct *task,
- int which_id)
+static bool fill_id_event(struct proc_event *ev, struct ve_struct *ve,
+ struct task_struct *task, int which_id)
 {
const struct cred *cred;
 
@@ -177,8 +179,8 @@ void proc_id_connector(struct task_struct *task, int 
which_id)
proc_event_connector(task, which_id, which_id, fill_id_event);
 }
 
-static bool fill_sid_event(struct proc_event *ev, struct task_struct *task,
-  int unused)
+static bool fill_sid_event(struct proc_event *ev, struct ve_struct *ve,
+  struct task_struct *task, int unused)
 {
ev->event_data.sid.process_pid = task_pid_nr_ns(task, _pid_ns);
ev->event_data.sid.process_tgid = task_tgid_nr_ns(task, _pid_ns);
@@ -190,8 +192,8 @@ void proc_sid_connector(struct task_struct *task)
proc_event_connector(task, PROC_EVENT_SID, 0, fill_sid_event);
 }
 
-static bool fill_ptrace_event(struct proc_event *ev, struct task_struct *task,
-  int ptrace_id)
+static bool fill_ptrace_event(struct proc_event *ev, struct ve_struct *ve,
+ struct task_struct *task, int ptrace_id)
 {
ev->event_data.ptrace.process_pid  = task_pid_nr_ns(task, _pid_ns);
ev->event_data.ptrace.process_tgid = task_tgid_nr_ns(task, 
_pid_ns);
@@ -212,8 +214,8 @@ void proc_ptrace_connector(struct task_struct *task, int 
ptrace_id)
 fill_ptrace_event);
 }
 
-static bool fill_comm_event(struct proc_event *ev, struct task_struct *task,
-   int unused)
+static bool fill_comm_event(struct proc_event *ev, struct ve_struct *ve,
+   struct task_struct *task, int unused)
 {
ev->event_data.comm.process_pid  = task_pid_nr_ns(task, _pid_ns);
ev->event_data.comm.process_tgid = task_tgid_nr_ns(task, _pid_ns);
@@ -226,8 +228,8 @@ void proc_comm_connector(struct task_struct 

[Devel] [PATCH v2 22/27] proc connector: take namespaces from VE

2017-08-17 Thread Stanislav Kinsburskiy
Intead of hardcoded "init" namespaces.

Signed-off-by: Stanislav Kinsburskiy 
---
 drivers/connector/cn_proc.c |   69 ++-
 1 file changed, 42 insertions(+), 27 deletions(-)

diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c
index b66fde8..df6553d 100644
--- a/drivers/connector/cn_proc.c
+++ b/drivers/connector/cn_proc.c
@@ -122,14 +122,15 @@ static bool fill_fork_event(struct proc_event *ev, struct 
ve_struct *ve,
struct task_struct *task, int unused)
 {
struct task_struct *parent;
+   struct pid_namespace *pid_ns = ve->ve_ns->pid_ns;
 
rcu_read_lock();
parent = rcu_dereference(task->real_parent);
-   ev->event_data.fork.parent_pid = task_pid_nr_ns(parent, _pid_ns);
-   ev->event_data.fork.parent_tgid = task_tgid_nr_ns(parent, _pid_ns);
+   ev->event_data.fork.parent_pid = task_pid_nr_ns(parent, pid_ns);
+   ev->event_data.fork.parent_tgid = task_tgid_nr_ns(parent, pid_ns);
rcu_read_unlock();
-   ev->event_data.fork.child_pid = task_pid_nr_ns(task, _pid_ns);
-   ev->event_data.fork.child_tgid = task_tgid_nr_ns(task, _pid_ns);
+   ev->event_data.fork.child_pid = task_pid_nr_ns(task, pid_ns);
+   ev->event_data.fork.child_tgid = task_tgid_nr_ns(task, pid_ns);
return true;
 }
 
@@ -141,8 +142,10 @@ void proc_fork_connector(struct task_struct *task)
 static bool fill_exec_event(struct proc_event *ev, struct ve_struct *ve,
struct task_struct *task, int unused)
 {
-   ev->event_data.exec.process_pid = task_pid_nr_ns(task, _pid_ns);
-   ev->event_data.exec.process_tgid = task_tgid_nr_ns(task, _pid_ns);
+   struct pid_namespace *pid_ns = ve->ve_ns->pid_ns;
+
+   ev->event_data.exec.process_pid = task_pid_nr_ns(task, pid_ns);
+   ev->event_data.exec.process_tgid = task_tgid_nr_ns(task, pid_ns);
return true;
 }
 
@@ -155,17 +158,19 @@ static bool fill_id_event(struct proc_event *ev, struct 
ve_struct *ve,
  struct task_struct *task, int which_id)
 {
const struct cred *cred;
+   struct pid_namespace *pid_ns = ve->ve_ns->pid_ns;
+   struct user_namespace *user_ns = ve->init_cred->user_ns;
 
-   ev->event_data.id.process_pid = task_pid_nr_ns(task, _pid_ns);
-   ev->event_data.id.process_tgid = task_tgid_nr_ns(task, _pid_ns);
+   ev->event_data.id.process_pid = task_pid_nr_ns(task, pid_ns);
+   ev->event_data.id.process_tgid = task_tgid_nr_ns(task, pid_ns);
rcu_read_lock();
cred = __task_cred(task);
if (which_id == PROC_EVENT_UID) {
-   ev->event_data.id.r.ruid = from_kuid_munged(_user_ns, 
cred->uid);
-   ev->event_data.id.e.euid = from_kuid_munged(_user_ns, 
cred->euid);
+   ev->event_data.id.r.ruid = from_kuid_munged(user_ns, cred->uid);
+   ev->event_data.id.e.euid = from_kuid_munged(user_ns, 
cred->euid);
} else if (which_id == PROC_EVENT_GID) {
-   ev->event_data.id.r.rgid = from_kgid_munged(_user_ns, 
cred->gid);
-   ev->event_data.id.e.egid = from_kgid_munged(_user_ns, 
cred->egid);
+   ev->event_data.id.r.rgid = from_kgid_munged(user_ns, cred->gid);
+   ev->event_data.id.e.egid = from_kgid_munged(user_ns, 
cred->egid);
} else {
rcu_read_unlock();
return false;
@@ -182,8 +187,10 @@ void proc_id_connector(struct task_struct *task, int 
which_id)
 static bool fill_sid_event(struct proc_event *ev, struct ve_struct *ve,
   struct task_struct *task, int unused)
 {
-   ev->event_data.sid.process_pid = task_pid_nr_ns(task, _pid_ns);
-   ev->event_data.sid.process_tgid = task_tgid_nr_ns(task, _pid_ns);
+   struct pid_namespace *pid_ns = ve->ve_ns->pid_ns;
+
+   ev->event_data.sid.process_pid = task_pid_nr_ns(task, pid_ns);
+   ev->event_data.sid.process_tgid = task_tgid_nr_ns(task, pid_ns);
return true;
 }
 
@@ -195,11 +202,13 @@ void proc_sid_connector(struct task_struct *task)
 static bool fill_ptrace_event(struct proc_event *ev, struct ve_struct *ve,
  struct task_struct *task, int ptrace_id)
 {
-   ev->event_data.ptrace.process_pid  = task_pid_nr_ns(task, _pid_ns);
-   ev->event_data.ptrace.process_tgid = task_tgid_nr_ns(task, 
_pid_ns);
+   struct pid_namespace *pid_ns = ve->ve_ns->pid_ns;
+
+   ev->event_data.ptrace.process_pid  = task_pid_nr_ns(task, pid_ns);
+   ev->event_data.ptrace.process_tgid = task_tgid_nr_ns(task, pid_ns);
if (ptrace_id == PTRACE_ATTACH) {
-   ev->event_data.ptrace.tracer_pid  = task_pid_nr_ns(current, 
_pid_ns);
-   ev->event_data.ptrace.tracer_tgid = task_tgid_nr_ns(current, 
_pid_ns);
+   ev->event_data.ptrace.tracer_pid  = task_pid_nr_ns(current, 
pid_ns);
+   

[Devel] [PATCH v2 26/27] connector: take VE from socket upon callback

2017-08-17 Thread Stanislav Kinsburskiy
This is needed to attach listener to the right device. I.e. attach to the
right source of events (in terms of CT).

Signed-off-by: Stanislav Kinsburskiy 
---
 drivers/connector/connector.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c
index 771dadf..81854bf 100644
--- a/drivers/connector/connector.c
+++ b/drivers/connector/connector.c
@@ -130,7 +130,7 @@ EXPORT_SYMBOL_GPL(cn_netlink_send);
 static int cn_call_callback(struct sk_buff *skb)
 {
struct cn_callback_entry *i, *cbq = NULL;
-   struct cn_dev *dev = get_cdev(get_ve0());
+   struct cn_dev *dev = get_cdev(skb->sk->sk_net->owner_ve);
struct cn_msg *msg = nlmsg_data(nlmsg_hdr(skb));
struct netlink_skb_parms *nsp = _CB(skb);
int err = -ENODEV;

___
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel


[Devel] [PATCH v2 15/27] proc connector: use generic event helper for coredump event

2017-08-17 Thread Stanislav Kinsburskiy
Signed-off-by: Stanislav Kinsburskiy 
---
 drivers/connector/cn_proc.c |   28 +++-
 1 file changed, 7 insertions(+), 21 deletions(-)

diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c
index 2d5ff7c..312f30f 100644
--- a/drivers/connector/cn_proc.c
+++ b/drivers/connector/cn_proc.c
@@ -222,31 +222,17 @@ void proc_comm_connector(struct task_struct *task)
proc_event_connector(task, PROC_EVENT_COMM, 0, fill_comm_event);
 }
 
-void proc_coredump_connector(struct task_struct *task)
+static bool fill_coredump_event(struct proc_event *ev, struct task_struct 
*task,
+   int unused)
 {
-   struct cn_msg *msg;
-   struct proc_event *ev;
-   __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
-   struct timespec ts;
-
-   if (atomic_read(_event_num_listeners) < 1)
-   return;
-
-   msg = buffer_to_cn_msg(buffer);
-   ev = (struct proc_event *)msg->data;
-   memset(>event_data, 0, sizeof(ev->event_data));
-   get_seq(>seq, >cpu);
-   ktime_get_ts(); /* get high res monotonic timestamp */
-   ev->timestamp_ns = timespec_to_ns();
-   ev->what = PROC_EVENT_COREDUMP;
ev->event_data.coredump.process_pid = task->pid;
ev->event_data.coredump.process_tgid = task->tgid;
+   return true;
+}
 
-   memcpy(>id, _proc_event_id, sizeof(msg->id));
-   msg->ack = 0; /* not used */
-   msg->len = sizeof(*ev);
-   msg->flags = 0; /* not used */
-   cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
+void proc_coredump_connector(struct task_struct *task)
+{
+   proc_event_connector(task, PROC_EVENT_COREDUMP, 0, fill_coredump_event);
 }
 
 void proc_exit_connector(struct task_struct *task)

___
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel


[Devel] [PATCH v2 25/27] connector: containerize "connector" proc entry

2017-08-17 Thread Stanislav Kinsburskiy
Needed to expose "/proc/net/connector" in CT and show right content.

Signed-off-by: Stanislav Kinsburskiy 
---
 drivers/connector/connector.c |4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c
index 59d81a3..771dadf 100644
--- a/drivers/connector/connector.c
+++ b/drivers/connector/connector.c
@@ -241,7 +241,7 @@ EXPORT_SYMBOL_GPL(cn_del_callback);
 
 static int cn_proc_show(struct seq_file *m, void *v)
 {
-   struct cn_queue_dev *dev = get_cdev(get_ve0())->cbdev;
+   struct cn_queue_dev *dev = get_cdev(get_exec_env())->cbdev;
struct cn_callback_entry *cbq;
 
seq_printf(m, "NameID\n");
@@ -303,7 +303,7 @@ static int cn_init_ve(struct ve_struct *ve)
 
ve->cn->cn_already_initialized = 1;
 
-   if (!proc_create("connector", S_IRUGO, net->proc_net, _file_ops)) {
+   if (!proc_net_create("connector", S_IRUGO, net->proc_net, 
_file_ops)) {
err = -ENOMEM;
goto free_cdev;
}

___
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel


[Devel] [PATCH v2 20/27] proc connector: take number of listeners and per-cpu conters from VE

2017-08-17 Thread Stanislav Kinsburskiy
Instead of static variables.

Signed-off-by: Stanislav Kinsburskiy 
---
 drivers/connector/cn_proc.c |   50 ---
 1 file changed, 32 insertions(+), 18 deletions(-)

diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c
index 7a1124a..ff99f06 100644
--- a/drivers/connector/cn_proc.c
+++ b/drivers/connector/cn_proc.c
@@ -50,21 +50,17 @@ static inline struct cn_msg *buffer_to_cn_msg(__u8 *buffer)
return (struct cn_msg *)(buffer + 4);
 }
 
-static atomic_t proc_event_num_listeners = ATOMIC_INIT(0);
 static struct cb_id cn_proc_event_id = { CN_IDX_PROC, CN_VAL_PROC };
 
-/* proc_event_counts is used as the sequence number of the netlink message */
-static DEFINE_PER_CPU(__u32, proc_event_counts) = { 0 };
-
-static inline void get_seq(__u32 *ts, int *cpu)
+static inline void get_seq(struct ve_struct *ve, __u32 *ts, int *cpu)
 {
preempt_disable();
-   *ts = __this_cpu_inc_return(proc_event_counts) - 1;
+   *ts = __this_cpu_inc_return(*ve->cn->proc_event_counts) - 1;
*cpu = smp_processor_id();
preempt_enable();
 }
 
-static struct cn_msg *cn_msg_fill(__u8 *buffer,
+static struct cn_msg *cn_msg_fill(__u8 *buffer, struct ve_struct *ve,
  struct task_struct *task,
  int what, int cookie,
  bool (*fill_event)(struct proc_event *ev,
@@ -78,7 +74,7 @@ static struct cn_msg *cn_msg_fill(__u8 *buffer,
msg = buffer_to_cn_msg(buffer);
ev = (struct proc_event *)msg->data;
 
-   get_seq(>seq, >cpu);
+   get_seq(ve, >seq, >cpu);
memcpy(>id, _proc_event_id, sizeof(msg->id));
msg->ack = 0; /* not used */
msg->len = sizeof(*ev);
@@ -92,6 +88,13 @@ static struct cn_msg *cn_msg_fill(__u8 *buffer,
return fill_event(ev, task, cookie) ? msg : NULL;
 }
 
+static int proc_event_num_listeners(struct ve_struct *ve)
+{
+   if (ve->cn)
+   return atomic_read(>cn->proc_event_num_listeners);
+   return 0;
+}
+
 static void proc_event_connector(struct task_struct *task,
 int what, int cookie,
 bool (*fill_event)(struct proc_event *ev,
@@ -100,11 +103,12 @@ static void proc_event_connector(struct task_struct *task,
 {
struct cn_msg *msg;
__u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
+   struct ve_struct *ve = task->task_ve;
 
-   if (atomic_read(_event_num_listeners) < 1)
+   if (proc_event_num_listeners(ve) < 1)
return;
 
-   msg = cn_msg_fill(buffer, task, what, cookie, fill_event);
+   msg = cn_msg_fill(buffer, ve, task, what, cookie, fill_event);
if (!msg)
return;
 
@@ -258,14 +262,14 @@ void proc_exit_connector(struct task_struct *task)
  * values because it's not being returned via syscall return
  * mechanisms.
  */
-static void cn_proc_ack(int err, int rcvd_seq, int rcvd_ack)
+static void cn_proc_ack(struct ve_struct *ve, int err, int rcvd_seq, int 
rcvd_ack)
 {
struct cn_msg *msg;
struct proc_event *ev;
__u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
struct timespec ts;
 
-   if (atomic_read(_event_num_listeners) < 1)
+   if (proc_event_num_listeners(ve) < 1)
return;
 
msg = buffer_to_cn_msg(buffer);
@@ -292,6 +296,7 @@ static void cn_proc_mcast_ctl(struct cn_msg *msg,
  struct netlink_skb_parms *nsp)
 {
enum proc_cn_mcast_op *mc_op = NULL;
+   struct ve_struct *ve = get_exec_env();
int err = 0;
 
if (msg->len != sizeof(*mc_op))
@@ -315,10 +320,10 @@ static void cn_proc_mcast_ctl(struct cn_msg *msg,
mc_op = (enum proc_cn_mcast_op *)msg->data;
switch (*mc_op) {
case PROC_CN_MCAST_LISTEN:
-   atomic_inc(_event_num_listeners);
+   atomic_inc(>cn->proc_event_num_listeners);
break;
case PROC_CN_MCAST_IGNORE:
-   atomic_dec(_event_num_listeners);
+   atomic_dec(>cn->proc_event_num_listeners);
break;
default:
err = EINVAL;
@@ -326,22 +331,31 @@ static void cn_proc_mcast_ctl(struct cn_msg *msg,
}
 
 out:
-   cn_proc_ack(err, msg->seq, msg->ack);
+   cn_proc_ack(ve, err, msg->seq, msg->ack);
 }
 
 int cn_proc_init_ve(struct ve_struct *ve)
 {
-   int err = cn_add_callback_ve(ve, _proc_event_id,
-"cn_proc",
-_proc_mcast_ctl);
+   int err;
+
+   ve->cn->proc_event_counts = alloc_percpu(u32);
+   if (!ve->cn->proc_event_counts)
+   return -ENOMEM;
+
+   err = cn_add_callback_ve(ve, _proc_event_id,
+ "cn_proc",
+ _proc_mcast_ctl);
if (err) {
pr_warn("VE#%d: cn_proc failed 

[Devel] [PATCH v2 18/27] proc connector: add per-ve init and fini foutines

2017-08-17 Thread Stanislav Kinsburskiy
These routines will be called from main connecter per-ve init and fini
routines.

Signed-off-by: Stanislav Kinsburskiy 
---
 drivers/connector/cn_proc.c |   17 +
 include/linux/connector.h   |3 +++
 2 files changed, 20 insertions(+)

diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c
index 17a8c8c..8998335 100644
--- a/drivers/connector/cn_proc.c
+++ b/drivers/connector/cn_proc.c
@@ -329,6 +329,23 @@ static void cn_proc_mcast_ctl(struct cn_msg *msg,
cn_proc_ack(err, msg->seq, msg->ack);
 }
 
+int cn_proc_init_ve(struct ve_struct *ve)
+{
+   int err = cn_add_callback_ve(ve, _proc_event_id,
+"cn_proc",
+_proc_mcast_ctl);
+   if (err) {
+   pr_warn("VE#%d: cn_proc failed to register\n", ve->veid);
+   return err;
+   }
+   return 0;
+}
+
+void cn_proc_fini_ve(struct ve_struct *ve)
+{
+   cn_del_callback_ve(ve, _proc_event_id);
+}
+
 /*
  * cn_proc_init - initialization entry point
  *
diff --git a/include/linux/connector.h b/include/linux/connector.h
index 8b44bf0..60eb089 100644
--- a/include/linux/connector.h
+++ b/include/linux/connector.h
@@ -76,6 +76,9 @@ struct cn_private {
 
 };
 
+int cn_proc_init_ve(struct ve_struct *ve);
+void cn_proc_fini_ve(struct ve_struct *ve);
+
 int cn_add_callback_ve(struct ve_struct *ve,
   struct cb_id *id, const char *name,
   void (*callback)(struct cn_msg *,

___
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel


[Devel] [PATCH v2 24/27] proc connector: send events to both VEs if not in VE#0

2017-08-17 Thread Stanislav Kinsburskiy
This is needed to preserve current behaviour, when process in initial pid and
user namespaces (i.e. in VE#0) can receive events from all the processes in
the system.

Signed-off-by: Stanislav Kinsburskiy 
---
 drivers/connector/cn_proc.c |   29 ++---
 1 file changed, 22 insertions(+), 7 deletions(-)

diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c
index 17e0247..81f2e56 100644
--- a/drivers/connector/cn_proc.c
+++ b/drivers/connector/cn_proc.c
@@ -96,16 +96,16 @@ static int proc_event_num_listeners(struct ve_struct *ve)
return 0;
 }
 
-static void proc_event_connector(struct task_struct *task,
-int what, int cookie,
-bool (*fill_event)(struct proc_event *ev,
-   struct ve_struct *ve,
-   struct task_struct *task,
-   int cookie))
+static void proc_event_connector_ve(struct task_struct *task,
+   struct ve_struct *ve,
+   int what, int cookie,
+   bool (*fill_event)(struct proc_event *ev,
+  struct ve_struct *ve,
+  struct task_struct *task,
+  int cookie))
 {
struct cn_msg *msg;
__u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
-   struct ve_struct *ve = task->task_ve;
 
if (proc_event_num_listeners(ve) < 1)
return;
@@ -118,6 +118,21 @@ static void proc_event_connector(struct task_struct *task,
cn_netlink_send_ve(ve, msg, CN_IDX_PROC, GFP_KERNEL);
 }
 
+static void proc_event_connector(struct task_struct *task,
+int what, int cookie,
+bool (*fill_event)(struct proc_event *ev,
+   struct ve_struct *ve,
+   struct task_struct *task,
+   int cookie))
+{
+   struct ve_struct *ve = task->task_ve;
+
+   if (!ve_is_super(ve))
+   proc_event_connector_ve(task, ve, what, cookie, fill_event);
+
+   proc_event_connector_ve(task, get_ve0(), what, cookie, fill_event);
+}
+
 static bool fill_fork_event(struct proc_event *ev, struct ve_struct *ve,
struct task_struct *task, int unused)
 {

___
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel


[Devel] [PATCH v2 17/27] proc connector: add pid namespace awareness

2017-08-17 Thread Stanislav Kinsburskiy
This is precursor patch. Later VE pid ns will be used.

Signed-off-by: Stanislav Kinsburskiy 
---
 drivers/connector/cn_proc.c |   40 
 1 file changed, 20 insertions(+), 20 deletions(-)

diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c
index 4ee1640..17a8c8c 100644
--- a/drivers/connector/cn_proc.c
+++ b/drivers/connector/cn_proc.c
@@ -119,11 +119,11 @@ static bool fill_fork_event(struct proc_event *ev, struct 
task_struct *task,
 
rcu_read_lock();
parent = rcu_dereference(task->real_parent);
-   ev->event_data.fork.parent_pid = parent->pid;
-   ev->event_data.fork.parent_tgid = parent->tgid;
+   ev->event_data.fork.parent_pid = task_pid_nr_ns(parent, _pid_ns);
+   ev->event_data.fork.parent_tgid = task_tgid_nr_ns(parent, _pid_ns);
rcu_read_unlock();
-   ev->event_data.fork.child_pid = task->pid;
-   ev->event_data.fork.child_tgid = task->tgid;
+   ev->event_data.fork.child_pid = task_pid_nr_ns(task, _pid_ns);
+   ev->event_data.fork.child_tgid = task_tgid_nr_ns(task, _pid_ns);
return true;
 }
 
@@ -135,8 +135,8 @@ void proc_fork_connector(struct task_struct *task)
 static bool fill_exec_event(struct proc_event *ev, struct task_struct *task,
int unused)
 {
-   ev->event_data.exec.process_pid = task->pid;
-   ev->event_data.exec.process_tgid = task->tgid;
+   ev->event_data.exec.process_pid = task_pid_nr_ns(task, _pid_ns);
+   ev->event_data.exec.process_tgid = task_tgid_nr_ns(task, _pid_ns);
return true;
 }
 
@@ -150,8 +150,8 @@ static bool fill_id_event(struct proc_event *ev, struct 
task_struct *task,
 {
const struct cred *cred;
 
-   ev->event_data.id.process_pid = task->pid;
-   ev->event_data.id.process_tgid = task->tgid;
+   ev->event_data.id.process_pid = task_pid_nr_ns(task, _pid_ns);
+   ev->event_data.id.process_tgid = task_tgid_nr_ns(task, _pid_ns);
rcu_read_lock();
cred = __task_cred(task);
if (which_id == PROC_EVENT_UID) {
@@ -176,8 +176,8 @@ void proc_id_connector(struct task_struct *task, int 
which_id)
 static bool fill_sid_event(struct proc_event *ev, struct task_struct *task,
   int unused)
 {
-   ev->event_data.sid.process_pid = task->pid;
-   ev->event_data.sid.process_tgid = task->tgid;
+   ev->event_data.sid.process_pid = task_pid_nr_ns(task, _pid_ns);
+   ev->event_data.sid.process_tgid = task_tgid_nr_ns(task, _pid_ns);
return true;
 }
 
@@ -189,11 +189,11 @@ void proc_sid_connector(struct task_struct *task)
 static bool fill_ptrace_event(struct proc_event *ev, struct task_struct *task,
   int ptrace_id)
 {
-   ev->event_data.ptrace.process_pid  = task->pid;
-   ev->event_data.ptrace.process_tgid = task->tgid;
+   ev->event_data.ptrace.process_pid  = task_pid_nr_ns(task, _pid_ns);
+   ev->event_data.ptrace.process_tgid = task_tgid_nr_ns(task, 
_pid_ns);
if (ptrace_id == PTRACE_ATTACH) {
-   ev->event_data.ptrace.tracer_pid  = current->pid;
-   ev->event_data.ptrace.tracer_tgid = current->tgid;
+   ev->event_data.ptrace.tracer_pid  = task_pid_nr_ns(current, 
_pid_ns);
+   ev->event_data.ptrace.tracer_tgid = task_tgid_nr_ns(current, 
_pid_ns);
} else if (ptrace_id == PTRACE_DETACH) {
ev->event_data.ptrace.tracer_pid  = 0;
ev->event_data.ptrace.tracer_tgid = 0;
@@ -211,8 +211,8 @@ void proc_ptrace_connector(struct task_struct *task, int 
ptrace_id)
 static bool fill_comm_event(struct proc_event *ev, struct task_struct *task,
int unused)
 {
-   ev->event_data.comm.process_pid  = task->pid;
-   ev->event_data.comm.process_tgid = task->tgid;
+   ev->event_data.comm.process_pid  = task_pid_nr_ns(task, _pid_ns);
+   ev->event_data.comm.process_tgid = task_tgid_nr_ns(task, _pid_ns);
get_task_comm(ev->event_data.comm.comm, task);
return true;
 }
@@ -225,8 +225,8 @@ void proc_comm_connector(struct task_struct *task)
 static bool fill_coredump_event(struct proc_event *ev, struct task_struct 
*task,
int unused)
 {
-   ev->event_data.coredump.process_pid = task->pid;
-   ev->event_data.coredump.process_tgid = task->tgid;
+   ev->event_data.coredump.process_pid = task_pid_nr_ns(task, 
_pid_ns);
+   ev->event_data.coredump.process_tgid = task_tgid_nr_ns(task, 
_pid_ns);
return true;
 }
 
@@ -238,8 +238,8 @@ void proc_coredump_connector(struct task_struct *task)
 static bool fill_exit_event(struct proc_event *ev, struct task_struct *task,
int unused)
 {
-   ev->event_data.exit.process_pid = task->pid;
-   ev->event_data.exit.process_tgid = task->tgid;
+   ev->event_data.exit.process_pid = task_pid_nr_ns(task, 

[Devel] [PATCH v2 16/27] proc connector: use generic event helper for exit event

2017-08-17 Thread Stanislav Kinsburskiy
Signed-off-by: Stanislav Kinsburskiy 
---
 drivers/connector/cn_proc.c |   28 +++-
 1 file changed, 7 insertions(+), 21 deletions(-)

diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c
index 312f30f..4ee1640 100644
--- a/drivers/connector/cn_proc.c
+++ b/drivers/connector/cn_proc.c
@@ -235,33 +235,19 @@ void proc_coredump_connector(struct task_struct *task)
proc_event_connector(task, PROC_EVENT_COREDUMP, 0, fill_coredump_event);
 }
 
-void proc_exit_connector(struct task_struct *task)
+static bool fill_exit_event(struct proc_event *ev, struct task_struct *task,
+   int unused)
 {
-   struct cn_msg *msg;
-   struct proc_event *ev;
-   __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
-   struct timespec ts;
-
-   if (atomic_read(_event_num_listeners) < 1)
-   return;
-
-   msg = buffer_to_cn_msg(buffer);
-   ev = (struct proc_event *)msg->data;
-   memset(>event_data, 0, sizeof(ev->event_data));
-   get_seq(>seq, >cpu);
-   ktime_get_ts(); /* get high res monotonic timestamp */
-   ev->timestamp_ns = timespec_to_ns();
-   ev->what = PROC_EVENT_EXIT;
ev->event_data.exit.process_pid = task->pid;
ev->event_data.exit.process_tgid = task->tgid;
ev->event_data.exit.exit_code = task->exit_code;
ev->event_data.exit.exit_signal = task->exit_signal;
+   return true;
+}
 
-   memcpy(>id, _proc_event_id, sizeof(msg->id));
-   msg->ack = 0; /* not used */
-   msg->len = sizeof(*ev);
-   msg->flags = 0; /* not used */
-   cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
+void proc_exit_connector(struct task_struct *task)
+{
+   proc_event_connector(task, PROC_EVENT_EXIT, 0, fill_exit_event);
 }
 
 /*

___
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel


[Devel] [PATCH v2 03/27] connector: introduce VE-aware get_cdev() helper

2017-08-17 Thread Stanislav Kinsburskiy
Once containerized, device won't be one and for all.
Thus make a helper template and use it instead of direct device object access.
Use ve0 for now.

Signed-off-by: Stanislav Kinsburskiy 
---
 drivers/connector/connector.c |   20 +---
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c
index da26064..407fe52 100644
--- a/drivers/connector/connector.c
+++ b/drivers/connector/connector.c
@@ -63,6 +63,12 @@ static int cn_already_initialized;
  * a new message.
  *
  */
+
+static struct cn_dev *get_cdev(struct ve_struct *ve)
+{
+   return 
+}
+
 int cn_netlink_send(struct cn_msg *msg, u32 __group, gfp_t gfp_mask)
 {
struct cn_callback_entry *__cbq;
@@ -70,7 +76,7 @@ int cn_netlink_send(struct cn_msg *msg, u32 __group, gfp_t 
gfp_mask)
struct sk_buff *skb;
struct nlmsghdr *nlh;
struct cn_msg *data;
-   struct cn_dev *dev = 
+   struct cn_dev *dev = get_cdev(get_ve0());
u32 group = 0;
int found = 0;
 
@@ -123,7 +129,7 @@ EXPORT_SYMBOL_GPL(cn_netlink_send);
 static int cn_call_callback(struct sk_buff *skb)
 {
struct cn_callback_entry *i, *cbq = NULL;
-   struct cn_dev *dev = 
+   struct cn_dev *dev = get_cdev(get_ve0());
struct cn_msg *msg = nlmsg_data(nlmsg_hdr(skb));
struct netlink_skb_parms *nsp = _CB(skb);
int err = -ENODEV;
@@ -190,7 +196,7 @@ int cn_add_callback(struct cb_id *id, const char *name,
 struct netlink_skb_parms *))
 {
int err;
-   struct cn_dev *dev = 
+   struct cn_dev *dev = get_cdev(get_ve0());
 
if (!cn_already_initialized)
return -EAGAIN;
@@ -213,7 +219,7 @@ EXPORT_SYMBOL_GPL(cn_add_callback);
  */
 void cn_del_callback(struct cb_id *id)
 {
-   struct cn_dev *dev = 
+   struct cn_dev *dev = get_cdev(get_ve0());
 
cn_queue_del_callback(dev->cbdev, id);
 }
@@ -221,7 +227,7 @@ EXPORT_SYMBOL_GPL(cn_del_callback);
 
 static int cn_proc_show(struct seq_file *m, void *v)
 {
-   struct cn_queue_dev *dev = cdev.cbdev;
+   struct cn_queue_dev *dev = get_cdev(get_ve0())->cbdev;
struct cn_callback_entry *cbq;
 
seq_printf(m, "NameID\n");
@@ -255,7 +261,7 @@ static const struct file_operations cn_file_ops = {
 
 static int cn_init(void)
 {
-   struct cn_dev *dev = 
+   struct cn_dev *dev = get_cdev(get_ve0());
struct netlink_kernel_cfg cfg = {
.groups = CN_NETLINK_USERS + 0xf,
.input  = cn_rx_skb,
@@ -280,7 +286,7 @@ static int cn_init(void)
 
 static void cn_fini(void)
 {
-   struct cn_dev *dev = 
+   struct cn_dev *dev = get_cdev(get_ve0());
 
cn_already_initialized = 0;
 

___
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel


[Devel] [PATCH v2 19/27] proc connector: call proc-related init and fini routines explicitly

2017-08-17 Thread Stanislav Kinsburskiy
This allows to support per-container connector creation and destruction.

Signed-off-by: Stanislav Kinsburskiy 
---
 drivers/connector/cn_proc.c   |   19 ---
 drivers/connector/connector.c |   33 -
 2 files changed, 28 insertions(+), 24 deletions(-)

diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c
index 8998335..7a1124a 100644
--- a/drivers/connector/cn_proc.c
+++ b/drivers/connector/cn_proc.c
@@ -345,22 +345,3 @@ void cn_proc_fini_ve(struct ve_struct *ve)
 {
cn_del_callback_ve(ve, _proc_event_id);
 }
-
-/*
- * cn_proc_init - initialization entry point
- *
- * Adds the connector callback to the connector driver.
- */
-static int __init cn_proc_init(void)
-{
-   int err = cn_add_callback(_proc_event_id,
- "cn_proc",
- _proc_mcast_ctl);
-   if (err) {
-   pr_warn("cn_proc failed to register\n");
-   return err;
-   }
-   return 0;
-}
-
-module_init(cn_proc_init);
diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c
index 110637b..59d81a3 100644
--- a/drivers/connector/connector.c
+++ b/drivers/connector/connector.c
@@ -281,6 +281,7 @@ static int cn_init_ve(struct ve_struct *ve)
.input  = cn_rx_skb,
};
struct net *net = ve->ve_netns;
+   int err;
 
ve->cn = kzalloc(sizeof(*ve->cn), GFP_KERNEL);
if (!ve->cn)
@@ -289,20 +290,40 @@ static int cn_init_ve(struct ve_struct *ve)
dev = >cn->cdev;
 
dev->nls = netlink_kernel_create(net, NETLINK_CONNECTOR, );
-   if (!dev->nls)
-   return -EIO;
+   if (!dev->nls) {
+   err = -EIO;
+   goto free_cn;
+   }
 
dev->cbdev = cn_queue_alloc_dev("cqueue", dev->nls);
if (!dev->cbdev) {
-   netlink_kernel_release(dev->nls);
-   return -EINVAL;
+   err = -EINVAL;
+   goto netlink_release;
}
 
ve->cn->cn_already_initialized = 1;
 
-   proc_create("connector", S_IRUGO, net->proc_net, _file_ops);
+   if (!proc_create("connector", S_IRUGO, net->proc_net, _file_ops)) {
+   err = -ENOMEM;
+   goto free_cdev;
+   }
+
+   err = cn_proc_init_ve(ve);
+   if (err)
+   goto remove_proc;
 
return 0;
+
+remove_proc:
+   remove_proc_entry("connector", net->proc_net);
+free_cdev:
+   cn_queue_free_dev(dev->cbdev);
+netlink_release:
+   netlink_kernel_release(dev->nls);
+free_cn:
+   kfree(ve->cn);
+   ve->cn = NULL;
+   return err;
 }
 
 static void cn_fini_ve(struct ve_struct *ve)
@@ -312,6 +333,8 @@ static void cn_fini_ve(struct ve_struct *ve)
 
ve->cn->cn_already_initialized = 0;
 
+   cn_proc_fini_ve(ve);
+
remove_proc_entry("connector", net->proc_net);
 
cn_queue_free_dev(dev->cbdev);

___
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel


[Devel] [PATCH v2 06/27] connector: per-ve helpers intoruduced

2017-08-17 Thread Stanislav Kinsburskiy
This is precursor patch.

Signed-off-by: Stanislav Kinsburskiy 
---
 drivers/connector/connector.c |   48 -
 include/linux/connector.h |7 ++
 2 files changed, 40 insertions(+), 15 deletions(-)

diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c
index bc2308a..bba667d 100644
--- a/drivers/connector/connector.c
+++ b/drivers/connector/connector.c
@@ -67,14 +67,14 @@ static struct cn_dev *get_cdev(struct ve_struct *ve)
return >cn->cdev;
 }
 
-int cn_netlink_send(struct cn_msg *msg, u32 __group, gfp_t gfp_mask)
+int cn_netlink_send_ve(struct ve_struct *ve, struct cn_msg *msg, u32 __group, 
gfp_t gfp_mask)
 {
struct cn_callback_entry *__cbq;
unsigned int size;
struct sk_buff *skb;
struct nlmsghdr *nlh;
struct cn_msg *data;
-   struct cn_dev *dev = get_cdev(get_ve0());
+   struct cn_dev *dev = get_cdev(ve);
u32 group = 0;
int found = 0;
 
@@ -119,6 +119,11 @@ int cn_netlink_send(struct cn_msg *msg, u32 __group, gfp_t 
gfp_mask)
 
return netlink_broadcast(dev->nls, skb, 0, group, gfp_mask);
 }
+
+int cn_netlink_send(struct cn_msg *msg, u32 __group, gfp_t gfp_mask)
+{
+   return cn_netlink_send_ve(get_ve0(), msg, __group, gfp_mask);
+}
 EXPORT_SYMBOL_GPL(cn_netlink_send);
 
 /*
@@ -183,18 +188,13 @@ static void cn_rx_skb(struct sk_buff *__skb)
}
 }
 
-/*
- * Callback add routing - adds callback with given ID and name.
- * If there is registered callback with the same ID it will not be added.
- *
- * May sleep.
- */
-int cn_add_callback(struct cb_id *id, const char *name,
-   void (*callback)(struct cn_msg *,
-struct netlink_skb_parms *))
+int cn_add_callback_ve(struct ve_struct *ve,
+  struct cb_id *id, const char *name,
+  void (*callback)(struct cn_msg *,
+   struct netlink_skb_parms *))
 {
int err;
-   struct cn_dev *dev = get_cdev(get_ve0());
+   struct cn_dev *dev = get_cdev(ve);
 
if (!cn_already_initialized)
return -EAGAIN;
@@ -205,8 +205,28 @@ int cn_add_callback(struct cb_id *id, const char *name,
 
return 0;
 }
+
+/*
+ * Callback add routing - adds callback with given ID and name.
+ * If there is registered callback with the same ID it will not be added.
+ *
+ * May sleep.
+ */
+int cn_add_callback(struct cb_id *id, const char *name,
+   void (*callback)(struct cn_msg *,
+struct netlink_skb_parms *))
+{
+   return cn_add_callback_ve(get_ve0(), id, name, callback);
+}
 EXPORT_SYMBOL_GPL(cn_add_callback);
 
+void cn_del_callback_ve(struct ve_struct *ve, struct cb_id *id)
+{
+   struct cn_dev *dev = get_cdev(ve);
+
+   cn_queue_del_callback(dev->cbdev, id);
+}
+
 /*
  * Callback remove routing - removes callback
  * with given ID.
@@ -217,9 +237,7 @@ EXPORT_SYMBOL_GPL(cn_add_callback);
  */
 void cn_del_callback(struct cb_id *id)
 {
-   struct cn_dev *dev = get_cdev(get_ve0());
-
-   cn_queue_del_callback(dev->cbdev, id);
+   cn_del_callback_ve(get_ve0(), id);
 }
 EXPORT_SYMBOL_GPL(cn_del_callback);
 
diff --git a/include/linux/connector.h b/include/linux/connector.h
index 9e05e28..8b44bf0 100644
--- a/include/linux/connector.h
+++ b/include/linux/connector.h
@@ -76,6 +76,13 @@ struct cn_private {
 
 };
 
+int cn_add_callback_ve(struct ve_struct *ve,
+  struct cb_id *id, const char *name,
+  void (*callback)(struct cn_msg *,
+   struct netlink_skb_parms *));
+void cn_del_callback_ve(struct ve_struct *ve, struct cb_id *id);
+int cn_netlink_send_ve(struct ve_struct *ve, struct cn_msg *, u32, gfp_t);
+
 int cn_add_callback(struct cb_id *id, const char *name,
void (*callback)(struct cn_msg *, struct netlink_skb_parms 
*));
 void cn_del_callback(struct cb_id *);

___
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel


[Devel] [PATCH v2 11/27] proc connector: use generic event helper for id event

2017-08-17 Thread Stanislav Kinsburskiy
Signed-off-by: Stanislav Kinsburskiy 
---
 drivers/connector/cn_proc.c |   29 -
 1 file changed, 8 insertions(+), 21 deletions(-)

diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c
index 06fd6b3..0647fcf 100644
--- a/drivers/connector/cn_proc.c
+++ b/drivers/connector/cn_proc.c
@@ -145,21 +145,11 @@ void proc_exec_connector(struct task_struct *task)
proc_event_connector(task, PROC_EVENT_EXEC, 0, fill_exec_event);
 }
 
-void proc_id_connector(struct task_struct *task, int which_id)
+static bool fill_id_event(struct proc_event *ev, struct task_struct *task,
+ int which_id)
 {
-   struct cn_msg *msg;
-   struct proc_event *ev;
-   __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
-   struct timespec ts;
const struct cred *cred;
 
-   if (atomic_read(_event_num_listeners) < 1)
-   return;
-
-   msg = buffer_to_cn_msg(buffer);
-   ev = (struct proc_event *)msg->data;
-   memset(>event_data, 0, sizeof(ev->event_data));
-   ev->what = which_id;
ev->event_data.id.process_pid = task->pid;
ev->event_data.id.process_tgid = task->tgid;
rcu_read_lock();
@@ -172,18 +162,15 @@ void proc_id_connector(struct task_struct *task, int 
which_id)
ev->event_data.id.e.egid = from_kgid_munged(_user_ns, 
cred->egid);
} else {
rcu_read_unlock();
-   return;
+   return false;
}
rcu_read_unlock();
-   get_seq(>seq, >cpu);
-   ktime_get_ts(); /* get high res monotonic timestamp */
-   ev->timestamp_ns = timespec_to_ns();
+   return true;
+}
 
-   memcpy(>id, _proc_event_id, sizeof(msg->id));
-   msg->ack = 0; /* not used */
-   msg->len = sizeof(*ev);
-   msg->flags = 0; /* not used */
-   cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
+void proc_id_connector(struct task_struct *task, int which_id)
+{
+   proc_event_connector(task, which_id, which_id, fill_id_event);
 }
 
 void proc_sid_connector(struct task_struct *task)

___
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel


[Devel] [PATCH v2 09/27] proc connector: use generic event helper for fork event

2017-08-17 Thread Stanislav Kinsburskiy
Signed-off-by: Stanislav Kinsburskiy 
---
 drivers/connector/cn_proc.c |   30 +++---
 1 file changed, 7 insertions(+), 23 deletions(-)

diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c
index 808b22a..ffda79b 100644
--- a/drivers/connector/cn_proc.c
+++ b/drivers/connector/cn_proc.c
@@ -112,26 +112,11 @@ static void proc_event_connector(struct task_struct *task,
cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
 }
 
-void proc_fork_connector(struct task_struct *task)
+static bool fill_fork_event(struct proc_event *ev, struct task_struct *task,
+   int unused)
 {
-   struct cn_msg *msg;
-   struct proc_event *ev;
-   __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
-   struct timespec ts;
struct task_struct *parent;
 
-   (void) proc_event_connector;
-
-   if (atomic_read(_event_num_listeners) < 1)
-   return;
-
-   msg = buffer_to_cn_msg(buffer);
-   ev = (struct proc_event *)msg->data;
-   memset(>event_data, 0, sizeof(ev->event_data));
-   get_seq(>seq, >cpu);
-   ktime_get_ts(); /* get high res monotonic timestamp */
-   ev->timestamp_ns = timespec_to_ns();
-   ev->what = PROC_EVENT_FORK;
rcu_read_lock();
parent = rcu_dereference(task->real_parent);
ev->event_data.fork.parent_pid = parent->pid;
@@ -139,13 +124,12 @@ void proc_fork_connector(struct task_struct *task)
rcu_read_unlock();
ev->event_data.fork.child_pid = task->pid;
ev->event_data.fork.child_tgid = task->tgid;
+   return true;
+}
 
-   memcpy(>id, _proc_event_id, sizeof(msg->id));
-   msg->ack = 0; /* not used */
-   msg->len = sizeof(*ev);
-   msg->flags = 0; /* not used */
-   /*  If cn_netlink_send() failed, the data is not sent */
-   cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
+void proc_fork_connector(struct task_struct *task)
+{
+   proc_event_connector(task, PROC_EVENT_FORK, 0, fill_fork_event);
 }
 
 void proc_exec_connector(struct task_struct *task)

___
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel


[Devel] [PATCH v2 12/27] proc connector: use generic event helper for sid event

2017-08-17 Thread Stanislav Kinsburskiy
Signed-off-by: Stanislav Kinsburskiy 
---
 drivers/connector/cn_proc.c |   28 +++-
 1 file changed, 7 insertions(+), 21 deletions(-)

diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c
index 0647fcf..2ad2587 100644
--- a/drivers/connector/cn_proc.c
+++ b/drivers/connector/cn_proc.c
@@ -173,31 +173,17 @@ void proc_id_connector(struct task_struct *task, int 
which_id)
proc_event_connector(task, which_id, which_id, fill_id_event);
 }
 
-void proc_sid_connector(struct task_struct *task)
+static bool fill_sid_event(struct proc_event *ev, struct task_struct *task,
+  int unused)
 {
-   struct cn_msg *msg;
-   struct proc_event *ev;
-   struct timespec ts;
-   __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
-
-   if (atomic_read(_event_num_listeners) < 1)
-   return;
-
-   msg = buffer_to_cn_msg(buffer);
-   ev = (struct proc_event *)msg->data;
-   memset(>event_data, 0, sizeof(ev->event_data));
-   get_seq(>seq, >cpu);
-   ktime_get_ts(); /* get high res monotonic timestamp */
-   ev->timestamp_ns = timespec_to_ns();
-   ev->what = PROC_EVENT_SID;
ev->event_data.sid.process_pid = task->pid;
ev->event_data.sid.process_tgid = task->tgid;
+   return true;
+}
 
-   memcpy(>id, _proc_event_id, sizeof(msg->id));
-   msg->ack = 0; /* not used */
-   msg->len = sizeof(*ev);
-   msg->flags = 0; /* not used */
-   cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
+void proc_sid_connector(struct task_struct *task)
+{
+   proc_event_connector(task, PROC_EVENT_SID, 0, fill_sid_event);
 }
 
 void proc_ptrace_connector(struct task_struct *task, int ptrace_id)

___
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel


[Devel] [PATCH v2 02/27] connector: store all private data on VE structure

2017-08-17 Thread Stanislav Kinsburskiy
This is needed to containerize connector and its proc part.

Signed-off-by: Stanislav Kinsburskiy 
---
 include/linux/connector.h |9 +
 include/linux/ve.h|4 
 2 files changed, 13 insertions(+)

diff --git a/include/linux/connector.h b/include/linux/connector.h
index 4c4d2b9..9e05e28 100644
--- a/include/linux/connector.h
+++ b/include/linux/connector.h
@@ -67,6 +67,15 @@ struct cn_dev {
struct cn_queue_dev *cbdev;
 };
 
+struct cn_private {
+   struct cn_dev   cdev;
+   int cn_already_initialized;
+
+   atomic_tproc_event_num_listeners;
+   u32 __percpu*proc_event_counts;
+
+};
+
 int cn_add_callback(struct cb_id *id, const char *name,
void (*callback)(struct cn_msg *, struct netlink_skb_parms 
*));
 void cn_del_callback(struct cb_id *);
diff --git a/include/linux/ve.h b/include/linux/ve.h
index c9b0af4..d63edee 100644
--- a/include/linux/ve.h
+++ b/include/linux/ve.h
@@ -30,6 +30,7 @@ struct file_system_type;
 struct veip_struct;
 struct nsproxy;
 struct user_namespace;
+struct cn_private;
 extern struct user_namespace init_user_ns;
 
 struct ve_struct {
@@ -123,6 +124,9 @@ struct ve_struct {
 #ifdef CONFIG_COREDUMP
charcore_pattern[CORENAME_MAX_SIZE];
 #endif
+#ifdef CONFIG_CONNECTOR
+   struct cn_private   *cn;
+#endif
 };
 
 struct ve_devmnt {

___
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel


[Devel] [PATCH v2 08/27] proc connector: generic proc_event_connector() helper introduced

2017-08-17 Thread Stanislav Kinsburskiy
A lot of code is duplicated in proc connector events handling.
This patch introduces generic even handler, which will be used by different
events.

Signed-off-by: Stanislav Kinsburskiy 
---
 drivers/connector/cn_proc.c |   50 +++
 1 file changed, 50 insertions(+)

diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c
index 3165811..808b22a 100644
--- a/drivers/connector/cn_proc.c
+++ b/drivers/connector/cn_proc.c
@@ -64,6 +64,54 @@ static inline void get_seq(__u32 *ts, int *cpu)
preempt_enable();
 }
 
+static struct cn_msg *cn_msg_fill(__u8 *buffer,
+ struct task_struct *task,
+ int what, int cookie,
+ bool (*fill_event)(struct proc_event *ev,
+struct task_struct *task,
+int cookie))
+{
+   struct cn_msg *msg;
+   struct proc_event *ev;
+   struct timespec ts;
+
+   msg = buffer_to_cn_msg(buffer);
+   ev = (struct proc_event *)msg->data;
+
+   get_seq(>seq, >cpu);
+   memcpy(>id, _proc_event_id, sizeof(msg->id));
+   msg->ack = 0; /* not used */
+   msg->len = sizeof(*ev);
+   msg->flags = 0; /* not used */
+
+   memset(>event_data, 0, sizeof(ev->event_data));
+   ktime_get_ts(); /* get high res monotonic timestamp */
+   ev->timestamp_ns = timespec_to_ns();
+   ev->what = what;
+
+   return fill_event(ev, task, cookie) ? msg : NULL;
+}
+
+static void proc_event_connector(struct task_struct *task,
+int what, int cookie,
+bool (*fill_event)(struct proc_event *ev,
+   struct task_struct *task,
+   int cookie))
+{
+   struct cn_msg *msg;
+   __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
+
+   if (atomic_read(_event_num_listeners) < 1)
+   return;
+
+   msg = cn_msg_fill(buffer, task, what, cookie, fill_event);
+   if (!msg)
+   return;
+
+   /*  If cn_netlink_send() failed, the data is not sent */
+   cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
+}
+
 void proc_fork_connector(struct task_struct *task)
 {
struct cn_msg *msg;
@@ -72,6 +120,8 @@ void proc_fork_connector(struct task_struct *task)
struct timespec ts;
struct task_struct *parent;
 
+   (void) proc_event_connector;
+
if (atomic_read(_event_num_listeners) < 1)
return;
 

___
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel


[Devel] [PATCH v2 01/27] connector: remove redundant input callback from cn_dev

2017-08-17 Thread Stanislav Kinsburskiy
A small cleanup: this callback is never used.

Signed-off-by: Stanislav Kinsburskiy 
---
 drivers/connector/connector.c |6 +-
 include/linux/connector.h |1 -
 2 files changed, 1 insertion(+), 6 deletions(-)

diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c
index 0daa11e..da26064 100644
--- a/drivers/connector/connector.c
+++ b/drivers/connector/connector.c
@@ -253,16 +253,12 @@ static const struct file_operations cn_file_ops = {
.release = single_release
 };
 
-static struct cn_dev cdev = {
-   .input   = cn_rx_skb,
-};
-
 static int cn_init(void)
 {
struct cn_dev *dev = 
struct netlink_kernel_cfg cfg = {
.groups = CN_NETLINK_USERS + 0xf,
-   .input  = dev->input,
+   .input  = cn_rx_skb,
};
 
dev->nls = netlink_kernel_create(_net, NETLINK_CONNECTOR, );
diff --git a/include/linux/connector.h b/include/linux/connector.h
index b2b5a41..4c4d2b9 100644
--- a/include/linux/connector.h
+++ b/include/linux/connector.h
@@ -63,7 +63,6 @@ struct cn_dev {
 
u32 seq, groups;
struct sock *nls;
-   void (*input) (struct sk_buff *skb);
 
struct cn_queue_dev *cbdev;
 };

___
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel


[Devel] [PATCH v2 04/27] connector: per-ve init and fini helpers introduced

2017-08-17 Thread Stanislav Kinsburskiy
This helpers will be used later to initialize per-container connector.

Signed-off-by: Stanislav Kinsburskiy 
---
 drivers/connector/connector.c |   31 +--
 1 file changed, 25 insertions(+), 6 deletions(-)

diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c
index 407fe52..f5484b2 100644
--- a/drivers/connector/connector.c
+++ b/drivers/connector/connector.c
@@ -259,15 +259,20 @@ static const struct file_operations cn_file_ops = {
.release = single_release
 };
 
-static int cn_init(void)
+static int cn_init_ve(struct ve_struct *ve)
 {
struct cn_dev *dev = get_cdev(get_ve0());
struct netlink_kernel_cfg cfg = {
.groups = CN_NETLINK_USERS + 0xf,
.input  = cn_rx_skb,
};
+   struct net *net = ve->ve_netns;
+
+   ve->cn = kzalloc(sizeof(*ve->cn), GFP_KERNEL);
+   if (!ve->cn)
+   return -ENOMEM;
 
-   dev->nls = netlink_kernel_create(_net, NETLINK_CONNECTOR, );
+   dev->nls = netlink_kernel_create(net, NETLINK_CONNECTOR, );
if (!dev->nls)
return -EIO;
 
@@ -279,21 +284,35 @@ static int cn_init(void)
 
cn_already_initialized = 1;
 
-   proc_create("connector", S_IRUGO, init_net.proc_net, _file_ops);
+   proc_create("connector", S_IRUGO, net->proc_net, _file_ops);
 
return 0;
 }
 
-static void cn_fini(void)
+static void cn_fini_ve(struct ve_struct *ve)
 {
-   struct cn_dev *dev = get_cdev(get_ve0());
+   struct cn_dev *dev = get_cdev(ve);
+   struct net *net = ve->ve_netns;
 
cn_already_initialized = 0;
 
-   remove_proc_entry("connector", init_net.proc_net);
+   remove_proc_entry("connector", net->proc_net);
 
cn_queue_free_dev(dev->cbdev);
netlink_kernel_release(dev->nls);
+
+   kfree(ve->cn);
+   ve->cn = NULL;
+}
+
+static int cn_init(void)
+{
+   return cn_init_ve(get_ve0());
+}
+
+static void cn_fini(void)
+{
+   return cn_fini_ve(get_ve0());
 }
 
 subsys_initcall(cn_init);

___
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel


[Devel] [PATCH v2 05/27] connector: use device stored in VE

2017-08-17 Thread Stanislav Kinsburskiy
Instead of global static device.

Signed-off-by: Stanislav Kinsburskiy 
---
 drivers/connector/connector.c |8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c
index f5484b2..bc2308a 100644
--- a/drivers/connector/connector.c
+++ b/drivers/connector/connector.c
@@ -38,8 +38,6 @@ MODULE_AUTHOR("Evgeniy Polyakov ");
 MODULE_DESCRIPTION("Generic userspace <-> kernelspace connector.");
 MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_CONNECTOR);
 
-static struct cn_dev cdev;
-
 static int cn_already_initialized;
 
 /*
@@ -66,7 +64,7 @@ static int cn_already_initialized;
 
 static struct cn_dev *get_cdev(struct ve_struct *ve)
 {
-   return 
+   return >cn->cdev;
 }
 
 int cn_netlink_send(struct cn_msg *msg, u32 __group, gfp_t gfp_mask)
@@ -261,7 +259,7 @@ static const struct file_operations cn_file_ops = {
 
 static int cn_init_ve(struct ve_struct *ve)
 {
-   struct cn_dev *dev = get_cdev(get_ve0());
+   struct cn_dev *dev;
struct netlink_kernel_cfg cfg = {
.groups = CN_NETLINK_USERS + 0xf,
.input  = cn_rx_skb,
@@ -272,6 +270,8 @@ static int cn_init_ve(struct ve_struct *ve)
if (!ve->cn)
return -ENOMEM;
 
+   dev = >cn->cdev;
+
dev->nls = netlink_kernel_create(net, NETLINK_CONNECTOR, );
if (!dev->nls)
return -EIO;

___
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel


[Devel] [PATCH v2 00/27] proc connector: containerize on per-VE basis

2017-08-17 Thread Stanislav Kinsburskiy
This feature is requested by customer and needed by cgred service.

https://jira.sw.ru/browse/PSBM-60227

What's ne in v2:
1) Containerization is done on per-VE basis
2) Event in container is also sent to VE#0


---

Stanislav Kinsburskiy (27):
  connector: remove redundant input callback from cn_dev
  connector: store all private data on VE structure
  connector: introduce VE-aware get_cdev() helper
  connector: per-ve init and fini helpers introduced
  connector: use device stored in VE
  connector: per-ve helpers intoruduced
  connector: take cn_already_initialized from VE
  proc connector: generic proc_event_connector() helper introduced
  proc connector: use generic event helper for fork event
  proc connector: use generic event helper for exec event
  proc connector: use generic event helper for id event
  proc connector: use generic event helper for sid event
  proc connector: use generic event helper for ptrace event
  proc connector: use generic event helper for comm event
  proc connector: use generic event helper for coredump event
  proc connector: use generic event helper for exit event
  proc connector: add pid namespace awareness
  proc connector: add per-ve init and fini foutines
  proc connector: call proc-related init and fini routines explicitly
  proc connector: take number of listeners and per-cpu conters from VE
  proc connector: pass VE to event fillers
  proc connector: take namespaces from VE
  proc connector: use per-ve netlink sender helper
  proc connector: send events to both VEs if not in VE#0
  connector: containerize "connector" proc entry
  connector: take VE from socket upon callback
  connector: add VE SS hook


 drivers/connector/cn_proc.c   |  386 -
 drivers/connector/connector.c |  155 
 include/linux/connector.h |   20 ++
 include/linux/ve.h|4 
 4 files changed, 323 insertions(+), 242 deletions(-)

--
___
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel


[Devel] [PATCH v2 07/27] connector: take cn_already_initialized from VE

2017-08-17 Thread Stanislav Kinsburskiy
Signed-off-by: Stanislav Kinsburskiy 
---
 drivers/connector/connector.c |8 +++-
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c
index bba667d..110637b 100644
--- a/drivers/connector/connector.c
+++ b/drivers/connector/connector.c
@@ -38,8 +38,6 @@ MODULE_AUTHOR("Evgeniy Polyakov ");
 MODULE_DESCRIPTION("Generic userspace <-> kernelspace connector.");
 MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_CONNECTOR);
 
-static int cn_already_initialized;
-
 /*
  * msg->seq and msg->ack are used to determine message genealogy.
  * When someone sends message it puts there locally unique sequence
@@ -196,7 +194,7 @@ int cn_add_callback_ve(struct ve_struct *ve,
int err;
struct cn_dev *dev = get_cdev(ve);
 
-   if (!cn_already_initialized)
+   if (!ve->cn->cn_already_initialized)
return -EAGAIN;
 
err = cn_queue_add_callback(dev->cbdev, name, id, callback);
@@ -300,7 +298,7 @@ static int cn_init_ve(struct ve_struct *ve)
return -EINVAL;
}
 
-   cn_already_initialized = 1;
+   ve->cn->cn_already_initialized = 1;
 
proc_create("connector", S_IRUGO, net->proc_net, _file_ops);
 
@@ -312,7 +310,7 @@ static void cn_fini_ve(struct ve_struct *ve)
struct cn_dev *dev = get_cdev(ve);
struct net *net = ve->ve_netns;
 
-   cn_already_initialized = 0;
+   ve->cn->cn_already_initialized = 0;
 
remove_proc_entry("connector", net->proc_net);
 

___
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel


[Devel] [PATCH v2 10/27] proc connector: use generic event helper for exec event

2017-08-17 Thread Stanislav Kinsburskiy
Signed-off-by: Stanislav Kinsburskiy 
---
 drivers/connector/cn_proc.c |   28 +++-
 1 file changed, 7 insertions(+), 21 deletions(-)

diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c
index ffda79b..06fd6b3 100644
--- a/drivers/connector/cn_proc.c
+++ b/drivers/connector/cn_proc.c
@@ -132,31 +132,17 @@ void proc_fork_connector(struct task_struct *task)
proc_event_connector(task, PROC_EVENT_FORK, 0, fill_fork_event);
 }
 
-void proc_exec_connector(struct task_struct *task)
+static bool fill_exec_event(struct proc_event *ev, struct task_struct *task,
+   int unused)
 {
-   struct cn_msg *msg;
-   struct proc_event *ev;
-   struct timespec ts;
-   __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
-
-   if (atomic_read(_event_num_listeners) < 1)
-   return;
-
-   msg = buffer_to_cn_msg(buffer);
-   ev = (struct proc_event *)msg->data;
-   memset(>event_data, 0, sizeof(ev->event_data));
-   get_seq(>seq, >cpu);
-   ktime_get_ts(); /* get high res monotonic timestamp */
-   ev->timestamp_ns = timespec_to_ns();
-   ev->what = PROC_EVENT_EXEC;
ev->event_data.exec.process_pid = task->pid;
ev->event_data.exec.process_tgid = task->tgid;
+   return true;
+}
 
-   memcpy(>id, _proc_event_id, sizeof(msg->id));
-   msg->ack = 0; /* not used */
-   msg->len = sizeof(*ev);
-   msg->flags = 0; /* not used */
-   cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
+void proc_exec_connector(struct task_struct *task)
+{
+   proc_event_connector(task, PROC_EVENT_EXEC, 0, fill_exec_event);
 }
 
 void proc_id_connector(struct task_struct *task, int which_id)

___
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel