summaryrefslogblamecommitdiffstats
path: root/src/kernel/sysfs.c
blob: bd23845ad2c9798b20498d763de3dda2b684b74d (plain) (tree)
1
2
3
4
5



                                                              
                                                        















                                                               

                  

                          





                                        
                                                                     








                                                                                                                                                       
                                                                   

                                     
                                                       


                                                                                  



                                                                                            



                                                                                  



                                                                                            















                                                          


                                                                                                    
 
                                                                

                       



                                                    



                                                                     
                                                             

                                     

                                                                


                                                                                     
                                                                       

                                                                             
                                                                       


                                                                                     
                                                                       

                                                                             
                        
                                 
                 

                            
                                






                                 
                                                            




                                                                              
                                                     



                                                                          
                                                                  



                                                                                       
                                     





                                                          
                                       




                                                            





                                                          
 
                                     





                                                          
                                  





                                                       
                                 





                                                      
                          





                                               
                                       







                                                                            

                                                                                           




                                           

                               
                             













                               
                                         











                                      
                                               







                                                                       
                                                              

 
                                               


                                
/*
 * This file is part of the Distributed Network Block Device 3
 *
 * Copyright(c) 2011-2012 Johann Latocha <johann@latocha.de>
 * Copyright(c) 2019 Frederic Robra <frederic@robra.org>
 *
 * This file may be licensed under the terms of of the
 * GNU General Public License Version 2 (the ``GPL'').
 *
 * Software distributed under the License is distributed
 * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
 * express or implied. See the GPL for the specific language
 * governing rights and limitations.
 *
 * You should have received a copy of the GPL along with this
 * program. If not, go to http://www.gnu.org/licenses/gpl.html
 * or write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 */

#include "sysfs.h"

#include <linux/kobject.h>

#include "utils.h"

#ifndef MIN
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#endif

ssize_t show_initial_server_addr(char *buf, struct dnbd3_device *dev)
{
	if (dev->initial_server.host.type == HOST_IP4)
		return MIN(snprintf(buf, PAGE_SIZE, "%pI4,%d\n", dev->initial_server.host.addr, (int)ntohs(dev->initial_server.host.port)), PAGE_SIZE);
	else if (dev->initial_server.host.type == HOST_IP6)
		return MIN(snprintf(buf, PAGE_SIZE, "%pI6,%d\n", dev->initial_server.host.addr, (int)ntohs(dev->initial_server.host.port)), PAGE_SIZE);
	*buf = '\0';
	return 0;
}

ssize_t show_connected_servers(char *buf, struct dnbd3_device *dev)
{
	int i, size = PAGE_SIZE, ret;
	for (i = 0; i < dev->number_connections; ++i) {
		if (dev->socks[i].sock) {
			if (dev->socks[i].server->host.type == HOST_IP4) {
				ret = MIN(snprintf(buf, size, "%pI4,%d,%llu,%d\n",
						dev->socks[i].server->host.addr,
				                (int)ntohs(dev->socks[i].server->host.port),
						dev->socks[i].server->avg_rtt,
						(int)dev->socks[i].server->failures)
				          , size);

			} else {
				ret = MIN(snprintf(buf, size, "%pI6,%d,%llu,%d\n",
						dev->socks[i].server->host.addr,
						(int)ntohs(dev->socks[i].server->host.port),
						dev->socks[i].server->avg_rtt,
						(int)dev->socks[i].server->failures)
				          , size);

			}
			size -= ret;
			buf += ret;
			if (size <= 0) {
				size = 0;
				break;
			}
		}

	}
	return PAGE_SIZE - size;
}

//ssize_t show_cur_server_rtt(char *buf, dnbd3_devic *dev)
//{
//	return MIN(snprintf(buf, PAGE_SIZE, "%llu\n", (unsigned long long)dev->cur_rtt), PAGE_SIZE);
//}

ssize_t show_alt_server_num(char *buf, struct dnbd3_device *dev)
{
	int i, num = 0;
	for (i = 0; i < NUMBER_SERVERS; i++) {
		if (dev->alt_servers[i].host.type) {
			num++;
		}
	}
	return MIN(snprintf(buf, PAGE_SIZE, "%d\n", num), PAGE_SIZE);
}

