summaryrefslogtreecommitdiffstats
path: root/src/kernel/sysfs.c
diff options
context:
space:
mode:
authorsr2012-08-27 21:02:49 +0200
committersr2012-08-27 21:02:49 +0200
commitde01183aa40dbbd274e18f681d8a255a886f493e (patch)
treef614e764704aec26df15df68c633178064c60a41 /src/kernel/sysfs.c
parent[KERNEL] Make rtt threshold relative (diff)
downloaddnbd3-de01183aa40dbbd274e18f681d8a255a886f493e.tar.gz
dnbd3-de01183aa40dbbd274e18f681d8a255a886f493e.tar.xz
dnbd3-de01183aa40dbbd274e18f681d8a255a886f493e.zip
[KERNEL] Refactor and extend sysfs (add data the server will need in proxy mode)
[SERVER] Use MSG_MORE instead of cork/uncork to save two syscalls [KERNEL] Fail-Counter for alt servers, ignore servers that fail too often [KERNEL] Add new alt servers to list, instead of replacing the old list [*] Add CMD_LATEST_RID to tell client about new revisions
Diffstat (limited to 'src/kernel/sysfs.c')
-rw-r--r--src/kernel/sysfs.c137
1 files changed, 62 insertions, 75 deletions
diff --git a/src/kernel/sysfs.c b/src/kernel/sysfs.c
index df94d20..ff3b5f9 100644
--- a/src/kernel/sysfs.c
+++ b/src/kernel/sysfs.c
@@ -23,51 +23,84 @@
#include "sysfs.h"
#include "utils.h"
-ssize_t show_cur_server_ip(char *buf, dnbd3_device_t *dev)
+#ifndef MIN
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+#endif
+
+ssize_t show_cur_server_addr(char *buf, dnbd3_device_t *dev)
{
- return sprintf(buf, "%pI4\n", dev->cur_server.hostaddr);
+ if (dev->cur_server.hostaddrtype == AF_INET)
+ return MIN(snprintf(buf, PAGE_SIZE, "%pI4,%d\n", dev->cur_server.hostaddr, (int)ntohs(dev->cur_server.port)), PAGE_SIZE);
+ return MIN(snprintf(buf, PAGE_SIZE, "%pI6,%d\n", dev->cur_server.hostaddr, (int)ntohs(dev->cur_server.port)), PAGE_SIZE);
}
ssize_t show_cur_server_rtt(char *buf, dnbd3_device_t *dev)
{
- return sprintf(buf, "%llu\n", (unsigned long long)dev->cur_rtt);
+ return MIN(snprintf(buf, PAGE_SIZE, "%llu\n", (unsigned long long)dev->cur_rtt), PAGE_SIZE);
}
ssize_t show_alt_server_num(char *buf, dnbd3_device_t *dev)
{
- return sprintf(buf, "%d\n", dev->alt_servers_num);
+ int i, num = 0;
+ for (i = 0; i < NUMBER_SERVERS; ++i)
+ {
+ if (dev->alt_servers[i].hostaddrtype) ++num;
+ }
+ return MIN(snprintf(buf, PAGE_SIZE, "%d\n", num), PAGE_SIZE);
+}
+
+ssize_t show_alt_servers(char *buf, dnbd3_device_t *dev)
+{
+ int i, size = PAGE_SIZE, ret;
+ for (i = 0; i < NUMBER_SERVERS; ++i)
+ {
+ if (dev->alt_servers[i].hostaddrtype == AF_INET)
+ ret = MIN(snprintf(buf, size, "%pI4,%d,%llu,%d\n",
+ dev->alt_servers[i].hostaddr,
+ (int)ntohs(dev->alt_servers[i].port),
+ (unsigned long long)((dev->alt_servers[i].rtts[0] + dev->alt_servers[i].rtts[1] + dev->alt_servers[i].rtts[2] + dev->alt_servers[i].rtts[3]) / 4),
+ (int)dev->alt_servers[i].failures)
+ , size);
+ else if (dev->alt_servers[i].hostaddrtype == AF_INET6)
+ ret = MIN(snprintf(buf, size, "%pI6,%d,%llu,%d\n",
+ dev->alt_servers[i].hostaddr,
+ (int)ntohs(dev->alt_servers[i].port),
+ (unsigned long long)((dev->alt_servers[i].rtts[0] + dev->alt_servers[i].rtts[1] + dev->alt_servers[i].rtts[2] + dev->alt_servers[i].rtts[3]) / 4),
+ (int)dev->alt_servers[i].failures)
+ , size);
+ else
+ continue;
+ size -= ret;
+ buf += ret;
+ if (size <= 0)
+ {
+ size = 0;
+ break;
+ }
+ }
+ return PAGE_SIZE - size;
}
ssize_t show_image_name(char *buf, dnbd3_device_t *dev)
{
if (dev->imgname == NULL) return sprintf(buf, "(null)");
- return sprintf(buf, "%s\n", dev->imgname);
+ return MIN(snprintf(buf, PAGE_SIZE, "%s\n", dev->imgname), PAGE_SIZE);
}
ssize_t show_rid(char *buf, dnbd3_device_t *dev)
{
- return sprintf(buf, "%d\n", dev->rid);
+ return MIN(snprintf(buf, PAGE_SIZE, "%d\n", dev->rid), PAGE_SIZE);
}
ssize_t show_update_available(char *buf, dnbd3_device_t *dev)
{
- return sprintf(buf, "%d\n", dev->update_available);
-}
-
-ssize_t show_alt_server_ip(char *buf, dnbd3_server_t *srv)
-{
- return sprintf(buf, "%pI4\n", srv->hostaddr);
-}
-
-ssize_t show_alt_server_rtt(char *buf, dnbd3_server_t *srv)
-{
- return sprintf(buf, "%llu\n", (uint64_t)((srv->rtts[0]+srv->rtts[1]+srv->rtts[2]+srv->rtts[3]) / 4));
+ return MIN(snprintf(buf, PAGE_SIZE, "%d\n", dev->update_available), PAGE_SIZE);
}
-device_attr_t cur_server_ip =
+device_attr_t cur_server_addr =
{
- .attr = {.name = "cur_server_ip", .mode = 0444 },
- .show = show_cur_server_ip,
+ .attr = {.name = "cur_server_addr", .mode = 0444 },
+ .show = show_cur_server_addr,
.store = NULL,
};
@@ -85,6 +118,13 @@ device_attr_t alt_server_num =
.store = NULL,
};
+device_attr_t alt_servers =
+{
+ .attr = {.name = "alt_servers", .mode = 0444 },
+ .show = show_alt_servers,
+ .store = NULL,
+};
+
device_attr_t image_name =
{
.attr = {.name = "image_name", .mode = 0444 },
@@ -106,20 +146,6 @@ device_attr_t update_available =
.store = NULL,
};
-server_attr_t alt_server_ip =
-{
- .attr = {.name = "alt_server_ip", .mode = 0444 },
- .show = show_alt_server_ip,
- .store = NULL,
-};
-
-server_attr_t alt_server_rtt =
-{
- .attr = {.name = "alt_server_rtt", .mode = 0444 },
- .show = show_alt_server_rtt,
- .store = NULL,
-};
-
ssize_t device_show(struct kobject *kobj, struct attribute *attr, char *buf)
{
device_attr_t *device_attr = container_of(attr, device_attr_t, attr);
@@ -127,41 +153,24 @@ ssize_t device_show(struct kobject *kobj, struct attribute *attr, char *buf)
return device_attr->show(buf, dev);
}
-ssize_t server_show(struct kobject *kobj, struct attribute *attr, char *buf)
-{
- server_attr_t *server_attr = container_of(attr, server_attr_t, attr);
- dnbd3_server_t *srv = container_of(kobj, dnbd3_server_t, kobj);
- return server_attr->show(buf, srv);
-}
-
struct attribute *device_attrs[] =
{
- &cur_server_ip.attr,
+ &cur_server_addr.attr,
&cur_server_rtt.attr,
&alt_server_num.attr,
+ &alt_servers.attr,
&image_name.attr,
&rid.attr,
&update_available.attr,
NULL,
};
-struct attribute *server_attrs[] =
-{
- &alt_server_ip.attr,
- &alt_server_rtt.attr,
- NULL,
-};
struct sysfs_ops device_ops =
{
.show = device_show,
};
-struct sysfs_ops server_ops =
-{
- .show = server_show,
-};
-
void release(struct kobject *kobj)
{
kobj->state_initialized = 0;
@@ -174,39 +183,17 @@ struct kobj_type device_ktype =
.release = release,
};
-struct kobj_type server_ktype =
-{
- .default_attrs = server_attrs,
- .sysfs_ops = &server_ops,
- .release = release,
-};
void dnbd3_sysfs_init(dnbd3_device_t *dev)
{
- int i;
- char name[15] = "alt_server99";
struct kobject *kobj = &dev->kobj;
struct kobj_type *ktype = &device_ktype;
struct kobject *parent = &disk_to_dev(dev->disk)->kobj;
kobject_init_and_add(kobj, ktype, parent, "net");
-
- for (i = 0; i < NUMBER_SERVERS; i++)
- {
- sprintf(name, "alt_server%d", i);
- kobj = &dev->alt_servers[i].kobj;
- ktype = &server_ktype;
- parent = &dev->kobj;
- kobject_init_and_add(kobj, ktype, parent, name);
- }
}
void dnbd3_sysfs_exit(dnbd3_device_t *dev)
{
- int i;
- for (i = 0; i < NUMBER_SERVERS; i++)
- {
- kobject_put(&dev->alt_servers[i].kobj);
- }
kobject_put(&dev->kobj);
}