#include "common.h"
#include "quota_debug.h"
-#include "quota_plugin.h"
+#include "quota_common.h"
#include "quota_mnt.h"
#include "quota_fs.h"
+#if HAVE_SYS_QUOTA_H
+# include <sys/quota.h>
+#endif
+
/* *** *** *** prototypes of local functions *** *** *** */
static int qft(const char *type);
-static void getquota_ext3(quota_t **quota, quota_mnt_t *m);
-static void getquota_ext2(quota_t **quota, quota_mnt_t *m);
-static void getquota_ufs(quota_t **quota, quota_mnt_t *m);
-static void getquota_vxfs(quota_t **quota, quota_mnt_t *m);
-static void getquota_zfs(quota_t **quota, quota_mnt_t *m);
+static quota_t *getquota_ext3(quota_t **quota, quota_mnt_t *m);
+static quota_t *getquota_ext3_v1(quota_t **quota, quota_mnt_t *m);
+static quota_t *getquota_ext3_v2(quota_t **quota, quota_mnt_t *m);
+static quota_t *getquota_ext2(quota_t **quota, quota_mnt_t *m);
+static quota_t *getquota_ufs(quota_t **quota, quota_mnt_t *m);
+static quota_t *getquota_vxfs(quota_t **quota, quota_mnt_t *m);
+static quota_t *getquota_zfs(quota_t **quota, quota_mnt_t *m);
/* *** *** *** local functions *** *** *** */
return QFT_NONE;
} /* static int qft(const char *type) */
-static void
+static quota_t *
getquota_ext3(quota_t **quota, quota_mnt_t *m)
{
#if HAVE_QUOTACTL
- int fmt;
- if(quotactl(QCMD(Q_GETFMT, type), dev, 0, (void *)&fmt) == -1) {
+ uint32_t fmt;
+#endif
+#if HAVE_QUOTACTL
+ if(quotactl(QCMD(Q_GETFMT, USRQUOTA), m->device,
+ 0, (void *)&fmt) == -1)
+ {
DBG("quotactl returned -1: %s", strerror(errno));
- *quota = NULL;
+ return NULL;
}
-#endif
-#if 0
- int kern_quota_on(const char *dev, int type, int fmt)
+ if(fmt == 1) {
+ return getquota_ext3_v1(quota, m);
+ } else if(fmt == 2) {
+ return getquota_ext3_v2(quota, m);
+ } else {
+ DBG("unknown quota format: 0x%08x", fmt);
+ return NULL;
+ }
+#endif /* HAVE_QUOTACTL */
+
+ return NULL;
+} /* static quota_t *getquota_ext3(quota_t **quota, quota_mnt_t *m) */
+
+static quota_t *
+getquota_ext3_v1(quota_t **quota, quota_mnt_t *m)
{
- /* Check whether quota is turned on... */
- if (kernel_iface == IFACE_GENERIC) {
- int actfmt;
-
- if (quotactl(QCMD(Q_GETFMT, type), dev, 0, (void *)&actfmt) < 0)
- return -1;
- actfmt = kern2utilfmt(actfmt);
- if (actfmt >= 0 && (fmt == -1 || (1 << actfmt) & fmt))
- return actfmt;
- return -1;
- }
- if ((fmt & (1 << QF_VFSV0)) && v2_kern_quota_on(dev, type)) /* New quota format */
- return QF_VFSV0;
- if ((fmt & (1 << QF_XFS)) && xfs_kern_quota_on(dev, type)) /* XFS quota format */
- return QF_XFS;
- if ((fmt & (1 << QF_VFSOLD)) && v1_kern_quota_on(dev, type)) /* Old quota format */
- return QF_VFSOLD;
- return -1;
-}
+#if HAVE_QUOTACTL
+ struct dqinfo dqi_usr, dqi_grp;
#endif
+ quota_t *q;
+ DBG("quota v1:");
+#if HAVE_QUOTACTL
+ if(quotactl(QCMD(Q_GETINFO, USRQUOTA), m->device,
+ 0, (void *)&dqi_usr) == -1)
+ {
+ DBG("quotactl (Q_GETINFO, USRQUOTA) returned -1: %s",
+ strerror(errno));
+ *quota = NULL;
+ return NULL;
+ }
+ if(quotactl(QCMD(Q_GETINFO, GRPQUOTA), m->device,
+ 0, (void *)&dqi_grp) == -1)
+ {
+ DBG("quotactl (Q_GETINFO, GRPQUOTA) returned -1: %s",
+ strerror(errno));
+ *quota = NULL;
+ return NULL;
+ }
+#endif /* HAVE_QUOTACTL */
-#if 0
- quotaio.c
- kernfmt = kern_quota_on(h->qh_quotadev, type, fmt == -1 ? kernel_formats : (1 << fmt));
- if (kernfmt >= 0) {
- h->qh_io_flags |= IOFL_QUOTAON;
- fmt = kernfmt; /* Default is kernel used format */
- }
-if ((fmt = get_qf_name(mnt, type, (fmt == -1) ? ((1 << QF_VFSOLD) | (1 << QF_VFSV0)) : (1 << fmt),
- (!QIO_ENABLED(h) || flags & IOI_OPENFILE) ? NF_FORMAT : 0, &qfname)) < 0) {
-errstr(_("Quota file not found or has wrong format.\n"));
- goto out_handle;
- if (!QIO_ENABLED(h) || flags & IOI_OPENFILE) { /* Need to open file? */
- /* We still need to open file for operations like 'repquota' */
- if ((fd = open(qfname, QIO_RO(h) ? O_RDONLY : O_RDWR)) < 0) {
- errstr(_("Can't open quotafile %s: %s\n"),
- qfname, strerror(errno));
- goto out_handle;
- }
- flock(fd, QIO_RO(h) ? LOCK_SH : LOCK_EX);
- /* Init handle */
- h->qh_fd = fd;
- h->qh_fmt = fmt;
- }
- else {
- h->qh_fd = -1;
- h->qh_fmt = fmt;
- }
- free(qfname); /* We don't need it anymore */
- qfname = NULL;
- if (h->qh_fmt == QF_VFSOLD)
- h->qh_ops = "afile_ops_1;
- else if (h->qh_fmt == QF_VFSV0)
- h->qh_ops = "afile_ops_2;
- memset(&h->qh_info, 0, sizeof(h->qh_info));
-
- if (h->qh_ops->init_io && h->qh_ops->init_io(h) < 0) {
- errstr(_("Can't initialize quota on %s: %s\n"), h->qh_quotadev, strerror(errno));
- goto out_lock;
- }
- return h;
-out_lock:
- if (fd != -1)
- flock(fd, LOCK_UN);
-out_handle:
- if (qfname)
- free(qfname);
- free(h);
- return NULL;
+ q = *quota = (quota_t *)smalloc(sizeof(quota_t));
+
+ q->type = (char *)sstrdup("usrquota");
+#if HAVE_GRP_H
+/* struct group *getgrid((gid_t)500) */
+ q->name = (char *)sstrdup("niki");
+#else
+ q->name = (char *)sstrdup("");
#endif
- *quota = NULL;
+ q->id = (char *)sstrdup("500");
+ q->dir = (char *)sstrdup(m->dir);
+ q->blocks = 5;
+ q->bquota = 100;
+ q->blimit = 180;
+ q->bgrace = dqi_usr.dqi_bgrace;
+ q->btimeleft = 0;
+ q->inodes = 5;
+ q->iquota = 100;
+ q->ilimit = 180;
+ q->igrace = dqi_usr.dqi_igrace;
+ q->itimeleft = 0;
+ q->next = NULL;
+
+ q->next = (quota_t *)smalloc(sizeof(quota_t));
+ q = q->next;
+ q->type = (char *)sstrdup("grpquota");
+#if HAVE_GRP_H
+/* struct group *getgrid((gid_t)500) */
+ q->name = (char *)sstrdup("users");
+#else
+ q->name = (char *)sstrdup("");
+#endif
+ q->id = (char *)sstrdup("100");
+ q->dir = (char *)sstrdup(m->dir);
+ q->blocks = 5;
+ q->bquota = 100;
+ q->blimit = 180;
+ q->bgrace = dqi_grp.dqi_bgrace;
+ q->btimeleft = 0;
+ q->inodes = 5;
+ q->iquota = 100;
+ q->ilimit = 180;
+ q->igrace = dqi_grp.dqi_igrace;
+ q->itimeleft = 0;
+ q->next = NULL;
+
+ return *quota;
}
-static void
+static quota_t *
+getquota_ext3_v2(quota_t **quota, quota_mnt_t *m)
+{
+ DBG("quota v2:");
+ return getquota_ext3_v1(quota, m);
+}
+
+static quota_t *
getquota_ext2(quota_t **quota, quota_mnt_t *m)
{
- *quota = NULL;
+ return NULL;
}
-static void
+static quota_t *
getquota_ufs(quota_t **quota, quota_mnt_t *m)
{
- *quota = NULL;
+ return NULL;
}
-static void
+static quota_t *
getquota_vxfs(quota_t **quota, quota_mnt_t *m)
{
- *quota = NULL;
+ return NULL;
}
-static void
+static quota_t *
getquota_zfs(quota_t **quota, quota_mnt_t *m)
{
- *quota = NULL;
+ return NULL;
}
/* *** *** *** global functions *** *** *** */
#endif
return EXIT_FAILURE;
}
-}
+} /* int quota_fs_issupported(const char *fsname) */
int
quota_fs_isnfs(const char *fsname)
} else {
return EXIT_FAILURE;
}
-}
+} /* int quota_fs_isnfs(const char *fsname) */
void
quota_fs_freequota(quota_t *quota)
{
quota_t *q = quota, *prev = NULL;
+DBG("x");
while(q != NULL) {
while(q->next != NULL) {
prev = q;
}
free(q->type);
free(q->name);
+ free(q->id);
free(q->dir);
free(q);
prev = NULL;
quota_fs_getquota(quota_t **quota, quota_mnt_t *mnt)
{
quota_mnt_t *m = mnt;
+ quota_t *q = NULL;
+ *quota = NULL;
while(m != NULL) {
switch(qft(m->type)) {
- case QFT_EXT3:
- getquota_ext3(quota, m);
+ case QFT_EXT3:
+ q = getquota_ext3(&q, m);
break;
case QFT_EXT2:
- getquota_ext2(quota, m);
+ q = getquota_ext2(&q, m);
break;
case QFT_UFS:
- getquota_ufs(quota, m);
+ q = getquota_ufs(&q, m);
break;
case QFT_VXFS:
- getquota_vxfs(quota, m);
+ q = getquota_vxfs(&q, m);
break;
case QFT_ZFS:
- getquota_zfs(quota, m);
+ q = getquota_zfs(&q, m);
break;
}
+ if(q != NULL) { /* found some quotas */
+ DBG("\ttype: %s", (*quota)->type);
+ DBG("\tname: %s", (*quota)->name);
+ DBG("\tid: %s", (*quota)->id);
+ DBG("\tdir: %s", (*quota)->dir);
+ DBG("\tblocks: %llu (%lld/%lld) %llu %llu",
+ (*quota)->blocks, (*quota)->bquota, (*quota)->blimit,
+ (*quota)->bgrace, (*quota)->btimeleft);
+ DBG("\tinodes: %llu (%lld/%lld) %llu %llu",
+ (*quota)->inodes, (*quota)->iquota, (*quota)->ilimit,
+ (*quota)->igrace, (*quota)->itimeleft);
+
+ if(*quota == NULL) { /* not init yet */
+DBG("a");
+ *quota = q; /* init */
+ } else { /* we have some quotas already */
+DBG("b");
+ quota_t *t = *quota;
+ /* goto last entry */
+ while(t->next != NULL) {
+ t = t->next;
+DBG("c");
+ }
+ t->next = q; /* set next pointer */
+ }
+ }
+DBG("z");
m = m->next;
- } /* while(l != NULL) */
+ } /* while(m != NULL) */
return(*quota);
-}
+} /* quota_t *quota_fs_getquota(quota_t **quota, quota_mnt_t *mnt) */
#include "plugin.h"
#include "quota_debug.h"
+#include "quota_common.h"
#include "quota_mnt.h"
#include "quota_fs.h"
#include "quota_plugin.h"
/* *** *** *** local constants *** *** *** */
-static const char *quota_filename_template = "quota-%s.rrd";
+static const char *quota_filename_template = MODULE_NAME "-%s.rrd";
static char *quota_ds_def[] =
{
"DS:blocks:GAUGE:25:0:U",
"DS:block_quota:GAUGE:25:-1:U",
"DS:block_limit:GAUGE:25:-1:U",
- "DS:block_grace:GAUGE:25:0:U",
- "DS:block_timeleft:GAUGE:25:0:U",
+ "DS:block_grace:GAUGE:25:-1:U",
+ "DS:block_timeleft:GAUGE:25:-1:U",
"DS:inodes:GAUGE:25:0:U",
"DS:inode_quota:GAUGE:25:-1:U",
"DS:inode_limit:GAUGE:25:-1:U",
- "DS:inode_grace:GAUGE:25:0:U",
- "DS:inode_timeleft:GAUGE:25:0:U",
+ "DS:inode_grace:GAUGE:25:-1:U",
+ "DS:inode_timeleft:GAUGE:25:-1:U",
NULL
};
static const int quota_ds_num = 10;
{
char buf[BUFSIZE];
int r;
+ char *name, *n;
r = snprintf(buf, BUFSIZE,
"%u:%llu:%lld:%lld:%llu:%llu:%llu:%lld:%lld:%llu:%llu",
DBG("failed");
return;
}
- plugin_submit(MODULE_NAME, q->name, buf);
+ n = name = (char *)smalloc(strlen(q->type) + 1 + strlen(q->dir)
+ + 1 + strlen(q->name) + 1 + strlen(q->id));
+ sstrncpy(n, q->type, strlen(q->type)+1);
+ n += strlen(q->type);
+ sstrncpy(n, "-", 1+1);
+ n += 1;
+ sstrncpy(n, q->name, strlen(q->name)+1);
+ n += strlen(q->name);
+ sstrncpy(n, "-", 1+1);
+ n += 1;
+ sstrncpy(n, q->id, strlen(q->id)+1);
+ n += strlen(q->id);
+ sstrncpy(n, "-", 1+1);
+ n += 1;
+ sstrncpy(n, q->dir, strlen(q->dir)+1);
+ n += strlen(q->dir);
+ n = name;
+ /* translate '/' -> '_' */
+ while(*n != '\0') {
+ if(*n == '/') {
+ *n = '_';
+ }
+ n++;
+ }
+
+ DBG("rrd file: %s-%s", MODULE_NAME, name);
+ plugin_submit(MODULE_NAME, name, buf);
}
#undef BUFSIZE
{
quota_mnt_t *list = NULL, *l = NULL;
quota_t *quota = NULL, *q = NULL;
- quota_t q_def = {
- type: "usrquota",
- name: "500",
- dir: "/",
- blocks: 0, bquota: -1, blimit: -1,
- bgrace: 0, btimeleft: 0,
- inodes: 0, iquota: -1, ilimit: -1,
- igrace: 0, itimeleft: 0,
- next: NULL,
- };
l = quota_mnt_getlist(&list);
DBG("local mountpoints:");
while(q != NULL) {
DBG("\ttype: %s", q->type);
DBG("\tname: %s", q->name);
+ DBG("\tid: %s", q->id);
DBG("\tdir: %s", q->dir);
DBG("\tblocks: %llu (%lld/%lld) %llu %llu",
q->blocks, q->bquota, q->blimit,
DBG("\tinodes: %llu (%lld/%lld) %llu %llu",
q->inodes, q->iquota, q->ilimit,
q->igrace, q->itimeleft);
+ quota_submit(q);
q = q->next;
if(q != NULL) {
DBG("\t-- ");
}
DBG("\t== ");
- quota_submit(&q_def);
-
quota_fs_freequota(quota);
quota_mnt_freelist(list);
}
return;
}
+ DBG("host: %s", host);
+ DBG("file: %s", file);
+ DBG("val: %s", val);
+ DBG("quota_ds_def: %s", *quota_ds_def);
+ DBG("quota_ds_num: %d", quota_ds_num);
rrd_update_file(host, file, val, quota_ds_def, quota_ds_num);
}