ssize_t show_alt_servers(char *buf, struct dnbd3_device *dev)
{
	int i, size = PAGE_SIZE, ret;
	for (i = 0; i < NUMBER_SERVERS; ++i) {
		if (dev->alt_servers[i].host.type == HOST_IP4) {
			ret = MIN(snprintf(buf, size, "%pI4,%d,%llu,%d\n",
			                   dev->alt_servers[i].host.addr,
			                   (int)ntohs(dev->alt_servers[i].host.port),
					   dev->alt_servers[i].avg_rtt,
			                   (int)dev->alt_servers[i].failures)
			          , size);
		} else if (dev->alt_servers[i].host.type == HOST_IP6) {
			ret = MIN(snprintf(buf, size, "%pI6,%d,%llu,%d\n",
			                   dev->alt_servers[i].host.addr,
			                   (int)ntohs(dev->alt_servers[i].host.port),
					   dev->alt_servers[i].avg_rtt,
			                   (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, struct dnbd3_device *dev)
{
	if (dev->imgname == NULL) return sprintf(buf, "(null)");
	return MIN(snprintf(buf, PAGE_SIZE, "%s\n", dev->imgname), PAGE_SIZE);
}

ssize_t show_rid(char *buf, struct dnbd3_device *dev)
{
	return MIN(snprintf(buf, PAGE_SIZE, "%d\n", dev->rid), PAGE_SIZE);
}

ssize_t show_update_available(char *buf, struct dnbd3_device *dev)
{
	return MIN(snprintf(buf, PAGE_SIZE, "%d\n", dev->update_available), PAGE_SIZE);
}

struct device_attr_t initial_server =
{
	.attr = {.name = "initial_server", .mode = 0444 },
	.show   = show_initial_server_addr,
	.store  = NULL,
};

struct device_attr_t connected_server =
{
	.attr = {.name = "connected_server", .mode = 0444 },
	.show   = show_connected_servers,
	.store  = NULL,
};
//device_attr_t cur_server_rtt =
//{
//	.attr = {.name = "cur_server_rtt", .mode = 0444 },
//	.show   = show_cur_server_rtt,
//	.store  = NULL,
//};

struct device_attr_t alt_server_num =
{
	.attr = {.name = "alt_server_num", .mode = 0444 },
	.show   = show_alt_server_num,
	.store  = NULL,
};

struct device_attr_t alt_servers =
{
	.attr = {.name = "alt_servers", .mode = 0444 },
	.show   = show_alt_servers,
	.store  = NULL,
};

struct device_attr_t image_name =
{
	.attr = {.name = "image_name", .mode = 0444 },
	.show   = show_image_name,
	.store  = NULL,
};

struct device_attr_t rid =
{
	.attr = {.name = "rid", .mode = 0444 },
	.show   = show_rid,
	.store  = NULL,
};

struct device_attr_t update_available =
{
	.attr = {.name = "update_available", .mode = 0444 },
	.show   = show_update_available,
	.store  = NULL,
};

ssize_t device_show(struct kobject *kobj, struct attribute *attr, char *buf)
{
	struct device_attr_t *device_attr = container_of(attr, struct device_attr_t, attr);
	struct dnbd3_device *dev = container_of(kobj, struct dnbd3_device, kobj);
	return device_attr->show(buf, dev);
}

struct attribute *device_attrs[] =
{
	&initial_server.attr,
	&connected_server.attr,
//	&cur_server_rtt.attr,
	&alt_server_num.attr,
	&alt_servers.attr,
	&image_name.attr,
	&rid.attr,
	&update_available.attr,
	NULL,
};


struct sysfs_ops device_ops =
{
	.show = device_show,
};

static void release(struct kobject *kobj)
{
	kobj->state_initialized = 0;
}

struct kobj_type device_ktype =
{
	.default_attrs = device_attrs,
	.sysfs_ops = &device_ops,
	.release = release,
};


void dnbd3_sysfs_init(struct dnbd3_device *dev)
{
	int error;
	struct kobject *kobj = &dev->kobj;
	struct kobj_type *ktype = &device_ktype;
	struct kobject *parent = &disk_to_dev(dev->disk)->kobj;

	error = kobject_init_and_add(kobj, ktype, parent, "%s", "net");
	if (error)
		error_dev(dev, "kobject initializing failed");
}

void dnbd3_sysfs_exit(struct dnbd3_device *dev)
{
	kobject_put(&dev->kobj);
}