[Devel,RHEL7,COMMIT] vedev: drop obsoleted vedev.c - old way to provide device access into a CT

Submitted by Konstantin Khorenko on April 7, 2017, 10:34 a.m.

Details

Message ID 201704071034.v37AY97o025893@finist_cl7.x64_64.work.ct
State New
Series "vedev: drop obsoleted vedev.c - old way to provide device access into a CT"
Headers show

Commit Message

Konstantin Khorenko April 7, 2017, 10:34 a.m.
The commit is pushed to "branch-rh7-3.10.0-514.10.2.vz7.29.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-514.10.2.vz7.29.13
------>
commit 9dd9ead624da71cc0c0ab33ee284d3c8b742b1b7
Author: Konstantin Khorenko <khorenko@virtuozzo.com>
Date:   Fri Apr 7 14:30:23 2017 +0400

    vedev: drop obsoleted vedev.c - old way to provide device access into a CT
    
    In Virtuozzo 7 we allow access to devices inside a CT
    via devices cgroup configuration, sysfs visibility is also
    managed via cgroup (ve.sysfs_permissions) =>
    
    functionality from this file is obsoleted and to be dropped.
    
    https://jira.sw.ru/browse/PSBM-54408
    
    Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com>
---
 drivers/base/vedev.c | 575 ---------------------------------------------------
 1 file changed, 575 deletions(-)

Patch hide | download patch | download mbox

