[Devel] [PATCH] fused: save logrotate option to fstab
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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