forked from Qortal/Brooklyn
Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey!
313 lines
7.5 KiB
C
313 lines
7.5 KiB
C
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
/*
|
|
* RDMA Transport Layer
|
|
*
|
|
* Copyright (c) 2014 - 2018 ProfitBricks GmbH. All rights reserved.
|
|
* Copyright (c) 2018 - 2019 1&1 IONOS Cloud GmbH. All rights reserved.
|
|
* Copyright (c) 2019 - 2020 1&1 IONOS SE. All rights reserved.
|
|
*/
|
|
#undef pr_fmt
|
|
#define pr_fmt(fmt) KBUILD_MODNAME " L" __stringify(__LINE__) ": " fmt
|
|
|
|
#include "rtrs-pri.h"
|
|
#include "rtrs-srv.h"
|
|
#include "rtrs-log.h"
|
|
|
|
static void rtrs_srv_release(struct kobject *kobj)
|
|
{
|
|
struct rtrs_srv_sess *sess;
|
|
|
|
sess = container_of(kobj, struct rtrs_srv_sess, kobj);
|
|
kfree(sess);
|
|
}
|
|
|
|
static struct kobj_type ktype = {
|
|
.sysfs_ops = &kobj_sysfs_ops,
|
|
.release = rtrs_srv_release,
|
|
};
|
|
|
|
static ssize_t rtrs_srv_disconnect_show(struct kobject *kobj,
|
|
struct kobj_attribute *attr, char *buf)
|
|
{
|
|
return sysfs_emit(buf, "Usage: echo 1 > %s\n", attr->attr.name);
|
|
}
|
|
|
|
static ssize_t rtrs_srv_disconnect_store(struct kobject *kobj,
|
|
struct kobj_attribute *attr,
|
|
const char *buf, size_t count)
|
|
{
|
|
struct rtrs_srv_sess *sess;
|
|
struct rtrs_sess *s;
|
|
char str[MAXHOSTNAMELEN];
|
|
|
|
sess = container_of(kobj, struct rtrs_srv_sess, kobj);
|
|
s = &sess->s;
|
|
if (!sysfs_streq(buf, "1")) {
|
|
rtrs_err(s, "%s: invalid value: '%s'\n",
|
|
attr->attr.name, buf);
|
|
return -EINVAL;
|
|
}
|
|
|
|
sockaddr_to_str((struct sockaddr *)&sess->s.dst_addr, str, sizeof(str));
|
|
|
|
rtrs_info(s, "disconnect for path %s requested\n", str);
|
|
/* first remove sysfs itself to avoid deadlock */
|
|
sysfs_remove_file_self(&sess->kobj, &attr->attr);
|
|
close_sess(sess);
|
|
|
|
return count;
|
|
}
|
|
|
|
static struct kobj_attribute rtrs_srv_disconnect_attr =
|
|
__ATTR(disconnect, 0644,
|
|
rtrs_srv_disconnect_show, rtrs_srv_disconnect_store);
|
|
|
|
static ssize_t rtrs_srv_hca_port_show(struct kobject *kobj,
|
|
struct kobj_attribute *attr,
|
|
char *page)
|
|
{
|
|
struct rtrs_srv_sess *sess;
|
|
struct rtrs_con *usr_con;
|
|
|
|
sess = container_of(kobj, typeof(*sess), kobj);
|
|
usr_con = sess->s.con[0];
|
|
|
|
return sysfs_emit(page, "%u\n", usr_con->cm_id->port_num);
|
|
}
|
|
|
|
static struct kobj_attribute rtrs_srv_hca_port_attr =
|
|
__ATTR(hca_port, 0444, rtrs_srv_hca_port_show, NULL);
|
|
|
|
static ssize_t rtrs_srv_hca_name_show(struct kobject *kobj,
|
|
struct kobj_attribute *attr,
|
|
char *page)
|
|
{
|
|
struct rtrs_srv_sess *sess;
|
|
|
|
sess = container_of(kobj, struct rtrs_srv_sess, kobj);
|
|
|
|
return sysfs_emit(page, "%s\n", sess->s.dev->ib_dev->name);
|
|
}
|
|
|
|
static struct kobj_attribute rtrs_srv_hca_name_attr =
|
|
__ATTR(hca_name, 0444, rtrs_srv_hca_name_show, NULL);
|
|
|
|
static ssize_t rtrs_srv_src_addr_show(struct kobject *kobj,
|
|
struct kobj_attribute *attr,
|
|
char *page)
|
|
{
|
|
struct rtrs_srv_sess *sess;
|
|
int cnt;
|
|
|
|
sess = container_of(kobj, struct rtrs_srv_sess, kobj);
|
|
cnt = sockaddr_to_str((struct sockaddr *)&sess->s.dst_addr,
|
|
page, PAGE_SIZE);
|
|
return cnt + scnprintf(page + cnt, PAGE_SIZE - cnt, "\n");
|
|
}
|
|
|
|
static struct kobj_attribute rtrs_srv_src_addr_attr =
|
|
__ATTR(src_addr, 0444, rtrs_srv_src_addr_show, NULL);
|
|
|
|
static ssize_t rtrs_srv_dst_addr_show(struct kobject *kobj,
|
|
struct kobj_attribute *attr,
|
|
char *page)
|
|
{
|
|
struct rtrs_srv_sess *sess;
|
|
int len;
|
|
|
|
sess = container_of(kobj, struct rtrs_srv_sess, kobj);
|
|
len = sockaddr_to_str((struct sockaddr *)&sess->s.src_addr, page,
|
|
PAGE_SIZE);
|
|
len += sysfs_emit_at(page, len, "\n");
|
|
return len;
|
|
}
|
|
|
|
static struct kobj_attribute rtrs_srv_dst_addr_attr =
|
|
__ATTR(dst_addr, 0444, rtrs_srv_dst_addr_show, NULL);
|
|
|
|
static struct attribute *rtrs_srv_sess_attrs[] = {
|
|
&rtrs_srv_hca_name_attr.attr,
|
|
&rtrs_srv_hca_port_attr.attr,
|
|
&rtrs_srv_src_addr_attr.attr,
|
|
&rtrs_srv_dst_addr_attr.attr,
|
|
&rtrs_srv_disconnect_attr.attr,
|
|
NULL,
|
|
};
|
|
|
|
static const struct attribute_group rtrs_srv_sess_attr_group = {
|
|
.attrs = rtrs_srv_sess_attrs,
|
|
};
|
|
|
|
STAT_ATTR(struct rtrs_srv_stats, rdma,
|
|
rtrs_srv_stats_rdma_to_str,
|
|
rtrs_srv_reset_rdma_stats);
|
|
|
|
static struct attribute *rtrs_srv_stats_attrs[] = {
|
|
&rdma_attr.attr,
|
|
NULL,
|
|
};
|
|
|
|
static const struct attribute_group rtrs_srv_stats_attr_group = {
|
|
.attrs = rtrs_srv_stats_attrs,
|
|
};
|
|
|
|
static int rtrs_srv_create_once_sysfs_root_folders(struct rtrs_srv_sess *sess)
|
|
{
|
|
struct rtrs_srv *srv = sess->srv;
|
|
int err = 0;
|
|
|
|
mutex_lock(&srv->paths_mutex);
|
|
if (srv->dev_ref++) {
|
|
/*
|
|
* Device needs to be registered only on the first session
|
|
*/
|
|
goto unlock;
|
|
}
|
|
srv->dev.class = rtrs_dev_class;
|
|
err = dev_set_name(&srv->dev, "%s", sess->s.sessname);
|
|
if (err)
|
|
goto unlock;
|
|
|
|
/*
|
|
* Suppress user space notification until
|
|
* sysfs files are created
|
|
*/
|
|
dev_set_uevent_suppress(&srv->dev, true);
|
|
err = device_add(&srv->dev);
|
|
if (err) {
|
|
pr_err("device_add(): %d\n", err);
|
|
put_device(&srv->dev);
|
|
goto unlock;
|
|
}
|
|
srv->kobj_paths = kobject_create_and_add("paths", &srv->dev.kobj);
|
|
if (!srv->kobj_paths) {
|
|
err = -ENOMEM;
|
|
pr_err("kobject_create_and_add(): %d\n", err);
|
|
device_del(&srv->dev);
|
|
put_device(&srv->dev);
|
|
goto unlock;
|
|
}
|
|
dev_set_uevent_suppress(&srv->dev, false);
|
|
kobject_uevent(&srv->dev.kobj, KOBJ_ADD);
|
|
unlock:
|
|
mutex_unlock(&srv->paths_mutex);
|
|
|
|
return err;
|
|
}
|
|
|
|
static void
|
|
rtrs_srv_destroy_once_sysfs_root_folders(struct rtrs_srv_sess *sess)
|
|
{
|
|
struct rtrs_srv *srv = sess->srv;
|
|
|
|
mutex_lock(&srv->paths_mutex);
|
|
if (!--srv->dev_ref) {
|
|
kobject_del(srv->kobj_paths);
|
|
kobject_put(srv->kobj_paths);
|
|
mutex_unlock(&srv->paths_mutex);
|
|
device_del(&srv->dev);
|
|
put_device(&srv->dev);
|
|
} else {
|
|
put_device(&srv->dev);
|
|
mutex_unlock(&srv->paths_mutex);
|
|
}
|
|
}
|
|
|
|
static void rtrs_srv_sess_stats_release(struct kobject *kobj)
|
|
{
|
|
struct rtrs_srv_stats *stats;
|
|
|
|
stats = container_of(kobj, struct rtrs_srv_stats, kobj_stats);
|
|
|
|
kfree(stats);
|
|
}
|
|
|
|
static struct kobj_type ktype_stats = {
|
|
.sysfs_ops = &kobj_sysfs_ops,
|
|
.release = rtrs_srv_sess_stats_release,
|
|
};
|
|
|
|
static int rtrs_srv_create_stats_files(struct rtrs_srv_sess *sess)
|
|
{
|
|
int err;
|
|
struct rtrs_sess *s = &sess->s;
|
|
|
|
err = kobject_init_and_add(&sess->stats->kobj_stats, &ktype_stats,
|
|
&sess->kobj, "stats");
|
|
if (err) {
|
|
rtrs_err(s, "kobject_init_and_add(): %d\n", err);
|
|
kobject_put(&sess->stats->kobj_stats);
|
|
return err;
|
|
}
|
|
err = sysfs_create_group(&sess->stats->kobj_stats,
|
|
&rtrs_srv_stats_attr_group);
|
|
if (err) {
|
|
rtrs_err(s, "sysfs_create_group(): %d\n", err);
|
|
goto err;
|
|
}
|
|
|
|
return 0;
|
|
|
|
err:
|
|
kobject_del(&sess->stats->kobj_stats);
|
|
kobject_put(&sess->stats->kobj_stats);
|
|
|
|
return err;
|
|
}
|
|
|
|
int rtrs_srv_create_sess_files(struct rtrs_srv_sess *sess)
|
|
{
|
|
struct rtrs_srv *srv = sess->srv;
|
|
struct rtrs_sess *s = &sess->s;
|
|
char str[NAME_MAX];
|
|
int err;
|
|
struct rtrs_addr path = {
|
|
.src = &sess->s.dst_addr,
|
|
.dst = &sess->s.src_addr,
|
|
};
|
|
|
|
rtrs_addr_to_str(&path, str, sizeof(str));
|
|
err = rtrs_srv_create_once_sysfs_root_folders(sess);
|
|
if (err)
|
|
return err;
|
|
|
|
err = kobject_init_and_add(&sess->kobj, &ktype, srv->kobj_paths,
|
|
"%s", str);
|
|
if (err) {
|
|
rtrs_err(s, "kobject_init_and_add(): %d\n", err);
|
|
goto destroy_root;
|
|
}
|
|
err = sysfs_create_group(&sess->kobj, &rtrs_srv_sess_attr_group);
|
|
if (err) {
|
|
rtrs_err(s, "sysfs_create_group(): %d\n", err);
|
|
goto put_kobj;
|
|
}
|
|
err = rtrs_srv_create_stats_files(sess);
|
|
if (err)
|
|
goto remove_group;
|
|
|
|
return 0;
|
|
|
|
remove_group:
|
|
sysfs_remove_group(&sess->kobj, &rtrs_srv_sess_attr_group);
|
|
put_kobj:
|
|
kobject_del(&sess->kobj);
|
|
destroy_root:
|
|
kobject_put(&sess->kobj);
|
|
rtrs_srv_destroy_once_sysfs_root_folders(sess);
|
|
|
|
return err;
|
|
}
|
|
|
|
void rtrs_srv_destroy_sess_files(struct rtrs_srv_sess *sess)
|
|
{
|
|
if (sess->kobj.state_in_sysfs) {
|
|
kobject_del(&sess->stats->kobj_stats);
|
|
kobject_put(&sess->stats->kobj_stats);
|
|
sysfs_remove_group(&sess->kobj, &rtrs_srv_sess_attr_group);
|
|
kobject_put(&sess->kobj);
|
|
|
|
rtrs_srv_destroy_once_sysfs_root_folders(sess);
|
|
}
|
|
}
|