|
@@ -532,6 +532,161 @@ static struct o2nm_node_group *to_o2nm_node_group(struct config_group *group)
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
+struct o2nm_cluster_attribute {
|
|
|
+ struct configfs_attribute attr;
|
|
|
+ ssize_t (*show)(struct o2nm_cluster *, char *);
|
|
|
+ ssize_t (*store)(struct o2nm_cluster *, const char *, size_t);
|
|
|
+};
|
|
|
+
|
|
|
+static ssize_t o2nm_cluster_attr_write(const char *page, ssize_t count,
|
|
|
+ unsigned int *val)
|
|
|
+{
|
|
|
+ unsigned long tmp;
|
|
|
+ char *p = (char *)page;
|
|
|
+
|
|
|
+ tmp = simple_strtoul(p, &p, 0);
|
|
|
+ if (!p || (*p && (*p != '\n')))
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ if (tmp == 0)
|
|
|
+ return -EINVAL;
|
|
|
+ if (tmp >= (u32)-1)
|
|
|
+ return -ERANGE;
|
|
|
+
|
|
|
+ *val = tmp;
|
|
|
+
|
|
|
+ return count;
|
|
|
+}
|
|
|
+
|
|
|
+static ssize_t o2nm_cluster_attr_idle_timeout_ms_read(
|
|
|
+ struct o2nm_cluster *cluster, char *page)
|
|
|
+{
|
|
|
+ return sprintf(page, "%u\n", cluster->cl_idle_timeout_ms);
|
|
|
+}
|
|
|
+
|
|
|
+static ssize_t o2nm_cluster_attr_idle_timeout_ms_write(
|
|
|
+ struct o2nm_cluster *cluster, const char *page, size_t count)
|
|
|
+{
|
|
|
+ ssize_t ret;
|
|
|
+ unsigned int val;
|
|
|
+
|
|
|
+ ret = o2nm_cluster_attr_write(page, count, &val);
|
|
|
+
|
|
|
+ if (ret > 0) {
|
|
|
+ if (val <= cluster->cl_keepalive_delay_ms) {
|
|
|
+ mlog(ML_NOTICE, "o2net: idle timeout must be larger "
|
|
|
+ "than keepalive delay\n");
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+ cluster->cl_idle_timeout_ms = val;
|
|
|
+ }
|
|
|
+
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+static ssize_t o2nm_cluster_attr_keepalive_delay_ms_read(
|
|
|
+ struct o2nm_cluster *cluster, char *page)
|
|
|
+{
|
|
|
+ return sprintf(page, "%u\n", cluster->cl_keepalive_delay_ms);
|
|
|
+}
|
|
|
+
|
|
|
+static ssize_t o2nm_cluster_attr_keepalive_delay_ms_write(
|
|
|
+ struct o2nm_cluster *cluster, const char *page, size_t count)
|
|
|
+{
|
|
|
+ ssize_t ret;
|
|
|
+ unsigned int val;
|
|
|
+
|
|
|
+ ret = o2nm_cluster_attr_write(page, count, &val);
|
|
|
+
|
|
|
+ if (ret > 0) {
|
|
|
+ if (val >= cluster->cl_idle_timeout_ms) {
|
|
|
+ mlog(ML_NOTICE, "o2net: keepalive delay must be "
|
|
|
+ "smaller than idle timeout\n");
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+ cluster->cl_keepalive_delay_ms = val;
|
|
|
+ }
|
|
|
+
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+static ssize_t o2nm_cluster_attr_reconnect_delay_ms_read(
|
|
|
+ struct o2nm_cluster *cluster, char *page)
|
|
|
+{
|
|
|
+ return sprintf(page, "%u\n", cluster->cl_reconnect_delay_ms);
|
|
|
+}
|
|
|
+
|
|
|
+static ssize_t o2nm_cluster_attr_reconnect_delay_ms_write(
|
|
|
+ struct o2nm_cluster *cluster, const char *page, size_t count)
|
|
|
+{
|
|
|
+ return o2nm_cluster_attr_write(page, count,
|
|
|
+ &cluster->cl_reconnect_delay_ms);
|
|
|
+}
|
|
|
+static struct o2nm_cluster_attribute o2nm_cluster_attr_idle_timeout_ms = {
|
|
|
+ .attr = { .ca_owner = THIS_MODULE,
|
|
|
+ .ca_name = "idle_timeout_ms",
|
|
|
+ .ca_mode = S_IRUGO | S_IWUSR },
|
|
|
+ .show = o2nm_cluster_attr_idle_timeout_ms_read,
|
|
|
+ .store = o2nm_cluster_attr_idle_timeout_ms_write,
|
|
|
+};
|
|
|
+
|
|
|
+static struct o2nm_cluster_attribute o2nm_cluster_attr_keepalive_delay_ms = {
|
|
|
+ .attr = { .ca_owner = THIS_MODULE,
|
|
|
+ .ca_name = "keepalive_delay_ms",
|
|
|
+ .ca_mode = S_IRUGO | S_IWUSR },
|
|
|
+ .show = o2nm_cluster_attr_keepalive_delay_ms_read,
|
|
|
+ .store = o2nm_cluster_attr_keepalive_delay_ms_write,
|
|
|
+};
|
|
|
+
|
|
|
+static struct o2nm_cluster_attribute o2nm_cluster_attr_reconnect_delay_ms = {
|
|
|
+ .attr = { .ca_owner = THIS_MODULE,
|
|
|
+ .ca_name = "reconnect_delay_ms",
|
|
|
+ .ca_mode = S_IRUGO | S_IWUSR },
|
|
|
+ .show = o2nm_cluster_attr_reconnect_delay_ms_read,
|
|
|
+ .store = o2nm_cluster_attr_reconnect_delay_ms_write,
|
|
|
+};
|
|
|
+
|
|
|
+static struct configfs_attribute *o2nm_cluster_attrs[] = {
|
|
|
+ &o2nm_cluster_attr_idle_timeout_ms.attr,
|
|
|
+ &o2nm_cluster_attr_keepalive_delay_ms.attr,
|
|
|
+ &o2nm_cluster_attr_reconnect_delay_ms.attr,
|
|
|
+ NULL,
|
|
|
+};
|
|
|
+static ssize_t o2nm_cluster_show(struct config_item *item,
|
|
|
+ struct configfs_attribute *attr,
|
|
|
+ char *page)
|
|
|
+{
|
|
|
+ struct o2nm_cluster *cluster = to_o2nm_cluster(item);
|
|
|
+ struct o2nm_cluster_attribute *o2nm_cluster_attr =
|
|
|
+ container_of(attr, struct o2nm_cluster_attribute, attr);
|
|
|
+ ssize_t ret = 0;
|
|
|
+
|
|
|
+ if (o2nm_cluster_attr->show)
|
|
|
+ ret = o2nm_cluster_attr->show(cluster, page);
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+static ssize_t o2nm_cluster_store(struct config_item *item,
|
|
|
+ struct configfs_attribute *attr,
|
|
|
+ const char *page, size_t count)
|
|
|
+{
|
|
|
+ struct o2nm_cluster *cluster = to_o2nm_cluster(item);
|
|
|
+ struct o2nm_cluster_attribute *o2nm_cluster_attr =
|
|
|
+ container_of(attr, struct o2nm_cluster_attribute, attr);
|
|
|
+ ssize_t ret;
|
|
|
+
|
|
|
+ if (o2nm_cluster_attr->store == NULL) {
|
|
|
+ ret = -EINVAL;
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+
|
|
|
+ ret = o2nm_cluster_attr->store(cluster, page, count);
|
|
|
+ if (ret < count)
|
|
|
+ goto out;
|
|
|
+out:
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
static struct config_item *o2nm_node_group_make_item(struct config_group *group,
|
|
|
const char *name)
|
|
|
{
|
|
@@ -613,10 +768,13 @@ static void o2nm_cluster_release(struct config_item *item)
|
|
|
|
|
|
static struct configfs_item_operations o2nm_cluster_item_ops = {
|
|
|
.release = o2nm_cluster_release,
|
|
|
+ .show_attribute = o2nm_cluster_show,
|
|
|
+ .store_attribute = o2nm_cluster_store,
|
|
|
};
|
|
|
|
|
|
static struct config_item_type o2nm_cluster_type = {
|
|
|
.ct_item_ops = &o2nm_cluster_item_ops,
|
|
|
+ .ct_attrs = o2nm_cluster_attrs,
|
|
|
.ct_owner = THIS_MODULE,
|
|
|
};
|
|
|
|
|
@@ -667,6 +825,9 @@ static struct config_group *o2nm_cluster_group_make_group(struct config_group *g
|
|
|
cluster->cl_group.default_groups[2] = NULL;
|
|
|
rwlock_init(&cluster->cl_nodes_lock);
|
|
|
cluster->cl_node_ip_tree = RB_ROOT;
|
|
|
+ cluster->cl_reconnect_delay_ms = O2NET_RECONNECT_DELAY_MS_DEFAULT;
|
|
|
+ cluster->cl_idle_timeout_ms = O2NET_IDLE_TIMEOUT_MS_DEFAULT;
|
|
|
+ cluster->cl_keepalive_delay_ms = O2NET_KEEPALIVE_DELAY_MS_DEFAULT;
|
|
|
|
|
|
ret = &cluster->cl_group;
|
|
|
o2nm_single_cluster = cluster;
|