diff --git a/drivers/base/vedev.c b/drivers/base/vedev.c
deleted file mode 100644
index f32d84c..0000000
--- a/drivers/base/vedev.c
+++ /dev/null
@@ -1,575 +0,0 @@ 
-/*
- *  drivers/base/vedev.c
- *
- *  Copyright (c) 2010-2015 Parallels IP Holdings GmbH
- *
- */
-
-#include <linux/kobject.h>
-#include <linux/ve.h>
-#include <linux/ve_proto.h>
-#include <linux/genhd.h>
-
-#include "base.h"
-
-struct ve_device_link {
-	char *name;
-	struct kobject *kobj;
-	struct list_head list;
-};
-
-struct ve_device {
-	struct ve_struct *ve;
-	struct device *dev;
-	struct list_head kobj_list;
-	struct list_head ve_list;
-	struct kobject *kobj;
-	struct list_head links;
-	struct kobject* net_link;
-};
-
-static DECLARE_MUTEX(vedev_lock);
-
-extern struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd);
-extern void sysfs_put_active(struct sysfs_dirent *sd);
-
-static struct kobject *ve_kobj_path_create(char *path)
-{
-	char *e, *p = path;
-	struct sysfs_dirent *sd, *parent_sd = get_exec_env()->_sysfs_root;
-	struct kobject *k, *pk = NULL;
-
-	if (*p == '/')
-		p++;
-
-	while (1) {
-		e = strchr(p, '/');
-		if (e)
-			*e = '\0';
-		sd = sysfs_get_dirent(parent_sd, p);
-		if (sd == NULL) {
-new:			k = kobject_create_and_add(p, pk);
-			kobject_put(pk);
-			if (!k)
-				return ERR_PTR(-ENOMEM);
-		} else {
-			if (!(sd->s_flags & SYSFS_DIR)) {
-				sysfs_put(sd);
-
-				return (sd->s_flags & SYSFS_DIR_LINK) ?
-					ERR_PTR(-EEXIST) : ERR_PTR(-EINVAL);
-			}
-
-			k = sd->s_dir.kobj;
-			/*a directory may be deleted*/
-			if (!sysfs_get_active(sd)) {
-				sysfs_put(sd);
-				goto new;
-			}
-
-			kobject_get(k);
-			kobject_put(pk);
-			sysfs_put_active(sd);
-			sysfs_put(sd);
-		}
-		pk = k;
-		parent_sd = k->sd;
-		if (!e)
-			break;
-
-		p = e + 1;
-	}
-
-	return k;
-}
-
-static inline struct kobject *vedev_kobj_path_create(char *path, struct ve_device *ve_dev)
-{
-	struct kobject *obj;
-	struct ve_struct *old_ve = set_exec_env(ve_dev->ve);
-	obj = ve_kobj_path_create(path);
-	set_exec_env(old_ve);
-	return obj;
-}
-
-static int ve_device_add_symlink(struct kobject *kobj, const char *name, \
-			struct ve_device *ve_dev)
-{
-	char *path;
-	int ret = -ENOMEM;
-	struct kobject *dev_kobj, *ve_kobj = NULL;
-	struct ve_device_link *ve_link;
-
-	path = kobject_get_path(kobj, GFP_KERNEL);
-	if (!path)
-		goto out;
-
-	ve_kobj = vedev_kobj_path_create(path, ve_dev);
-	kfree(path);
-	if (IS_ERR(ve_kobj)) {
-		ret = PTR_ERR(ve_kobj);
-		ve_kobj = NULL;
-		goto out;
-	}
-
-	ve_link = kmalloc(sizeof(struct ve_device_link), GFP_KERNEL);
-	if (!ve_link)
-		goto out;
-
-	ve_link->name = kstrdup(dev_name(ve_dev->dev), GFP_KERNEL);
-	if (!ve_link->name)
-		goto out_free;
-
-	if (ve_dev->kobj)
-		dev_kobj = ve_dev->kobj;
-	else
-		dev_kobj = &ve_dev->dev->kobj;
-
-	ret = sysfs_create_link(ve_kobj, dev_kobj, name);
-	if (ret)
-		goto out_free_name;
-
-	ve_link->kobj = ve_kobj;
-	list_add(&ve_link->list, &ve_dev->links);
-
-	return 0;
-
-out_free_name:
-	kfree(ve_link->name);
-out_free:
-	kfree(ve_link);
-out:
-	kobject_put(ve_kobj);
-	return ret;
-}
-
-static void dirlink_kobj_release(struct kobject *kobj)
-{
-	kfree(kobj);
-}
-
-static struct kobj_type dirlink_kobj_ktype = {
-	.release	= dirlink_kobj_release,
-};
-
-static struct kobject *kobject_link_create(struct kobject *parent, struct kobject *target)
-{
-	struct sysfs_dirent *sd;
-	struct kobject *kobj;
-
-	kobj = kzalloc(sizeof(*kobj), GFP_KERNEL);
-	if (!kobj)
-		return ERR_PTR(-ENOMEM);
-
-	kobject_init(kobj, &dirlink_kobj_ktype);
-
-	kobject_set_name(kobj, "%s", kobject_name(target));
-	sd = sysfs_create_dirlink(parent->sd, target);
-	if (IS_ERR(sd)) {
-		kobject_put(kobj);
-		kobj = (struct kobject *) sd;
-		goto out;
-	}
-	kobj->sd = sd;
-	kobj->parent = kobject_get(parent);
-out:
-	return kobj;
-}
-
-static void kobject_link_del(struct kobject *kobj, struct ve_struct *ve)
-{
-	struct ve_struct *old_ve;
-	if (!kobj)
-		return;
-	if (kobj->sd) {
-		old_ve = set_exec_env(ve);
-		sysfs_remove_dirlink(kobj->sd);
-		set_exec_env(old_ve);
-	}
-	kobj->sd = NULL;
-	kobject_put(kobj->parent);
-	kobject_put(kobj);
-}
-
-static int ve_device_link_kobj(struct ve_device *ve_dev)
-{
-	char *path, *p;
-	int ret = 0;
-	struct sysfs_dirent *sd;
-	struct kobject *k = NULL, *pk = NULL;
-
-	path = kobject_get_path(&ve_dev->dev->kobj, GFP_KERNEL);
-	if (!path) {
-		return -ENOMEM;
-	}
-	p = strrchr(path, '/');
-	if (p && p != path) {
-		*p = '\0';
-		p++;
-		pk = vedev_kobj_path_create(path, ve_dev);
-		if (IS_ERR(pk)) {
-			ret = PTR_ERR(pk);
-			pk = NULL;
-			goto out;
-		}
-	} else {
-		ret = -EINVAL;
-		goto out;
-	}
-
-	sd = sysfs_get_dirent(pk->sd, p);
-	if (sd != NULL) {
-		sysfs_put(pk->sd);
-		ret = -EEXIST;
-		goto out;
-	}
-
-	k = kobject_link_create(pk, &ve_dev->dev->kobj);
-	if (IS_ERR(k)) {
-		ret = PTR_ERR(k);
-		goto out;
-	}
-	ve_dev->kobj = k;
-
-out:
-	kobject_put(pk);
-	kfree(path);
-	return ret;
-}
-
-static int ve_device_link_bus(struct ve_device *ve_dev)
-{
-	struct kobject *devs_kobj = NULL;
-	int ret = 0;
-
-	if (ve_dev->dev->bus) {
-		devs_kobj = &ve_dev->dev->bus->p->devices_kset->kobj;
-		ret = ve_device_add_symlink(devs_kobj, dev_name(ve_dev->dev), ve_dev);
-	}
-
-	return ret;
-}
-
-static int ve_device_link_class(struct ve_device *ve_dev)
-{
-	struct kobject *devs_kobj = NULL;
-	struct device *dev = ve_dev->dev;
-	int ret = 0;
-
-	if (!dev->class)
-		return 0;
-
-	if ((dev->kobj.parent != &dev->class->p->class_subsys.kobj) &&
-	    device_is_not_partition(dev)) {
-		devs_kobj = &dev->class->p->class_subsys.kobj;
-		ret = ve_device_add_symlink(devs_kobj, dev_name(dev), ve_dev);
-	}
-
-	return ret;
-}
-
-static void ve_device_del_link(struct ve_device *ve_dev)
-{
-	struct ve_device_link *l, *t;
-	list_for_each_entry_safe(l, t, &ve_dev->links, list) {
-		sysfs_remove_link(l->kobj, l->name);
-		kobject_put(l->kobj);
-		kfree(l->name);
-		kfree(l);
-	}
-	kobject_link_del(ve_dev->kobj, ve_dev->ve);
-}
-
-static int ve_device_create_link(struct ve_device *ve_dev)
-{
-	int ret;
-	ret = ve_device_link_kobj(ve_dev);
-	if (ret == -EEXIST)
-		goto out;
-	if (ret)
-		goto err;
-	ret = ve_device_link_bus(ve_dev);
-	if (ret)
-		goto err;
-out:
-	return 0;
-err:
-	ve_device_del_link(ve_dev);
-	return ret;
-}
-
-static inline struct ve_device *__ve_device_find(struct list_head *head,
-						struct ve_struct *ve)
-{
-	struct ve_device *ve_dev;
-
-	list_for_each_entry(ve_dev, head, kobj_list)
-		if (ve_dev->ve == ve)
-			return ve_dev;
-
-	return NULL;
-}
-
-static struct ve_device *__ve_device_subscribe(struct device *dev, struct ve_struct *ve)
-{
-	struct ve_device *ve_dev;
-
-	ve_dev = kzalloc(sizeof(struct ve_device), GFP_KERNEL);
-
-	if (!ve_dev)
-		return ERR_PTR(-ENOMEM);
-
-	ve_dev->ve = ve;
-	ve_dev->dev = dev;
-	get_device(dev);
-	INIT_LIST_HEAD(&ve_dev->links);
-
-	list_add(&ve_dev->kobj_list, &dev->kobj.env_head);
-	list_add(&ve_dev->ve_list, &ve->devices);
-	return ve_dev;
-}
-
-static struct ve_device *ve_device_subscribe(struct device *dev, struct ve_struct *ve)
-{
-	struct ve_device *ve_dev;
-
-	down(&vedev_lock);
-
-	if (__ve_device_find(&dev->kobj.env_head, ve)) {
-		ve_dev = ERR_PTR(-EEXIST);
-		goto out;
-	}
-
-	ve_dev = __ve_device_subscribe(dev, ve);
-out:
-	up(&vedev_lock);
-	return ve_dev;
-}
-
-static void ve_device_del_one(struct ve_device *ve_dev, int event)
-{
-	struct ve_struct *old_ve;
-	unsigned type;
-
-	list_del(&ve_dev->ve_list);
-	list_del(&ve_dev->kobj_list);
-
-	if (event) {
-		old_ve = set_exec_env(ve_dev->ve);
-		kobject_uevent_env_one(&ve_dev->dev->kobj, KOBJ_REMOVE, NULL);
-		set_exec_env(old_ve);
-	}
-
-	ve_device_del_link(ve_dev);
-	if (MAJOR(ve_dev->dev->devt)) {
-		type = ve_dev->dev->class == &block_class ? S_IFBLK : S_IFCHR;
-		devcgroup_set_perms_ve(ve_dev->ve->css.cgroup, type, ve_dev->dev->devt, 00);
-	}
-	put_device(ve_dev->dev);
-	kfree(ve_dev);
-}
-
-void ve_device_del(struct device *dev, struct ve_struct *ve)
-{
-	struct ve_device *ve_dev, *tmp;
-	down(&vedev_lock);
-	list_for_each_entry_safe(ve_dev, tmp, &dev->kobj.env_head, kobj_list) {
-		if (ve && ve_dev->ve != ve)
-			continue;
-
-		ve_device_del_one(ve_dev, 1);
-	}
-	up(&vedev_lock);
-}
-
-/*
- * Check that physical device is a NIC
- */
-static inline int is_phydev_net(struct device *dev)
-{
-	struct sysfs_dirent *sd;
-
-	sd = sysfs_get_dirent(dev->kobj.sd, "net");
-	if (!sd)
-		return 0;
-
-	sysfs_put(sd);
-	return 1;
-}
-
-static int ve_device_add(struct device *dev, struct ve_struct *ve)
-{
-	int ret = 0;
-	struct ve_device *ve_dev;
-	struct ve_struct *old_ve;
-
-	if (is_phydev_net(dev))
-		return -EPERM;
-
-	ve_dev = ve_device_subscribe(dev, ve);
-	if (IS_ERR(ve_dev))
-		return PTR_ERR(ve_dev);
-
-	ret = ve_device_create_link(ve_dev);
-	if (ret < 0)
-		goto err;
-
-	ret = ve_device_link_class(ve_dev);
-	if (ret)
-		goto err;
-
-	if (MAJOR(dev->devt)) {
-		unsigned type = dev->class == &block_class ? S_IFBLK : S_IFCHR;
-		ret = devcgroup_set_perms_ve(ve->css.cgroup, type, dev->devt, 06);
-		if (ret < 0)
-			goto err;
-	}
-
-	old_ve = set_exec_env(ve);
-	kobject_uevent_env_one(&dev->kobj, KOBJ_ADD, NULL);
-	set_exec_env(old_ve);
-	return ret;
-err:
-	down(&vedev_lock);
-	ve_device_del_one(ve_dev, 0);
-	up(&vedev_lock);
-	return ret;
-}
-
-ssize_t ve_device_handler(struct device *dev, struct device_attribute *attr,
-			  const char *buf, size_t count)
-{
-	int ret;
-	struct ve_struct *ve;
-	envid_t veid;
-	char cmd;
-
-	if (!capable_setveid())
-		return -EPERM;
-
-	if (buf[count] != '\0')
-		return -EINVAL;
-
-	if (!strchr("+-", *buf))
-		return -EINVAL;
-	cmd = *buf;
-	buf++;
-
-	if (sscanf(buf, "%u", &veid) != 1)
-		return -EINVAL;
-
-	ve = get_ve_by_id(veid);
-
-	ret = -ENOENT;
-	if (!ve || !ve->is_running)
-		goto out;
-
-	if (cmd == '+')
-		ret = ve_device_add(dev, ve);
-	else {
-		ve_device_del(dev, ve);
-		ret = 0;
-	}
-out:
-	put_ve(ve);
-	if (unlikely(ret))
-		return ret;
-
-	return count;
-}
-
-void fini_ve_devices(struct ve_struct *ve)
-{
-	struct ve_device *ve_dev, *tmp;
-	down(&vedev_lock);
-	list_for_each_entry_safe(ve_dev, tmp, &ve->devices, ve_list) {
-		if (!ve_dev->net_link)
-			ve_device_del_one(ve_dev, 0);
-	}
-	up(&vedev_lock);
-}
-EXPORT_SYMBOL(fini_ve_devices);
-
-int ve_kobject_uevent_env(struct kobject *kobj,
-			enum kobject_action action, char *envp_ext[])
-{
-	int err, ret = 0;
-	struct ve_device *ve_dev;
-	struct ve_struct *ve_old;
-
-	down(&vedev_lock);
-	list_for_each_entry(ve_dev, &kobj->env_head, kobj_list) {
-		ve_old = set_exec_env(ve_dev->ve);
-		err = kobject_uevent_env_one(kobj, action, envp_ext);
-		if (err)
-			ret = err;
-		set_exec_env(ve_old);
-	}
-	up(&vedev_lock);
-
-	return ret;
-}
-
-static int ve_netdev_create(struct kobject *net_obj, struct ve_struct *ve)
-{
-	struct ve_device *ve_dev;
-	struct ve_struct *old_ve;
-	struct kobject *phy_obj = net_obj->parent;
-	struct device *phy_dev;
-	char *path, *p;
-	int err;
-	struct kobject *k = NULL, *pk = NULL;
-
-	/*
-	 * ve_netdev_create should not be called with network
-	 * interface not attached to physical device
-	 */
-	phy_dev = container_of(phy_obj, struct device, kobj);
-
-	ve_dev = __ve_device_subscribe(phy_dev, ve);
-
-	if (IS_ERR(ve_dev))
-		return PTR_ERR(ve_dev);
-
-	path = kobject_get_path(net_obj, GFP_KERNEL);
-
-	if (!path) {
-		err = -ENOMEM;
-		goto error;
-	}
-
-	p = strrchr(path, '/');
-
-	if (!p || (p == path)) {
-		err = -EINVAL;
-		kfree(path);
-		goto error;
-	}
-
-	*p = '\0';
-	old_ve = set_exec_env(ve);
-	pk = ve_kobj_path_create(path);
-	set_exec_env(old_ve);
-
-	kfree(path);
-
-	if (IS_ERR(pk)) {
-		err = PTR_ERR(pk);
-		goto error;
-	}
-
-	k = kobject_link_create(pk, net_obj);
-	kobject_put(pk);
-
-	if (IS_ERR(k)) {
-		err = PTR_ERR(k);
-		goto error;
-	}
-
-	ve_dev->net_link = k;
-	return 0;
-
-error:
-	ve_device_del_one(ve_dev, 0);
-	return err;
-}