00001 #include <linux/aquosa/qres_config.h>
00002 #include "qsup_lib.h"
00003
00010 #include <sys/ioctl.h>
00011 #include <sys/types.h>
00012 #include <sys/stat.h>
00013 #include <fcntl.h>
00014 #include <unistd.h>
00015 #include <string.h>
00016 #include <errno.h>
00017
00018 #include <linux/aquosa/qos_debug.h>
00019
00020 #define IOCTL_OP_ADD_LEVEL_RULE _IOR (QSUP_MAJOR_NUM, QSUP_OP_ADD_LEVEL_RULE, qsup_iparams_t)
00021 #define IOCTL_OP_ADD_GROUP_RULE _IOR (QSUP_MAJOR_NUM, QSUP_OP_ADD_GROUP_RULE, qsup_iparams_t)
00022 #define IOCTL_OP_ADD_USER_RULE _IOR (QSUP_MAJOR_NUM, QSUP_OP_ADD_USER_RULE, qsup_iparams_t)
00023 #define IOCTL_OP_FIND_CONSTR _IOWR(QSUP_MAJOR_NUM, QSUP_OP_FIND_CONSTR, qsup_iparams_t)
00024 #define IOCTL_OP_GET_AVAIL_GUA_BW _IOWR(QSUP_MAJOR_NUM, QSUP_OP_GET_AVAIL_GUA_BW, qsup_iparams_t)
00025 #define IOCTL_OP_RESERVE_SPARE _IOR (QSUP_MAJOR_NUM, QSUP_OP_RESERVE_SPARE, qsup_iparams_t)
00026
00028 int qsup_fd = -1;
00029
00030 #define QSUP_DEV_PATHNAME QOS_DEV_PATH "/" QSUP_DEV_NAME
00031
00032 qos_rv qsup_init() {
00033 if (qsup_fd == -1) {
00034 qsup_fd = open(QSUP_DEV_PATHNAME, O_RDONLY);
00035 if (qsup_fd < 0) {
00036 qos_log_debug("Failed to open device %s", QSUP_DEV_PATHNAME);
00037 return QOS_E_MISSING_COMPONENT;
00038 }
00039 }
00040 return QOS_OK;
00041 }
00042
00043 qos_rv qsup_cleanup() {
00044 int fd = qsup_fd;
00045
00046 if (qsup_fd != -1) {
00047 qsup_fd = -1;
00048 if (close(fd) < 0)
00049 return QOS_E_GENERIC;
00050 }
00051 return QOS_OK;
00052 }
00053
00054 static inline qos_rv check_open() {
00055 return qsup_init();
00056 }
00057
00058 qos_rv qsup_add_level_rule(int level_id, qos_bw_t max_level_bw) {
00059 qsup_iparams_t iparams;
00060
00061 qos_rv rv = check_open();
00062 qos_chk_rv(rv == QOS_OK, rv);
00063
00064 iparams.u.level_rule.level_id = level_id;
00065 iparams.u.level_rule.max_level_bw = max_level_bw;
00066
00067 if (ioctl(qsup_fd, IOCTL_OP_ADD_LEVEL_RULE, &iparams) < 0)
00068 return qos_int_rv(-errno);
00069
00070 return QOS_OK;
00071 }
00072
00073 qos_rv qsup_add_group_rule(int group_id, qsup_constraints_t * rule) {
00074 qsup_iparams_t iparams;
00075
00076 qos_rv rv = check_open();
00077 qos_chk_rv(rv == QOS_OK, rv);
00078
00079 iparams.u.group_rule.gid = group_id;
00080 iparams.u.group_rule.constr = *rule;
00081
00082 if (ioctl(qsup_fd, IOCTL_OP_ADD_GROUP_RULE, &iparams) < 0)
00083 return qos_int_rv(-errno);
00084
00085 return QOS_OK;
00086 }
00087
00088 qos_rv qsup_add_user_rule(int user_id, qsup_constraints_t * rule) {
00089 qsup_iparams_t iparams;
00090
00091 qos_rv rv = check_open();
00092 qos_chk_rv(rv == QOS_OK, rv);
00093
00094 iparams.u.user_rule.uid = user_id;
00095 iparams.u.user_rule.constr = *rule;
00096
00097 if (ioctl(qsup_fd, IOCTL_OP_ADD_USER_RULE, &iparams) < 0)
00098 return qos_int_rv(-errno);
00099
00100 return QOS_OK;
00101 }
00102
00103 qos_rv qsup_find_constraint(int uid, int gid, qsup_constraints_t *rule) {
00104 qsup_iparams_t iparams;
00105
00106 qos_rv rv = check_open();
00107 qos_chk_rv(rv == QOS_OK, rv);
00108
00109 iparams.u.found_rule.uid = uid;
00110 iparams.u.found_rule.gid = gid;
00111
00112 if (ioctl(qsup_fd, IOCTL_OP_FIND_CONSTR, &iparams) < 0)
00113 return qos_int_rv(-errno);
00114
00115 *rule = iparams.u.found_rule.constr;
00116
00117 return QOS_OK;
00118 }
00119
00120 qos_rv qsup_reserve_spare(qos_bw_t spare_bw) {
00121 qsup_iparams_t iparams;
00122 qos_rv rv;
00123
00124 qos_chk_ok_do(rv = check_open(), return rv);
00125
00126 iparams.u.spare_bw = spare_bw;
00127
00128 if (ioctl(qsup_fd, IOCTL_OP_RESERVE_SPARE, &iparams) < 0)
00129 return qos_int_rv(-errno);
00130
00131 return QOS_OK;
00132 }
00133
00134 qos_rv qsup_get_available_bandwidth(int uid, int gid, qos_bw_t *bw) {
00135 qsup_iparams_t iparams;
00136 qos_rv rv;
00137
00138 qos_chk_ok_do(rv = check_open(), return rv);
00139
00140 iparams.u.avail.uid = uid;
00141 iparams.u.avail.gid = gid;
00142 if (ioctl(qsup_fd, IOCTL_OP_GET_AVAIL_GUA_BW, &iparams) < 0)
00143 return qos_int_rv(-errno);
00144
00145 *bw = iparams.u.avail.avail_gua_bw;
00146
00147 return QOS_OK;
00148 }